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 
149 /* defined in mp-ctl.h */
150 #define MPCTLV3_VIDEO_DECODE_PB_HINT 0x41C04000
151 
152 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
153 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
154 
155 /*
156 To enable sending vp9/hevc hdr10plus metadata via private gralloc
157 handle to display, define HDR10PLUS_SETMETADATA_ENABLE as 1.This
158 disables sending metadata via framework. To enable sending vp9/hevc
159 hdr10plus metadata via framework, define HDR10PLUS_SETMETADATA_ENABLE
160 as 0. This disables sending metadata via gralloc handle.
161 */
162 #define HDR10_SETMETADATA_ENABLE 0
163 
164 using namespace android;
165 
166 #ifdef HYPERVISOR
167 #define ioctl(x, y, z) hypv_ioctl(x, y, z)
168 #define poll(x, y, z)  hypv_poll(x, y, z)
169 #endif
170 
171 static OMX_U32 maxSmoothStreamingWidth = 1920;
172 static OMX_U32 maxSmoothStreamingHeight = 1088;
173 
174 void print_omx_buffer(const char *str, OMX_BUFFERHEADERTYPE *pHeader)
175 {
176     if (!pHeader)
177         return;
178 
179     DEBUG_PRINT_HIGH("%s: Header %p buffer %p alloclen %d offset %d filledlen %d timestamp %lld flags %#x",
180         str, pHeader, pHeader->pBuffer, pHeader->nAllocLen,
181         pHeader->nOffset, pHeader->nFilledLen,
182         pHeader->nTimeStamp, pHeader->nFlags);
183 }
184 
185 void print_v4l2_buffer(const char *str, struct v4l2_buffer *v4l2)
186 {
187     if (!v4l2)
188         return;
189 
190     if (v4l2->length == 1)
191         DEBUG_PRINT_HIGH(
192             "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x\n",
193             str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
194             "OUTPUT" : "CAPTURE", v4l2->index,
195             v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
196             v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
197             v4l2->m.planes[0].bytesused, v4l2->flags);
198     else
199         DEBUG_PRINT_HIGH(
200             "%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",
201             str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
202             "OUTPUT" : "CAPTURE", v4l2->index,
203             v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
204             v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
205             v4l2->m.planes[0].bytesused, v4l2->m.planes[1].reserved[0],
206             v4l2->flags, v4l2->m.planes[1].reserved[1],
207             v4l2->m.planes[1].length, v4l2->m.planes[1].bytesused);
208 }
209 
210 void* async_message_thread (void *input)
211 {
212     OMX_BUFFERHEADERTYPE *buffer;
213     struct v4l2_plane plane[VIDEO_MAX_PLANES];
214     struct pollfd pfds[2];
215     struct v4l2_buffer v4l2_buf;
216     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
217     struct v4l2_event dqevent;
218     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
219     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
220     pfds[1].events = POLLIN | POLLERR;
221     pfds[0].fd = omx->drv_ctx.video_driver_fd;
222     pfds[1].fd = omx->m_poll_efd;
223     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
224     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
225     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
226     while (!omx->async_thread_force_stop) {
227         rc = poll(pfds, 2, POLL_TIMEOUT);
228         if (!rc) {
229             DEBUG_PRINT_ERROR("Poll timedout");
230             break;
231         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
232             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
233             break;
234         }
235         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
236             DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
237             break;
238         }
239         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
240             struct vdec_msginfo vdec_msg;
241             memset(&vdec_msg, 0, sizeof(vdec_msg));
242             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
243             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
244             v4l2_buf.length = omx->drv_ctx.num_planes;
245             v4l2_buf.m.planes = plane;
246             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
247                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
248                 vdec_msg.status_code=VDEC_S_SUCCESS;
249                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
250                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
251                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
252                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
253                     (uint64_t)v4l2_buf.timestamp.tv_usec;
254 
255                 if (omx->async_message_process(input,&vdec_msg) < 0) {
256                     DEBUG_PRINT_HIGH("async_message_thread Exited");
257                     break;
258                 }
259             }
260         }
261         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
262             struct vdec_msginfo vdec_msg;
263             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
264             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
265             v4l2_buf.length = 1;
266             v4l2_buf.m.planes = plane;
267             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
268                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
269                 vdec_msg.status_code=VDEC_S_SUCCESS;
270                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
271                 if (omx->async_message_process(input,&vdec_msg) < 0) {
272                     DEBUG_PRINT_HIGH("async_message_thread Exited");
273                     break;
274                 }
275             }
276         }
277         if (pfds[0].revents & POLLPRI) {
278             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
279             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
280                 struct vdec_msginfo vdec_msg;
281                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
282 
283                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
284                 vdec_msg.status_code=VDEC_S_SUCCESS;
285                 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
286                 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
287                 vdec_msg.msgdata.output_frame.flags = true; // INSUFFICIENT event
288                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
289                 omx->dpb_bit_depth = ptr[2];
290                 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth - %d", ptr[3]);
291                 omx->m_progressive = ptr[3];
292                 DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct - %d", ptr[4]);
293                 omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
294                                       (omx_vdec:: EXCEPT_BT2020));
295                 DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace - %d", omx->m_color_space);
296                 if (omx->async_message_process(input,&vdec_msg) < 0) {
297                     DEBUG_PRINT_HIGH("async_message_thread Exited");
298                     break;
299                 }
300             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT) {
301 
302                 bool event_fields_changed = false;
303                 bool send_msg = false;
304                 omx_vdec::color_space_type tmp_color_space;
305                 struct vdec_msginfo vdec_msg;
306                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received sufficient");
307                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
308                 int tmp_profile = 0;
309                 int tmp_level = 0;
310                 int codec = omx->get_session_codec_type();
311                 event_fields_changed |= (omx->dpb_bit_depth != (int)ptr[2]);
312                 event_fields_changed |= (omx->m_progressive != (int)ptr[3]);
313                 tmp_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
314                                    (omx_vdec:: EXCEPT_BT2020));
315                 event_fields_changed |= (omx->m_color_space != tmp_color_space);
316 
317                 /*
318                  * If the resolution is different due to 16\32 pixel alignment,
319                  * let's handle as Sufficient. Ex : 1080 & 1088 or 2160 & 2176.
320                  * When FBD comes, component updates the clients with actual
321                  * resolution through set_buffer_geometry.
322                  */
323 
324                  event_fields_changed |= (omx->drv_ctx.video_resolution.frame_height != ptr[0]);
325                  event_fields_changed |= (omx->drv_ctx.video_resolution.frame_width != ptr[1]);
326 
327                  if ((codec == V4L2_PIX_FMT_H264) ||
328                      (codec  == V4L2_PIX_FMT_HEVC)) {
329                      if (profile_level_converter::convert_v4l2_profile_to_omx(
330                                                          codec, ptr[9], &tmp_profile) &&
331                          profile_level_converter::convert_v4l2_level_to_omx(
332                                                          codec, ptr[10], &tmp_level)) {
333                          event_fields_changed |= (omx->mClientSessionForSufficiency &&
334                                                   ((tmp_profile != (int)omx->mClientSetProfile) ||
335                                                    (tmp_level > (int)omx->mClientSetLevel)));
336                      }
337                  }
338 
339                  if (!omx->is_down_scalar_enabled && omx->m_is_split_mode &&
340                         (omx->drv_ctx.video_resolution.frame_height != ptr[0] ||
341                         omx->drv_ctx.video_resolution.frame_width != ptr[1])) {
342                      event_fields_changed = true;
343                  }
344 
345                  if (event_fields_changed) {
346                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old Resolution(H,W) = (%d,%d) New Resolution(H,W) = (%d,%d))",
347                                      omx->drv_ctx.video_resolution.frame_height,
348                                      omx->drv_ctx.video_resolution.frame_width,
349                                      ptr[0], ptr[1]);
350                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old bitdepth = %d New bitdepth = %d",
351                                      omx->dpb_bit_depth, ptr[2]);
352                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old picstruct = %d New picstruct = %d",
353                                      omx->m_progressive, ptr[3]);
354                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old colorSpace = %s New colorspace = %s",
355                                      (omx->m_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"),
356                                      (tmp_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"));
357                     DEBUG_PRINT_HIGH("Client Session for sufficiency feature is %s", omx->mClientSessionForSufficiency ? "enabled": "disabled");
358                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Client (Profile,Level) = (%d,%d) bitstream(Profile,Level) = (%d,%d))",
359                                      omx->mClientSetProfile,
360                                      omx->mClientSetLevel,
361                                      tmp_profile, tmp_level);
362                     omx->dpb_bit_depth = ptr[2];
363                     omx->m_progressive = ptr[3];
364                     omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
365                                        (omx_vdec:: EXCEPT_BT2020));
366                     send_msg = true;
367                     vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
368                     vdec_msg.status_code=VDEC_S_SUCCESS;
369                     vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
370                     vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
371                     vdec_msg.msgdata.output_frame.flags = false; // SUFFICIENT event
372                 } else {
373                     struct v4l2_decoder_cmd dec;
374                     memset(&dec, 0, sizeof(dec));
375                     dec.cmd = V4L2_QCOM_CMD_SESSION_CONTINUE;
376                     rc = ioctl(pfds[0].fd, VIDIOC_DECODER_CMD, &dec);
377                     if (rc < 0) {
378                         DEBUG_PRINT_ERROR("Session continue failed");
379                         send_msg = true;
380                         vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
381                         vdec_msg.status_code=VDEC_S_SUCCESS;
382                     } else {
383                         DEBUG_PRINT_HIGH("Sent Session continue");
384                     }
385                 }
386 
387                 if (send_msg) {
388                     if (omx->async_message_process(input,&vdec_msg) < 0) {
389                         DEBUG_PRINT_HIGH("async_message_thread Exited");
390                         break;
391                     }
392                 }
393 
394             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
395                 struct vdec_msginfo vdec_msg;
396                 uint32_t flush_type = *(uint32_t *)dqevent.u.data;
397                 // Old driver doesn't send flushType information.
398                 // To make this backward compatible fallback to old approach
399                 // if the flush_type is not present.
400                 vdec_msg.status_code=VDEC_S_SUCCESS;
401                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) {
402                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
403                     DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
404                     if (omx->async_message_process(input,&vdec_msg) < 0) {
405                         DEBUG_PRINT_HIGH("async_message_thread Exited");
406                         break;
407                     }
408                 }
409 
410                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) {
411                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
412                     DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
413                     if (omx->async_message_process(input,&vdec_msg) < 0) {
414                         DEBUG_PRINT_HIGH("async_message_thread Exited");
415                         break;
416                     }
417                 }
418             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
419                 struct vdec_msginfo vdec_msg;
420                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
421                 vdec_msg.status_code=VDEC_S_SUCCESS;
422                 DEBUG_PRINT_ERROR("HW Overload received");
423                 if (omx->async_message_process(input,&vdec_msg) < 0) {
424                     DEBUG_PRINT_HIGH("async_message_thread Exited");
425                     break;
426                 }
427             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
428                 struct vdec_msginfo vdec_msg;
429                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
430                 vdec_msg.status_code=VDEC_S_SUCCESS;
431                 DEBUG_PRINT_ERROR("HW Unsupported received");
432                 if (omx->async_message_process(input,&vdec_msg) < 0) {
433                     DEBUG_PRINT_HIGH("async_message_thread Exited");
434                     break;
435                 }
436             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
437                 struct vdec_msginfo vdec_msg;
438                 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
439                 vdec_msg.status_code = VDEC_S_SUCCESS;
440                 DEBUG_PRINT_HIGH("SYS Error Recieved");
441                 if (omx->async_message_process(input,&vdec_msg) < 0) {
442                     DEBUG_PRINT_HIGH("async_message_thread Exited");
443                     break;
444                 }
445             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
446                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
447 
448                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
449             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
450                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
451                 struct vdec_msginfo vdec_msg;
452 
453                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
454 
455                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
456                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
457                 v4l2_buf.length = omx->drv_ctx.num_planes;
458                 v4l2_buf.m.planes = plane;
459                 v4l2_buf.index = ptr[5];
460                 v4l2_buf.flags = 0;
461 
462                 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
463                 vdec_msg.status_code = VDEC_S_SUCCESS;
464                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
465                 vdec_msg.msgdata.output_frame.len = 0;
466                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
467                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
468                     (uint64_t)ptr[4];
469                 if (omx->async_message_process(input,&vdec_msg) < 0) {
470                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
471                     break;
472                 }
473             } else {
474                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
475                 continue;
476             }
477         }
478     }
479     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
480     return NULL;
481 }
482 
483 void* message_thread_dec(void *input)
484 {
485     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
486     int res = 0;
487 
488     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
489     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
490     while (!omx->message_thread_stop) {
491         res = omx->signal.wait(2 * 1000000000);
492         if (res == ETIMEDOUT || omx->message_thread_stop) {
493             continue;
494         } else if (res) {
495             DEBUG_PRINT_ERROR("omx_vdec: message_thread_dec wait on condition failed, exiting");
496             break;
497         }
498         omx->process_event_cb(omx);
499     }
500     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
501     return 0;
502 }
503 
504 void post_message(omx_vdec *omx, unsigned char id)
505 {
506     (void)id;
507     omx->signal.signal();
508 }
509 
510 // omx_cmd_queue destructor
511 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
512 {
513     // Nothing to do
514 }
515 
516 // omx cmd queue constructor
517 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
518 {
519     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
520 }
521 
522 // omx cmd queue insert
523 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
524 {
525     bool ret = true;
526     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
527         m_q[m_write].id       = id;
528         m_q[m_write].param1   = p1;
529         m_q[m_write].param2   = p2;
530         m_write++;
531         m_size ++;
532         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
533             m_write = 0;
534         }
535     } else {
536         ret = false;
537         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
538     }
539     return ret;
540 }
541 
542 // omx cmd queue pop
543 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
544 {
545     bool ret = true;
546     if (m_size > 0) {
547         *id = m_q[m_read].id;
548         *p1 = m_q[m_read].param1;
549         *p2 = m_q[m_read].param2;
550         // Move the read pointer ahead
551         ++m_read;
552         --m_size;
553         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
554             m_read = 0;
555         }
556     } else {
557         ret = false;
558     }
559     return ret;
560 }
561 
562 // Retrieve the first mesg type in the queue
563 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
564 {
565     return m_q[m_read].id;
566 }
567 
568 #ifdef _ANDROID_
569 omx_vdec::ts_arr_list::ts_arr_list()
570 {
571     //initialize timestamps array
572     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
573 }
574 omx_vdec::ts_arr_list::~ts_arr_list()
575 {
576     //free m_ts_arr_list?
577 }
578 
579 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
580 {
581     bool ret = true;
582     bool duplicate_ts = false;
583     int idx = 0;
584 
585     //insert at the first available empty location
586     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
587         if (!m_ts_arr_list[idx].valid) {
588             //found invalid or empty entry, save timestamp
589             m_ts_arr_list[idx].valid = true;
590             m_ts_arr_list[idx].timestamp = ts;
591             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
592                     ts, idx);
593             break;
594         }
595     }
596 
597     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
598         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
599         ret = false;
600     }
601     return ret;
602 }
603 
604 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
605 {
606     bool ret = true;
607     int min_idx = -1;
608     OMX_TICKS min_ts = 0;
609     int idx = 0;
610 
611     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
612 
613         if (m_ts_arr_list[idx].valid) {
614             //found valid entry, save index
615             if (min_idx < 0) {
616                 //first valid entry
617                 min_ts = m_ts_arr_list[idx].timestamp;
618                 min_idx = idx;
619             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
620                 min_ts = m_ts_arr_list[idx].timestamp;
621                 min_idx = idx;
622             }
623         }
624 
625     }
626 
627     if (min_idx < 0) {
628         //no valid entries found
629         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
630         ts = 0;
631         ret = false;
632     } else {
633         ts = m_ts_arr_list[min_idx].timestamp;
634         m_ts_arr_list[min_idx].valid = false;
635         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
636                 ts, min_idx);
637     }
638 
639     return ret;
640 
641 }
642 
643 
644 bool omx_vdec::ts_arr_list::reset_ts_list()
645 {
646     bool ret = true;
647     int idx = 0;
648 
649     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
650     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
651         m_ts_arr_list[idx].valid = false;
652     }
653     return ret;
654 }
655 #endif
656 
657 // factory function executed by the core to create instances
658 void *get_omx_component_factory_fn(void)
659 {
660     return (new omx_vdec);
661 }
662 
663 bool is_platform_tp10capture_supported()
664 {
665     DEBUG_PRINT_HIGH("TP10 on capture port is supported");
666     return true;
667 }
668 
669 inline int omx_vdec::get_session_codec_type()
670 {
671     return output_capability;
672 }
673 /* ======================================================================
674    FUNCTION
675    omx_vdec::omx_vdec
676 
677    DESCRIPTION
678    Constructor
679 
680    PARAMETERS
681    None
682 
683    RETURN VALUE
684    None.
685    ========================================================================== */
686 omx_vdec::omx_vdec(): m_error_propogated(false),
687     m_state(OMX_StateInvalid),
688     m_app_data(NULL),
689     m_inp_mem_ptr(NULL),
690     m_out_mem_ptr(NULL),
691     m_intermediate_out_mem_ptr(NULL),
692     m_client_output_extradata_mem_ptr(NULL),
693     input_flush_progress (false),
694     output_flush_progress (false),
695     input_use_buffer (false),
696     output_use_buffer (false),
697     ouput_egl_buffers(false),
698     m_use_output_pmem(OMX_FALSE),
699     pending_input_buffers(0),
700     pending_output_buffers(0),
701     m_out_bm_count(0),
702     m_inp_bm_count(0),
703     m_out_extradata_bm_count(0),
704     m_inp_bPopulated(OMX_FALSE),
705     m_out_bPopulated(OMX_FALSE),
706     m_flags(0),
707     m_inp_bEnabled(OMX_TRUE),
708     m_out_bEnabled(OMX_TRUE),
709     m_in_alloc_cnt(0),
710     m_platform_list(NULL),
711     m_platform_entry(NULL),
712     m_pmem_info(NULL),
713     h264_parser(NULL),
714     arbitrary_bytes (false),
715     psource_frame (NULL),
716     pdest_frame (NULL),
717     m_inp_heap_ptr (NULL),
718     m_phdr_pmem_ptr(NULL),
719     m_heap_inp_bm_count (0),
720     codec_type_parse ((codec_type)0),
721     first_frame_meta (true),
722     frame_count (0),
723     nal_count (0),
724     nal_length(0),
725     look_ahead_nal (false),
726     first_frame(0),
727     first_buffer(NULL),
728     first_frame_size (0),
729     m_device_file_ptr(NULL),
730     h264_last_au_ts(LLONG_MAX),
731     h264_last_au_flags(0),
732     m_disp_hor_size(0),
733     m_disp_vert_size(0),
734     prev_ts(LLONG_MAX),
735     prev_ts_actual(LLONG_MAX),
736     rst_prev_ts(true),
737     frm_int(0),
738     m_fps_received(0),
739     m_fps_prev(0),
740     m_drc_enable(0),
741     in_reconfig(false),
742     c2d_enable_pending(false),
743     m_display_id(NULL),
744     client_extradata(0),
745 #ifdef _ANDROID_
746     m_enable_android_native_buffers(OMX_FALSE),
747     m_use_android_native_buffers(OMX_FALSE),
748 #endif
749     m_disable_dynamic_buf_mode(0),
750     m_desc_buffer_ptr(NULL),
751     secure_mode(false),
752     allocate_native_handle(false),
753     client_set_fps(false),
754     stereo_output_mode(HAL_NO_3D),
755     m_last_rendered_TS(-1),
756     m_dec_hfr_fps(0),
757     m_dec_secure_prefetch_size_internal(0),
758     m_dec_secure_prefetch_size_output(0),
759     m_arb_mode_override(0),
760     m_queued_codec_config_count(0),
761     secure_scaling_to_non_secure_opb(false),
762     m_force_compressed_for_dpb(true),
763     m_is_display_session(false),
764     m_prefetch_done(0),
765     m_is_split_mode(false),
766     m_buffer_error(false)
767 {
768     m_poll_efd = -1;
769     memset(&drv_ctx, 0, sizeof(drv_ctx));
770     drv_ctx.video_driver_fd = -1;
771     drv_ctx.extradata_info.ion.data_fd = -1;
772     drv_ctx.extradata_info.ion.dev_fd = -1;
773     /* Assumption is that , to begin with , we have all the frames with decoder */
774     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
775     memset(&m_debug,0,sizeof(m_debug));
776 #ifdef _ANDROID_
777 
778     char property_value[PROPERTY_VALUE_MAX] = {0};
779     property_get("vendor.vidc.debug.level", property_value, "1");
780     debug_level = strtoul(property_value, NULL, 16);
781     property_value[0] = '\0';
782 
783     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
784 
785     // TODO: Support in XML
786     perf_flag = 0;
787     if (perf_flag) {
788         DEBUG_PRINT_HIGH("perf flag is %d", perf_flag);
789         dec_time.start();
790     }
791     proc_frms = latency = 0;
792     prev_n_filled_len = 0;
793 
794     Platform::Config::getInt32(Platform::vidc_dec_log_in,
795             (int32_t *)&m_debug.in_buffer_log, 0);
796     Platform::Config::getInt32(Platform::vidc_dec_log_out,
797             (int32_t *)&m_debug.out_buffer_log, 0);
798 
799     Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_internal,
800             (int32_t *)&m_dec_secure_prefetch_size_internal, 0);
801     Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_output,
802             (int32_t *)&m_dec_secure_prefetch_size_output, 0);
803 
804     DEBUG_PRINT_HIGH("Prefetch size internal = %d, output = %d",
805             m_dec_secure_prefetch_size_internal, m_dec_secure_prefetch_size_output);
806 
807     Platform::Config::getInt32(Platform::vidc_dec_arb_mode_override,
808             (int32_t *)&m_arb_mode_override, 0);
809 
810     Platform::Config::getInt32(Platform::vidc_perf_control_enable,
811             (int32_t *)&m_perf_control.m_perf_control_enable, 0);
812     if (m_perf_control.m_perf_control_enable) {
813         DEBUG_PRINT_HIGH("perf cotrol enabled");
814         m_perf_control.load_perf_library();
815     }
816 
817     property_value[0] = '\0';
818     property_get("vendor.vidc.dec.log.in", property_value, "0");
819     m_debug.in_buffer_log |= atoi(property_value);
820 
821     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.in value is %d", m_debug.in_buffer_log);
822 
823     property_value[0] = '\0';
824     property_get("vendor.vidc.dec.log.out", property_value, "0");
825     m_debug.out_buffer_log |= atoi(property_value);
826 
827     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.out value is %d", m_debug.out_buffer_log);
828 
829     property_value[0] = '\0';
830     property_get("vendor.vidc.dec.log.cc.out", property_value, "0");
831     m_debug.out_cc_buffer_log |= atoi(property_value);
832 
833     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.cc.out value is %d", m_debug.out_buffer_log);
834 
835     property_value[0] = '\0';
836     property_get("vendor.vidc.dec.meta.log.out", property_value, "0");
837     m_debug.out_meta_buffer_log = atoi(property_value);
838 
839     property_value[0] = '\0';
840     property_get("vendor.vidc.log.loc", property_value, BUFFER_LOG_LOC);
841     if (*property_value)
842         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
843 
844     struct timeval te;
845     gettimeofday(&te, NULL);
846     m_debug.session_id = te.tv_sec*1000LL + te.tv_usec/1000;
847     m_debug.seq_count = 0;
848 
849 #ifdef _UBWC_
850     property_value[0] = '\0';
851     property_get("vendor.gralloc.disable_ubwc", property_value, "0");
852     m_disable_ubwc_mode = atoi(property_value);
853     DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
854 #else
855     m_disable_ubwc_mode = true;
856 #endif
857 #endif
858     memset(&m_cmp,0,sizeof(m_cmp));
859     memset(&m_cb,0,sizeof(m_cb));
860     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
861     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
862     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
863     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
864     memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
865     memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
866     memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
867     memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
868     m_demux_entries = 0;
869     msg_thread_id = 0;
870     async_thread_id = 0;
871     msg_thread_created = false;
872     async_thread_created = false;
873     async_thread_force_stop = false;
874     message_thread_stop = false;
875 #ifdef _ANDROID_ICS_
876     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
877 #endif
878 
879     /* invalidate m_frame_pack_arrangement */
880     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
881     m_frame_pack_arrangement.cancel_flag = 1;
882 
883     drv_ctx.timestamp_adjust = false;
884     m_vendor_config.pData = NULL;
885     pthread_mutex_init(&m_lock, NULL);
886     pthread_mutex_init(&c_lock, NULL);
887     pthread_mutex_init(&buf_lock, NULL);
888     pthread_mutex_init(&m_hdr10pluslock, NULL);
889     sem_init(&m_cmd_lock,0,0);
890     sem_init(&m_safe_flush, 0, 0);
891     streaming[CAPTURE_PORT] =
892         streaming[OUTPUT_PORT] = false;
893 #ifdef _ANDROID_
894     // TODO: Support in XML
895     m_debug_extradata = 0;
896 #endif
897     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
898     client_buffers.set_vdec_client(this);
899     dynamic_buf_mode = false;
900     is_down_scalar_enabled = false;
901     m_downscalar_width = 0;
902     m_downscalar_height = 0;
903     m_force_down_scalar = 0;
904     m_reconfig_height = 0;
905     m_reconfig_width = 0;
906     m_smoothstreaming_mode = false;
907     m_smoothstreaming_width = 0;
908     m_smoothstreaming_height = 0;
909     m_decode_order_mode = false;
910     m_perf_control.perf_lock_acquire();
911     m_client_req_turbo_mode = false;
912     is_q6_platform = false;
913     m_input_pass_buffer_fd = false;
914     memset(&m_extradata_info, 0, sizeof(m_extradata_info));
915     m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
916     m_client_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
917     m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
918     m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
919     m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
920 
921     m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
922     m_internal_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
923     m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
924     m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
925     m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
926     m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
927 
928     m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
929     m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
930 
931     m_dither_config = DITHER_DISABLE;
932 
933     DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config);
934     m_etb_count = 0;
935     m_etb_timestamp = 0;
936 
937     m_color_space = EXCEPT_BT2020;
938 
939     init_color_aspects_map();
940 
941     profile_level_converter::init();
942     mClientSessionForSufficiency = false;
943     mClientSetProfile = 0;
944     mClientSetLevel = 0;
945 #ifdef USE_GBM
946      drv_ctx.gbm_device_fd = -1;
947 #endif
948 }
949 
950 static const int event_type[] = {
951     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
952     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
953     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
954     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
955     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
956     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
957     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
958     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
959 };
960 
961 static OMX_ERRORTYPE subscribe_to_events(int fd)
962 {
963     OMX_ERRORTYPE eRet = OMX_ErrorNone;
964     struct v4l2_event_subscription sub;
965     int array_sz = sizeof(event_type)/sizeof(int);
966     int i,rc;
967     if (fd < 0) {
968         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
969         return OMX_ErrorBadParameter;
970     }
971 
972     for (i = 0; i < array_sz; ++i) {
973         memset(&sub, 0, sizeof(sub));
974         sub.type = event_type[i];
975         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
976         if (rc) {
977             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
978             break;
979         }
980     }
981     if (i < array_sz) {
982         for (--i; i >=0 ; i--) {
983             memset(&sub, 0, sizeof(sub));
984             sub.type = event_type[i];
985             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
986             if (rc)
987                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
988         }
989         eRet = OMX_ErrorNotImplemented;
990     }
991     return eRet;
992 }
993 
994 
995 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
996 {
997     OMX_ERRORTYPE eRet = OMX_ErrorNone;
998     struct v4l2_event_subscription sub;
999     int array_sz = sizeof(event_type)/sizeof(int);
1000     int i,rc;
1001     if (fd < 0) {
1002         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1003         return OMX_ErrorBadParameter;
1004     }
1005 
1006     for (i = 0; i < array_sz; ++i) {
1007         memset(&sub, 0, sizeof(sub));
1008         sub.type = event_type[i];
1009         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1010         if (rc) {
1011             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1012             break;
1013         }
1014     }
1015     return eRet;
1016 }
1017 
1018 /* ======================================================================
1019    FUNCTION
1020    omx_vdec::~omx_vdec
1021 
1022    DESCRIPTION
1023    Destructor
1024 
1025    PARAMETERS
1026    None
1027 
1028    RETURN VALUE
1029    None.
1030    ========================================================================== */
1031 omx_vdec::~omx_vdec()
1032 {
1033     m_pmem_info = NULL;
1034     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
1035     if (msg_thread_created) {
1036         DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
1037         message_thread_stop = true;
1038         post_message(this, OMX_COMPONENT_CLOSE_MSG);
1039         DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
1040         pthread_join(msg_thread_id,NULL);
1041     }
1042     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
1043     if(eventfd_write(m_poll_efd, 1)) {
1044          DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1045          async_thread_force_stop = true;
1046     }
1047     if (async_thread_created)
1048         pthread_join(async_thread_id,NULL);
1049 
1050     if (m_prefetch_done & 0x1)
1051         prefetch_buffers(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, ION_IOC_DRAIN, ION_FLAG_CP_PIXEL);
1052     if (m_prefetch_done & 0x2)
1053         prefetch_buffers(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, ION_IOC_DRAIN, ION_FLAG_CP_NON_PIXEL);
1054 
1055     unsubscribe_to_events(drv_ctx.video_driver_fd);
1056     close(m_poll_efd);
1057 #ifdef HYPERVISOR
1058     hypv_close(drv_ctx.video_driver_fd);
1059 #else
1060     close(drv_ctx.video_driver_fd);
1061 #endif
1062     clear_hdr10plusinfo();
1063     pthread_mutex_destroy(&m_lock);
1064     pthread_mutex_destroy(&c_lock);
1065     pthread_mutex_destroy(&buf_lock);
1066     pthread_mutex_destroy(&m_hdr10pluslock);
1067     sem_destroy(&m_cmd_lock);
1068     if (perf_flag) {
1069         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
1070         dec_time.end();
1071     }
1072     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
1073     m_perf_control.perf_lock_release();
1074 }
1075 
1076 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode)
1077 {
1078     int rc = 0;
1079     struct v4l2_ext_control ctrl[1];
1080     struct v4l2_ext_controls controls;
1081 
1082     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
1083     if (is_split_mode) {
1084         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
1085     } else {
1086         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
1087     }
1088 
1089     controls.count = 1;
1090     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
1091     controls.controls = ctrl;
1092 
1093     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
1094     if (rc) {
1095         DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
1096         return OMX_ErrorUnsupportedSetting;
1097     }
1098     m_is_split_mode = is_split_mode;
1099     return OMX_ErrorNone;
1100 
1101 }
1102 
1103 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
1104 {
1105     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1106     struct v4l2_format fmt;
1107     int rc = 0;
1108 
1109     // Default is Combined Mode
1110     bool enable_split = false;
1111     bool is_client_dest_format_non_ubwc = (
1112                      capture_capability != V4L2_PIX_FMT_NV12_UBWC &&
1113                      capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC);
1114     bool dither_enable = false;
1115     bool capability_changed = false;
1116 
1117     switch (m_dither_config) {
1118     case DITHER_DISABLE:
1119         dither_enable = false;
1120         break;
1121     case DITHER_COLORSPACE_EXCEPTBT2020:
1122         dither_enable = (m_color_space == EXCEPT_BT2020);
1123         break;
1124     case DITHER_ALL_COLORSPACE:
1125         dither_enable = true;
1126         break;
1127     default:
1128         DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config);
1129     }
1130 
1131     // Reset v4l2_foramt struct object
1132     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1133 
1134     if (is_client_dest_format_non_ubwc){
1135         // Assuming all the else blocks are for 8 bit depth
1136         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1137             enable_split = true;
1138             if(is_flexible_format){ // if flexible formats are expected, P010 is set for 10bit cases here
1139                  drv_ctx.output_format = VDEC_YUV_FORMAT_P010_VENUS;
1140                  capture_capability = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
1141                  capability_changed = true;
1142             }
1143         } else  if (m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE) {
1144             enable_split = true;
1145         } else {
1146             // Hardware does not support NV12+interlace clips.
1147             // Request NV12_UBWC and convert it to NV12+interlace using C2D
1148             // in combined mode
1149             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
1150             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
1151             capability_changed = true;
1152         }
1153     } else {
1154         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1155             enable_split = dither_enable;
1156 
1157             if (dither_enable) {
1158                 capture_capability = m_disable_ubwc_mode ?
1159                             V4L2_PIX_FMT_NV12 : V4L2_PIX_FMT_NV12_UBWC;
1160                 capability_changed = true;
1161             } else {
1162                 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
1163                 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
1164                 capability_changed = true;
1165             }
1166         }
1167         // 8 bit depth uses the default.
1168         // Combined mode
1169         // V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE
1170     }
1171 
1172     if (capability_changed == true) {
1173         // Get format for CAPTURE port
1174         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1175         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1176         if (rc) {
1177             DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__);
1178             return OMX_ErrorUnsupportedSetting;
1179         }
1180 
1181         // Set Capability for CAPTURE port if there is a change
1182         fmt.fmt.pix_mp.pixelformat = capture_capability;
1183         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1184         if (rc) {
1185             DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1186             return OMX_ErrorUnsupportedSetting;
1187         }
1188     }
1189     // Check the component for its valid current state
1190     if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
1191         !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
1192         DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
1193         return OMX_ErrorNone;
1194     }
1195     eRet = set_dpb(enable_split);
1196     if (eRet) {
1197         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
1198     }
1199 
1200     return eRet;
1201 }
1202 
1203 bool omx_vdec::check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)
1204 {
1205     if(required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
1206          required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus) {
1207          //for now, the flexible formats should be NV12 by default for 8bit cases
1208          //it will change to P010 after 10bit port-reconfig accordingly
1209        return TRUE;
1210     }
1211     else {
1212        return FALSE;
1213     }
1214 }
1215 
1216 int omx_vdec::enable_downscalar()
1217 {
1218     int rc = 0;
1219     struct v4l2_control control;
1220     struct v4l2_format fmt;
1221 
1222     if (is_down_scalar_enabled) {
1223         DEBUG_PRINT_LOW("%s: already enabled", __func__);
1224         return 0;
1225     }
1226 
1227     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
1228     rc = decide_dpb_buffer_mode();
1229     if (rc) {
1230         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
1231         return rc;
1232     }
1233     is_down_scalar_enabled = true;
1234 
1235     return 0;
1236 }
1237 
1238 int omx_vdec::disable_downscalar()
1239 {
1240     int rc = 0;
1241     struct v4l2_control control;
1242 
1243     if (!is_down_scalar_enabled) {
1244         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
1245         return 0;
1246     }
1247     rc = decide_dpb_buffer_mode();
1248     if (rc < 0) {
1249         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
1250         return rc;
1251     }
1252     is_down_scalar_enabled = false;
1253 
1254     return rc;
1255 }
1256 
1257 int omx_vdec::decide_downscalar()
1258 {
1259     int rc = 0;
1260     struct v4l2_format fmt;
1261     enum color_fmts color_format;
1262     OMX_U32 width, height;
1263     OMX_BOOL isPortraitVideo = OMX_FALSE;
1264 
1265     if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
1266         rc = disable_downscalar();
1267         if (rc) {
1268             DEBUG_PRINT_ERROR("Disable downscalar failed!");
1269             return rc;
1270         }
1271         return 0;
1272     }
1273 
1274 #ifdef _QUERY_DISP_RES_
1275     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1276     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1277     fmt.fmt.pix_mp.pixelformat = capture_capability;
1278     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1279     if (rc < 0) {
1280        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1281        return rc;
1282     }
1283     isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
1284     if (!m_downscalar_width || !m_downscalar_height) {
1285         qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
1286         int prim_config, ext_config, virt_config;
1287 
1288         prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
1289         dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
1290         DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d  dpa.yres=%d   dpa.xdpi = %f  dpa.ydpi = %f ",
1291             __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
1292 
1293         ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
1294         dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
1295         DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d  dsa.yres = %d   dsa.xdpi = %f  dsa.ydpi = %f ",
1296             __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
1297 
1298         virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
1299         dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
1300         DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d  dva.yres = %d   dva.xdpi = %f  dva.ydpi = %f ",
1301             __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
1302 
1303         /* Below logic takes care of following conditions:
1304          *   1. Choose display resolution as maximum resolution of all the connected
1305          *      displays (secondary, primary, virtual), so that we do not downscale
1306          *      unnecessarily which might be supported on one of the display losing quality.
1307          *   2. Displays connected might be in landscape or portrait mode, so the xres might
1308          *      be smaller or greater than the yres. So we first take the max of the two
1309          *      in width and min of two in height and then rotate it if below point is true.
1310          *   3. Video might also be in portrait mode, so invert the downscalar width and
1311          *      height for such cases.
1312          */
1313         if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
1314             m_downscalar_width = MAX(dsa.xres, dsa.yres);
1315             m_downscalar_height = MIN(dsa.xres, dsa.yres);
1316         } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
1317             m_downscalar_width = MAX(dva.xres, dva.yres);
1318             m_downscalar_height = MIN(dva.xres, dva.yres);
1319 
1320         } else {
1321             m_downscalar_width = MAX(dpa.xres, dpa.yres);
1322             m_downscalar_height = MIN(dpa.xres, dpa.yres);
1323         }
1324         if (isPortraitVideo) {
1325             // Swap width and height
1326             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1327             m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
1328             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1329         }
1330     }
1331     m_downscalar_width = ALIGN(m_downscalar_width, 128);
1332     m_downscalar_height = ALIGN(m_downscalar_height, 32);
1333 #endif
1334 
1335     if (!m_downscalar_width || !m_downscalar_height) {
1336         DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
1337         return 0;
1338     }
1339 
1340     if (m_force_down_scalar) {
1341         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
1342         return 0;
1343     }
1344 
1345     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1346     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1347     fmt.fmt.pix_mp.pixelformat = capture_capability;
1348     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1349     if (rc < 0) {
1350        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1351        return rc;
1352     }
1353 
1354     height = fmt.fmt.pix_mp.height;
1355     width = fmt.fmt.pix_mp.width;
1356 
1357     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
1358         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
1359 
1360     if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) &&
1361          m_is_display_session) {
1362         rc = enable_downscalar();
1363         if (rc < 0) {
1364             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
1365             return rc;
1366         }
1367 
1368         width = m_downscalar_width > fmt.fmt.pix_mp.width ?
1369                             fmt.fmt.pix_mp.width : m_downscalar_width;
1370         height = m_downscalar_height > fmt.fmt.pix_mp.height ?
1371                             fmt.fmt.pix_mp.height : m_downscalar_height;
1372         switch (capture_capability) {
1373             case V4L2_PIX_FMT_NV12:
1374                 color_format = COLOR_FMT_NV12;
1375                 break;
1376             case V4L2_PIX_FMT_NV12_UBWC:
1377                 color_format = COLOR_FMT_NV12_UBWC;
1378                 break;
1379             case V4L2_PIX_FMT_NV12_TP10_UBWC:
1380                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
1381                 break;
1382             default:
1383                 DEBUG_PRINT_ERROR("Color format not recognized\n");
1384                 rc = OMX_ErrorUndefined;
1385                 return rc;
1386         }
1387     } else {
1388 
1389         rc = disable_downscalar();
1390         if (rc < 0) {
1391             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
1392             return rc;
1393         }
1394     }
1395 
1396     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1397     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1398     fmt.fmt.pix_mp.height = height;
1399     fmt.fmt.pix_mp.width = width;
1400     fmt.fmt.pix_mp.pixelformat = capture_capability;
1401     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1402     if (rc) {
1403         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1404         return rc;
1405     }
1406 
1407     rc = get_buffer_req(&drv_ctx.op_buf);
1408     if (rc) {
1409         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
1410         return rc;
1411     }
1412 
1413     return rc;
1414 }
1415 
1416 /* ======================================================================
1417    FUNCTION
1418    omx_vdec::OMXCntrlProcessMsgCb
1419 
1420    DESCRIPTION
1421    IL Client callbacks are generated through this routine. The decoder
1422    provides the thread context for this routine.
1423 
1424    PARAMETERS
1425    ctxt -- Context information related to the self.
1426    id   -- Event identifier. This could be any of the following:
1427    1. Command completion event
1428    2. Buffer done callback event
1429    3. Frame done callback event
1430 
1431    RETURN VALUE
1432    None.
1433 
1434    ========================================================================== */
1435 void omx_vdec::process_event_cb(void *ctxt)
1436 {
1437     unsigned long p1; // Parameter - 1
1438     unsigned long p2; // Parameter - 2
1439     unsigned long ident;
1440     unsigned qsize=0; // qsize
1441     omx_vdec *pThis = (omx_vdec *) ctxt;
1442 
1443     if (!pThis) {
1444         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
1445                 __func__);
1446         return;
1447     }
1448 
1449     // Protect the shared queue data structure
1450     do {
1451         /*Read the message id's from the queue*/
1452         pthread_mutex_lock(&pThis->m_lock);
1453         qsize = pThis->m_cmd_q.m_size;
1454         if (qsize) {
1455             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
1456         }
1457 
1458         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1459             qsize = pThis->m_ftb_q.m_size;
1460             if (qsize) {
1461                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
1462             }
1463         }
1464 
1465         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1466             qsize = pThis->m_etb_q.m_size;
1467             if (qsize) {
1468                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
1469             }
1470         }
1471         pthread_mutex_unlock(&pThis->m_lock);
1472 
1473         /*process message if we have one*/
1474         if (qsize > 0) {
1475             switch (ident) {
1476                 case OMX_COMPONENT_GENERATE_EVENT:
1477                     if (pThis->m_cb.EventHandler) {
1478                         switch (p1) {
1479                             case OMX_CommandStateSet:
1480                                 pThis->m_state = (OMX_STATETYPE) p2;
1481                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
1482                                         pThis->m_state);
1483                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1484                                         OMX_EventCmdComplete, p1, p2, NULL);
1485                                 break;
1486 
1487                             case OMX_EventError:
1488                                 if (p2 == OMX_StateInvalid) {
1489                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
1490                                     pThis->m_state = (OMX_STATETYPE) p2;
1491                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1492                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
1493                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
1494                                     pThis->omx_report_error();
1495                                 } else {
1496                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1497                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
1498                                 }
1499                                 break;
1500 
1501                             case OMX_CommandPortDisable:
1502                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
1503                                 if (BITMASK_PRESENT(&pThis->m_flags,
1504                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1505                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1506                                     break;
1507                                 }
1508                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
1509                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1510                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
1511                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
1512                                     pThis->in_reconfig = false;
1513                                     pThis->client_buffers.enable_color_conversion(pThis->c2d_enable_pending);
1514                                     if (eRet !=  OMX_ErrorNone) {
1515                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
1516                                         pThis->omx_report_error();
1517                                         break;
1518                                     }
1519                                 }
1520                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1521                                         OMX_EventCmdComplete, p1, p2, NULL );
1522                                 break;
1523                             case OMX_CommandPortEnable:
1524                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
1525                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
1526                                         OMX_EventCmdComplete, p1, p2, NULL );
1527                                 break;
1528 
1529                             default:
1530                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1531                                         OMX_EventCmdComplete, p1, p2, NULL );
1532                                 break;
1533 
1534                         }
1535                     } else {
1536                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1537                     }
1538                     break;
1539                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
1540                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
1541                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1542                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
1543                         pThis->omx_report_error ();
1544                     }
1545                     break;
1546                 case OMX_COMPONENT_GENERATE_ETB: {
1547                         OMX_ERRORTYPE iret;
1548                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
1549                         if (iret == OMX_ErrorInsufficientResources) {
1550                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
1551                             pThis->omx_report_hw_overload ();
1552                         } else if (iret != OMX_ErrorNone) {
1553                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
1554                             pThis->omx_report_error ();
1555                         }
1556                     }
1557                     break;
1558 
1559                 case OMX_COMPONENT_GENERATE_FTB:
1560                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
1561                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1562                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
1563                         pThis->omx_report_error ();
1564                     }
1565                     break;
1566 
1567                 case OMX_COMPONENT_GENERATE_COMMAND:
1568                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
1569                             (OMX_U32)p2,(OMX_PTR)NULL);
1570                     break;
1571 
1572                 case OMX_COMPONENT_GENERATE_EBD:
1573 
1574                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
1575                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
1576                         pThis->omx_report_error ();
1577                     } else {
1578                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
1579                             pThis->time_stamp_dts.remove_time_stamp(
1580                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
1581                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1582                                     ?true:false);
1583                         }
1584 
1585                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
1586                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
1587                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
1588                             pThis->omx_report_error ();
1589                         }
1590                     }
1591                     break;
1592                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
1593                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
1594                                             if (p1) {
1595                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
1596                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1597                                                         ?true:false);
1598                                                 free(timestamp);
1599                                             }
1600                                         }
1601                                         break;
1602                 case OMX_COMPONENT_GENERATE_FBD:
1603                                         if (p2 != VDEC_S_SUCCESS) {
1604                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
1605                                             pThis->omx_report_error ();
1606                                             break;
1607                                         }
1608                                         if (pThis->fill_buffer_done(&pThis->m_cmp,
1609                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
1610                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
1611                                             pThis->omx_report_error ();
1612                                             break;
1613                                         }
1614 #if !HDR10_SETMETADATA_ENABLE
1615                                         if (pThis->output_capability != V4L2_PIX_FMT_VP9 &&
1616                                             pThis->output_capability != V4L2_PIX_FMT_HEVC)
1617                                             break;
1618 
1619                                         if (!pThis->m_cb.EventHandler) {
1620                                             DEBUG_PRINT_ERROR("fill_buffer_done: null event handler");
1621                                             break;
1622                                         }
1623                                         bool is_list_empty;
1624                                         is_list_empty = false;
1625                                         pthread_mutex_lock(&pThis->m_hdr10pluslock);
1626                                         is_list_empty = pThis->m_hdr10pluslist.empty();
1627                                         pthread_mutex_unlock(&pThis->m_hdr10pluslock);
1628                                         if (!is_list_empty) {
1629                                             DEBUG_PRINT_LOW("fill_buffer_done: event config update");
1630                                             pThis->m_cb.EventHandler(&pThis->m_cmp,
1631                                                     pThis->m_app_data,
1632                                                     OMX_EventConfigUpdate,
1633                                                     OMX_CORE_OUTPUT_PORT_INDEX,
1634                                                     OMX_QTIIndexConfigDescribeHDR10PlusInfo, NULL);
1635                                         }
1636 #endif
1637                                         break;
1638 
1639                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
1640                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete, flags %#llx",
1641                                                 (unsigned long long)pThis->m_flags);
1642                                         if (!pThis->input_flush_progress) {
1643                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1644                                         } else {
1645                                             pThis->execute_input_flush();
1646                                             if (pThis->m_cb.EventHandler) {
1647                                                 if (p2 != VDEC_S_SUCCESS) {
1648                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
1649                                                     pThis->omx_report_error ();
1650                                                 } else {
1651                                                     /*Check if we need generate event for Flush done*/
1652                                                     pThis->notify_flush_done(ctxt);
1653 
1654                                                     if (BITMASK_PRESENT(&pThis->m_flags,
1655                                                                 OMX_COMPONENT_IDLE_PENDING)) {
1656                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
1657                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
1658                                                             pThis->omx_report_error ();
1659                                                         } else {
1660                                                             pThis->streaming[OUTPUT_PORT] = false;
1661                                                         }
1662                                                         if (!pThis->output_flush_progress) {
1663                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
1664                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1665                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
1666                                                         }
1667                                                     }
1668                                                 }
1669                                             } else {
1670                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1671                                             }
1672                                         }
1673                                         break;
1674 
1675                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1676                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete, flags %#llx",
1677                                                 (unsigned long long)pThis->m_flags);
1678                                         if (!pThis->output_flush_progress) {
1679                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1680                                         } else {
1681                                             pThis->execute_output_flush();
1682                                             if (pThis->m_cb.EventHandler) {
1683                                                 if (p2 != VDEC_S_SUCCESS) {
1684                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1685                                                     pThis->omx_report_error ();
1686                                                 } else {
1687                                                     /*Check if we need generate event for Flush done*/
1688                                                     pThis->notify_flush_done(ctxt);
1689 
1690                                                     if (BITMASK_PRESENT(&pThis->m_flags,
1691                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1692                                                         DEBUG_PRINT_LOW("Internal flush complete");
1693                                                         BITMASK_CLEAR (&pThis->m_flags,
1694                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1695                                                         if (BITMASK_PRESENT(&pThis->m_flags,
1696                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1697                                                             pThis->post_event(OMX_CommandPortDisable,
1698                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
1699                                                                     OMX_COMPONENT_GENERATE_EVENT);
1700                                                             BITMASK_CLEAR (&pThis->m_flags,
1701                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1702                                                             BITMASK_CLEAR (&pThis->m_flags,
1703                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1704 
1705                                                         }
1706                                                     }
1707 
1708                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1709                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1710                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
1711                                                             pThis->omx_report_error ();
1712                                                             break;
1713                                                         }
1714                                                         pThis->streaming[CAPTURE_PORT] = false;
1715                                                         if (!pThis->input_flush_progress) {
1716                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
1717                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1718                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
1719                                                         }
1720                                                     }
1721                                                 }
1722                                             } else {
1723                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1724                                             }
1725                                         }
1726                                         break;
1727 
1728                 case OMX_COMPONENT_GENERATE_START_DONE:
1729                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE, flags %#llx",
1730                                                 (unsigned long long)pThis->m_flags);
1731                                         if (pThis->m_cb.EventHandler) {
1732                                             if (p2 != VDEC_S_SUCCESS) {
1733                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
1734                                                 pThis->omx_report_error ();
1735                                             } else {
1736                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
1737                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1738                                                     DEBUG_PRINT_LOW("Move to executing");
1739                                                     // Send the callback now
1740                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1741                                                     pThis->m_state = OMX_StateExecuting;
1742                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1743                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1744                                                             OMX_StateExecuting, NULL);
1745                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
1746                                                             OMX_COMPONENT_PAUSE_PENDING)) {
1747                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1748                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1749                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
1750                                                         pThis->omx_report_error ();
1751                                                     }
1752                                                 }
1753                                             }
1754                                         } else {
1755                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
1756                                         }
1757                                         break;
1758 
1759                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1760                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1761                                         if (pThis->m_cb.EventHandler) {
1762                                             if (p2 != VDEC_S_SUCCESS) {
1763                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1764                                                 pThis->omx_report_error ();
1765                                             } else {
1766                                                 pThis->complete_pending_buffer_done_cbs();
1767                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1768                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1769                                                     //Send the callback now
1770                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1771                                                     pThis->m_state = OMX_StatePause;
1772                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1773                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1774                                                             OMX_StatePause, NULL);
1775                                                 }
1776                                             }
1777                                         } else {
1778                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1779                                         }
1780 
1781                                         break;
1782 
1783                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1784                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1785                                         if (pThis->m_cb.EventHandler) {
1786                                             if (p2 != VDEC_S_SUCCESS) {
1787                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1788                                                 pThis->omx_report_error ();
1789                                             } else {
1790                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1791                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
1792                                                     // Send the callback now
1793                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1794                                                     pThis->m_state = OMX_StateExecuting;
1795                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1796                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1797                                                             OMX_StateExecuting,NULL);
1798                                                 }
1799                                             }
1800                                         } else {
1801                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1802                                         }
1803 
1804                                         break;
1805 
1806                 case OMX_COMPONENT_GENERATE_STOP_DONE:
1807                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1808                                         if (pThis->m_cb.EventHandler) {
1809                                             if (p2 != VDEC_S_SUCCESS) {
1810                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1811                                                 pThis->omx_report_error ();
1812                                             } else {
1813                                                 pThis->complete_pending_buffer_done_cbs();
1814                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1815                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
1816                                                     // Send the callback now
1817                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1818                                                     pThis->m_state = OMX_StateIdle;
1819                                                     DEBUG_PRINT_LOW("Move to Idle State");
1820                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1821                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1822                                                             OMX_StateIdle,NULL);
1823                                                 }
1824                                             }
1825                                         } else {
1826                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1827                                         }
1828 
1829                                         break;
1830 
1831                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1832                                         if (p2 == OMX_IndexParamPortDefinition) {
1833                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
1834                                             pThis->in_reconfig = true;
1835                                             pThis->prev_n_filled_len = 0;
1836                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1837                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
1838 
1839                                             /* Check if resolution is changed in smooth streaming mode */
1840                                             if (pThis->m_smoothstreaming_mode &&
1841                                                 (pThis->framesize.nWidth !=
1842                                                     pThis->drv_ctx.video_resolution.frame_width) ||
1843                                                 (pThis->framesize.nHeight !=
1844                                                     pThis->drv_ctx.video_resolution.frame_height)) {
1845 
1846                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1847                                                         pThis->framesize.nWidth,
1848                                                         pThis->framesize.nHeight,
1849                                                         pThis->drv_ctx.video_resolution.frame_width,
1850                                                         pThis->drv_ctx.video_resolution.frame_height);
1851 
1852                                                 /* Update new resolution */
1853                                                 pThis->framesize.nWidth =
1854                                                        pThis->drv_ctx.video_resolution.frame_width;
1855                                                 pThis->framesize.nHeight =
1856                                                        pThis->drv_ctx.video_resolution.frame_height;
1857 
1858                                                 /* Update C2D with new resolution */
1859                                                 if (!pThis->client_buffers.update_buffer_req()) {
1860                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1861                                                 }
1862                                             }
1863 
1864                                             /* Update new crop information */
1865                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1866                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1867                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1868                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1869 
1870                                             /* Validate the new crop information */
1871                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1872                                                 pThis->drv_ctx.video_resolution.frame_width) {
1873 
1874                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1875                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1876                                                         pThis->drv_ctx.video_resolution.frame_width);
1877                                                 pThis->rectangle.nLeft = 0;
1878 
1879                                                 if (pThis->rectangle.nWidth >
1880                                                     pThis->drv_ctx.video_resolution.frame_width) {
1881 
1882                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1883                                                             pThis->rectangle.nWidth,
1884                                                             pThis->drv_ctx.video_resolution.frame_width);
1885                                                     pThis->rectangle.nWidth =
1886                                                         pThis->drv_ctx.video_resolution.frame_width;
1887                                                 }
1888                                             }
1889                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1890                                                 pThis->drv_ctx.video_resolution.frame_height) {
1891 
1892                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1893                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
1894                                                     pThis->drv_ctx.video_resolution.frame_height);
1895                                                 pThis->rectangle.nTop = 0;
1896 
1897                                                 if (pThis->rectangle.nHeight >
1898                                                     pThis->drv_ctx.video_resolution.frame_height) {
1899 
1900                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1901                                                         pThis->rectangle.nHeight,
1902                                                         pThis->drv_ctx.video_resolution.frame_height);
1903                                                     pThis->rectangle.nHeight =
1904                                                         pThis->drv_ctx.video_resolution.frame_height;
1905                                                 }
1906                                             }
1907                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1908                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
1909                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1910                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
1911                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
1912                                         } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) {
1913                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo");
1914                                         } else {
1915                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1916                                             break;
1917                                         }
1918                                         if (pThis->m_debug.outfile) {
1919                                             fclose(pThis->m_debug.outfile);
1920                                             pThis->m_debug.outfile = NULL;
1921                                         }
1922                                         if (pThis->m_debug.ccoutfile) {
1923                                             fclose(pThis->m_debug.ccoutfile);
1924                                             pThis->m_debug.ccoutfile = NULL;
1925                                         }
1926                                         if (pThis->m_debug.out_ymeta_file) {
1927                                             fclose(pThis->m_debug.out_ymeta_file);
1928                                             pThis->m_debug.out_ymeta_file = NULL;
1929                                         }
1930                                         if (pThis->m_debug.out_uvmeta_file) {
1931                                             fclose(pThis->m_debug.out_uvmeta_file);
1932                                             pThis->m_debug.out_uvmeta_file = NULL;
1933                                         }
1934                                         pThis->m_debug.seq_count++;
1935 
1936                                         if (pThis->m_cb.EventHandler) {
1937                                             void *frame_data = NULL;
1938                                             reconfig_client_data port_data;
1939                                             reconfig_client_crop_data crop_data;
1940                                             if (p2 == OMX_IndexConfigCommonOutputCrop) {
1941                                                 crop_data.width = pThis->rectangle.nWidth;
1942                                                 crop_data.height = pThis->rectangle.nHeight;
1943                                                 crop_data.left = pThis->rectangle.nLeft;
1944                                                 crop_data.top = pThis->rectangle.nTop;
1945                                                 crop_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1946                                                 frame_data = (void*)&crop_data;
1947                                             } else if (p2 == OMX_IndexParamPortDefinition){
1948                                                 port_data.width = pThis->m_reconfig_width;
1949                                                 port_data.height = pThis->m_reconfig_height;
1950                                                 port_data.dpb_bit_depth = pThis->dpb_bit_depth;
1951                                                 port_data.m_progressive = pThis->m_progressive;
1952                                                 port_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1953                                                 frame_data = (void*)&port_data;
1954                                             }
1955                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1956                                                      OMX_EventPortSettingsChanged, p1, p2, (void*)frame_data);
1957                                         } else {
1958                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1959                                         }
1960                                         break;
1961 
1962                 case OMX_COMPONENT_GENERATE_EOS_DONE:
1963                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1964                                         if (pThis->m_cb.EventHandler) {
1965                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1966                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1967                                         } else {
1968                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1969                                         }
1970                                         pThis->prev_ts = LLONG_MAX;
1971                                         pThis->rst_prev_ts = true;
1972                                         break;
1973 
1974                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1975                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1976                                         pThis->omx_report_error();
1977                                         break;
1978 
1979                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1980                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
1981                                         pThis->omx_report_unsupported_setting();
1982                                         break;
1983 
1984                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1985                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1986                                         pThis->omx_report_hw_overload();
1987                                         break;
1988 
1989                 case OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL:
1990                                         DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL");
1991                                         pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_PIXEL);
1992                                         break;
1993 
1994                 case OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL:
1995                                         DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL");
1996                                         pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_NON_PIXEL) << 1;
1997                                         break;
1998 
1999                 default:
2000                                         break;
2001             }
2002         }
2003         pthread_mutex_lock(&pThis->m_lock);
2004         qsize = pThis->m_cmd_q.m_size;
2005         if (pThis->m_state != OMX_StatePause)
2006             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
2007         pthread_mutex_unlock(&pThis->m_lock);
2008     } while (qsize>0);
2009 
2010 }
2011 
2012 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
2013 {
2014     int format_changed = 0;
2015     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
2016             (width != (int)drv_ctx.video_resolution.frame_width)) {
2017         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
2018                 width, drv_ctx.video_resolution.frame_width,
2019                 height,drv_ctx.video_resolution.frame_height);
2020         format_changed = 1;
2021     }
2022     drv_ctx.video_resolution.frame_height = height;
2023     drv_ctx.video_resolution.frame_width = width;
2024     drv_ctx.video_resolution.scan_lines = scan_lines;
2025     drv_ctx.video_resolution.stride = stride;
2026 
2027     if (!is_down_scalar_enabled) {
2028         rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft;
2029         rectangle.nTop = m_extradata_info.output_crop_rect.nTop;
2030         rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth;
2031         rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight;
2032     }
2033     return format_changed;
2034 }
2035 
2036 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len, uint64_t timeStamp, int fd)
2037 {
2038     if (!m_debug.in_buffer_log)
2039         return 0;
2040 
2041 #ifdef USE_ION
2042     do_cache_operations(fd);
2043 #else
2044     (void)fd;
2045 #endif
2046     if (m_debug.in_buffer_log && !m_debug.infile) {
2047         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
2048                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p_%" PRId64 ".mpg", m_debug.log_loc,
2049                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this, m_debug.session_id);
2050         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
2051                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
2052                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
2053                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2054         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
2055                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
2056                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2057         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
2058                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2059                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2060         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2061                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2062                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2063         } else {
2064                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.bin",
2065                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2066         }
2067         m_debug.infile = fopen (m_debug.infile_name, "ab");
2068         if (!m_debug.infile) {
2069             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging (%d:%s)",
2070                              m_debug.infile_name, errno, strerror(errno));
2071             m_debug.infile_name[0] = '\0';
2072 #ifdef USE_ION
2073             do_cache_operations(fd);
2074 #endif
2075             return -1;
2076         }
2077         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2078                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2079             bool isVp9 = drv_ctx.decoder_format == VDEC_CODECTYPE_VP9;
2080             int width = drv_ctx.video_resolution.frame_width;
2081             int height = drv_ctx.video_resolution.frame_height;
2082             int fps = drv_ctx.frame_rate.fps_numerator;
2083             IvfFileHeader ivfHeader(isVp9, width, height, 1, fps, 0);
2084             fwrite((const char *)&ivfHeader,
2085                     sizeof(ivfHeader),1,m_debug.infile);
2086          }
2087     }
2088     if (m_debug.infile && buffer_addr && buffer_len) {
2089         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2090                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2091             IvfFrameHeader ivfFrameHeader(buffer_len, timeStamp);
2092             fwrite(&ivfFrameHeader, sizeof(ivfFrameHeader), 1, m_debug.infile);
2093         }
2094         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
2095     }
2096 #ifdef USE_ION
2097     do_cache_operations(fd);
2098 #endif
2099     return 0;
2100 }
2101 
2102 int omx_vdec::log_cc_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2103     if (client_buffers.client_buffers_invalid() ||
2104         !m_debug.out_cc_buffer_log || !buffer || !buffer->nFilledLen)
2105         return 0;
2106 
2107     if (m_debug.out_cc_buffer_log && !m_debug.ccoutfile) {
2108         snprintf(m_debug.ccoutfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_cc_%d_%d_%p_%" PRId64 "_%d.yuv",
2109                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2110                 m_debug.session_id, m_debug.seq_count);
2111         m_debug.ccoutfile = fopen (m_debug.ccoutfile_name, "ab");
2112         if (!m_debug.ccoutfile) {
2113             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2114             m_debug.ccoutfile_name[0] = '\0';
2115             return -1;
2116         }
2117         DEBUG_PRINT_HIGH("Opened CC output file: %s for logging", m_debug.ccoutfile_name);
2118     }
2119 
2120     fwrite(buffer->pBuffer, buffer->nFilledLen, 1, m_debug.ccoutfile);
2121     return 0;
2122 }
2123 
2124 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2125     int buf_index = 0;
2126     char *temp = NULL;
2127     char *bufaddr = NULL;
2128 
2129     if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
2130         return 0;
2131 
2132     if (m_debug.out_buffer_log && !m_debug.outfile) {
2133         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p_%" PRId64 "_%d.yuv",
2134                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2135                 m_debug.session_id, m_debug.seq_count);
2136         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
2137         if (!m_debug.outfile) {
2138             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2139             m_debug.outfile_name[0] = '\0';
2140             return -1;
2141         }
2142         DEBUG_PRINT_HIGH("Opened output file: %s for logging", m_debug.outfile_name);
2143     }
2144 
2145     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) {
2146         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
2147                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2148         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
2149                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2150         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
2151         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
2152         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
2153             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
2154             m_debug.out_ymetafile_name[0] = '\0';
2155             m_debug.out_uvmetafile_name[0] = '\0';
2156             return -1;
2157         }
2158     }
2159 
2160     buf_index = buffer - m_out_mem_ptr;
2161     bufaddr = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
2162     if (dynamic_buf_mode && !secure_mode) {
2163         bufaddr = ion_map(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd,
2164                           drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2165         //mmap returns (void *)-1 on failure and sets error code in errno.
2166         if (bufaddr == MAP_FAILED) {
2167             DEBUG_PRINT_ERROR("mmap failed - errno: %d", errno);
2168             return -1;
2169         }
2170     }
2171     temp = bufaddr;
2172 
2173     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
2174             drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
2175         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
2176             drv_ctx.video_resolution.frame_width,
2177             drv_ctx.video_resolution.frame_height);
2178 
2179         if (m_debug.outfile)
2180             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
2181 
2182         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
2183             unsigned int width = 0, height = 0;
2184             unsigned int y_plane, y_meta_plane;
2185             int y_stride = 0, y_sclines = 0;
2186             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
2187             int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC;
2188             int i;
2189             int bytes_written = 0;
2190 
2191             width = drv_ctx.video_resolution.frame_width;
2192             height = drv_ctx.video_resolution.frame_height;
2193             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
2194             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
2195             y_stride = VENUS_Y_STRIDE(color_fmt, width);
2196             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
2197             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
2198             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
2199 
2200             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
2201             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
2202 
2203             for (i = 0; i < y_meta_scanlines; i++) {
2204                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
2205                  temp += y_meta_stride;
2206             }
2207 
2208             temp = bufaddr + y_meta_plane + y_plane;
2209             for(i = 0; i < uv_meta_scanlines; i++) {
2210                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
2211                 temp += uv_meta_stride;
2212             }
2213         }
2214     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
2215         int stride = drv_ctx.video_resolution.stride;
2216         int scanlines = drv_ctx.video_resolution.scan_lines;
2217         if (m_smoothstreaming_mode) {
2218             stride = drv_ctx.video_resolution.frame_width;
2219             scanlines = drv_ctx.video_resolution.frame_height;
2220             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2221             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2222         }
2223         unsigned i;
2224         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2225             drv_ctx.video_resolution.frame_width,
2226             drv_ctx.video_resolution.frame_height, stride, scanlines);
2227         int bytes_written = 0;
2228         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2229              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2230              temp += stride;
2231         }
2232         temp = bufaddr + stride * scanlines;
2233         int stride_c = stride;
2234         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2235             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2236             temp += stride_c;
2237         }
2238     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
2239         int stride = drv_ctx.video_resolution.stride;
2240         int scanlines = drv_ctx.video_resolution.scan_lines;
2241         if (m_smoothstreaming_mode) {
2242             stride = drv_ctx.video_resolution.frame_width * 2;
2243             scanlines = drv_ctx.video_resolution.frame_height;
2244             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2245             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2246         }
2247         unsigned i;
2248         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2249             drv_ctx.video_resolution.frame_width,
2250             drv_ctx.video_resolution.frame_height, stride, scanlines);
2251         int bytes_written = 0;
2252         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2253              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2254              temp += stride;
2255         }
2256         temp = bufaddr + stride * scanlines;
2257         int stride_c = stride;
2258         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2259             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2260             temp += stride_c;
2261         }
2262     }
2263 
2264     if (dynamic_buf_mode && !secure_mode) {
2265         ion_unmap(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, bufaddr,
2266                   drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2267     }
2268     return 0;
2269 }
2270 
2271 void omx_vdec::init_color_aspects_map()
2272 {
2273     mPrimariesMap.insert({
2274             {ColorAspects::PrimariesUnspecified, (ColorPrimaries)(2)},
2275             {ColorAspects::PrimariesBT709_5, ColorPrimaries_BT709_5},
2276             {ColorAspects::PrimariesBT470_6M, ColorPrimaries_BT470_6M},
2277             {ColorAspects::PrimariesBT601_6_625, ColorPrimaries_BT601_6_625},
2278             {ColorAspects::PrimariesBT601_6_525, ColorPrimaries_BT601_6_525},
2279             {ColorAspects::PrimariesGenericFilm, ColorPrimaries_GenericFilm},
2280             {ColorAspects::PrimariesBT2020, ColorPrimaries_BT2020},
2281         });
2282     mTransferMap.insert({
2283             {ColorAspects::TransferUnspecified, (GammaTransfer)(2)},
2284             {ColorAspects::TransferLinear, Transfer_Linear},
2285             {ColorAspects::TransferSRGB, Transfer_sRGB},
2286             {ColorAspects::TransferSMPTE170M, Transfer_SMPTE_170M},
2287             {ColorAspects::TransferGamma22, Transfer_Gamma2_2},
2288             {ColorAspects::TransferGamma28, Transfer_Gamma2_8},
2289             {ColorAspects::TransferST2084, Transfer_SMPTE_ST2084},
2290             {ColorAspects::TransferHLG, Transfer_HLG},
2291             {ColorAspects::TransferSMPTE240M, Transfer_SMPTE_240M},
2292             {ColorAspects::TransferXvYCC, Transfer_XvYCC},
2293             {ColorAspects::TransferBT1361, Transfer_BT1361},
2294             {ColorAspects::TransferST428, Transfer_ST_428},
2295         });
2296     mMatrixCoeffMap.insert({
2297             {ColorAspects::MatrixUnspecified, (MatrixCoEfficients)(2)},
2298             {ColorAspects::MatrixBT709_5, MatrixCoEff_BT709_5},
2299             {ColorAspects::MatrixBT470_6M, MatrixCoeff_FCC_73_682},
2300             {ColorAspects::MatrixBT601_6, MatrixCoEff_BT601_6_625},
2301             {ColorAspects::MatrixSMPTE240M, MatrixCoEff_SMPTE240M},
2302             {ColorAspects::MatrixBT2020, MatrixCoEff_BT2020},
2303             {ColorAspects::MatrixBT2020Constant, MatrixCoEff_BT2020Constant},
2304         });
2305     mColorRangeMap.insert({
2306             {ColorAspects::RangeUnspecified, (ColorRange)(2)},
2307             {ColorAspects::RangeFull, Range_Full},
2308             {ColorAspects::RangeLimited, Range_Limited},
2309         });
2310 }
2311 /* ======================================================================
2312    FUNCTION
2313    omx_vdec::ComponentInit
2314 
2315    DESCRIPTION
2316    Initialize the component.
2317 
2318    PARAMETERS
2319    ctxt -- Context information related to the self.
2320    id   -- Event identifier. This could be any of the following:
2321    1. Command completion event
2322    2. Buffer done callback event
2323    3. Frame done callback event
2324 
2325    RETURN VALUE
2326    None.
2327 
2328    ========================================================================== */
2329 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
2330 {
2331 
2332     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2333     struct v4l2_fmtdesc fdesc;
2334     struct v4l2_format fmt;
2335     struct v4l2_requestbuffers bufreq;
2336     struct v4l2_control control;
2337     struct v4l2_frmsizeenum frmsize;
2338     struct v4l2_queryctrl query;
2339     unsigned int   alignment = 0,buffer_size = 0;
2340     int fds[2];
2341     int r,ret=0;
2342     bool codec_ambiguous = false;
2343     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
2344     char property_value[PROPERTY_VALUE_MAX] = {0};
2345     FILE *soc_file = NULL;
2346     char buffer[10];
2347     struct v4l2_ext_control ctrl[2];
2348     struct v4l2_ext_controls controls;
2349     int conceal_color_8bit = 0, conceal_color_10bit = 0;
2350 
2351 #ifdef _ANDROID_
2352     char platform_name[PROPERTY_VALUE_MAX];
2353     property_get("ro.board.platform", platform_name, "0");
2354     if (!strncmp(platform_name, "msm8610", 7)) {
2355         device_name = (OMX_STRING)"/dev/video/q6_dec";
2356         is_q6_platform = true;
2357         maxSmoothStreamingWidth = 1280;
2358         maxSmoothStreamingHeight = 720;
2359     }
2360 #endif
2361 
2362     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
2363                 OMX_MAX_STRINGNAME_SIZE)) {
2364         secure_mode = true;
2365         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
2366     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
2367                 OMX_MAX_STRINGNAME_SIZE)) {
2368         secure_mode = true;
2369         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
2370     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
2371                 OMX_MAX_STRINGNAME_SIZE)) {
2372         secure_mode = true;
2373         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
2374     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
2375                 OMX_MAX_STRINGNAME_SIZE)) {
2376         secure_mode = true;
2377         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
2378     }
2379 
2380 #ifdef HYPERVISOR
2381     drv_ctx.video_driver_fd = hypv_open(device_name, O_RDWR);
2382 #else
2383     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
2384 #endif
2385 
2386     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
2387 
2388     if (drv_ctx.video_driver_fd < 0) {
2389         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
2390         return OMX_ErrorInsufficientResources;
2391     }
2392     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
2393     drv_ctx.frame_rate.fps_denominator = 1;
2394     operating_frame_rate = DEFAULT_FPS;
2395     m_poll_efd = eventfd(0, 0);
2396     if (m_poll_efd < 0) {
2397         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
2398         return OMX_ErrorInsufficientResources;
2399     }
2400     ret = subscribe_to_events(drv_ctx.video_driver_fd);
2401     if (!ret) {
2402         async_thread_created = true;
2403         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
2404     }
2405     if (ret) {
2406         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
2407         async_thread_created = false;
2408         return OMX_ErrorInsufficientResources;
2409     }
2410 
2411 #ifdef OUTPUT_EXTRADATA_LOG
2412     outputExtradataFile = fopen (output_extradata_filename, "ab");
2413 #endif
2414 
2415     // Copy the role information which provides the decoder kind
2416     strlcpy(drv_ctx.kind,role,128);
2417 
2418 
2419     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
2420                 OMX_MAX_STRINGNAME_SIZE)) {
2421         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
2422                 OMX_MAX_STRINGNAME_SIZE);
2423         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
2424         output_capability = V4L2_PIX_FMT_MPEG2;
2425         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
2426         /*Initialize Start Code for MPEG2*/
2427         codec_type_parse = CODEC_TYPE_MPEG2;
2428         m_frame_parser.init_start_codes(codec_type_parse);
2429     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
2430                 OMX_MAX_STRINGNAME_SIZE)) {
2431         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2432         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
2433         output_capability=V4L2_PIX_FMT_H264;
2434         eCompressionFormat = OMX_VIDEO_CodingAVC;
2435         codec_type_parse = CODEC_TYPE_H264;
2436         m_frame_parser.init_start_codes(codec_type_parse);
2437         m_frame_parser.init_nal_length(nal_length);
2438     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
2439                 OMX_MAX_STRINGNAME_SIZE)) {
2440         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
2441         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
2442         output_capability = V4L2_PIX_FMT_H264_MVC;
2443         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
2444         codec_type_parse = CODEC_TYPE_H264;
2445         m_frame_parser.init_start_codes(codec_type_parse);
2446         m_frame_parser.init_nal_length(nal_length);
2447     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
2448                 OMX_MAX_STRINGNAME_SIZE)) {
2449         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
2450         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
2451         output_capability = V4L2_PIX_FMT_HEVC;
2452         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
2453         codec_type_parse = CODEC_TYPE_HEVC;
2454         m_frame_parser.init_start_codes(codec_type_parse);
2455         m_frame_parser.init_nal_length(nal_length);
2456     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
2457                 OMX_MAX_STRINGNAME_SIZE)) {
2458         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
2459         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
2460         output_capability = V4L2_PIX_FMT_VP8;
2461         eCompressionFormat = OMX_VIDEO_CodingVP8;
2462         codec_type_parse = CODEC_TYPE_VP8;
2463     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
2464                 OMX_MAX_STRINGNAME_SIZE)) {
2465         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
2466         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
2467         output_capability = V4L2_PIX_FMT_VP9;
2468         eCompressionFormat = OMX_VIDEO_CodingVP9;
2469         codec_type_parse = CODEC_TYPE_VP9;
2470     } else {
2471         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
2472         eRet = OMX_ErrorInvalidComponentName;
2473     }
2474 
2475     m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
2476 
2477     if (eRet == OMX_ErrorNone) {
2478         OMX_COLOR_FORMATTYPE dest_color_format;
2479         if (m_disable_ubwc_mode) {
2480             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
2481         } else {
2482             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
2483         }
2484         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
2485             dest_color_format = (OMX_COLOR_FORMATTYPE)
2486                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
2487         else
2488             dest_color_format = (OMX_COLOR_FORMATTYPE)
2489                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2490         if (!client_buffers.set_color_format(dest_color_format)) {
2491             DEBUG_PRINT_ERROR("Setting color format failed");
2492             eRet = OMX_ErrorInsufficientResources;
2493         }
2494 
2495         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
2496         is_flexible_format = FALSE;
2497         is_mbaff = FALSE;
2498 
2499         if (m_disable_ubwc_mode) {
2500             capture_capability = V4L2_PIX_FMT_NV12;
2501         } else {
2502             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
2503         }
2504 
2505         struct v4l2_capability cap;
2506         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
2507         if (ret) {
2508             DEBUG_PRINT_ERROR("Failed to query capabilities");
2509             /*TODO: How to handle this case */
2510         } else {
2511             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
2512                 " version = %d, capabilities = %x", cap.driver, cap.card,
2513                 cap.bus_info, cap.version, cap.capabilities);
2514         }
2515         ret=0;
2516         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2517         fdesc.index=0;
2518         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2519             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2520                     fdesc.pixelformat, fdesc.flags);
2521             fdesc.index++;
2522         }
2523         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2524         fdesc.index=0;
2525         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2526 
2527             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2528                     fdesc.pixelformat, fdesc.flags);
2529             fdesc.index++;
2530         }
2531         m_extradata_info.output_crop_rect.nLeft = 0;
2532         m_extradata_info.output_crop_rect.nTop = 0;
2533         m_extradata_info.output_crop_rect.nWidth = 320;
2534         m_extradata_info.output_crop_rect.nHeight = 240;
2535         update_resolution(320, 240, 320, 240);
2536 
2537         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2538         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2539         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2540         fmt.fmt.pix_mp.pixelformat = output_capability;
2541         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2542         if (ret) {
2543             /*TODO: How to handle this case */
2544             DEBUG_PRINT_ERROR("Failed to set format on output port");
2545             return OMX_ErrorInsufficientResources;
2546         }
2547         DEBUG_PRINT_HIGH("Set Format was successful");
2548 
2549         /*
2550          * refer macro DEFAULT_CONCEAL_COLOR to set conceal color values
2551          */
2552         Platform::Config::getInt32(Platform::vidc_dec_conceal_color_8bit, &conceal_color_8bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2553         Platform::Config::getInt32(Platform::vidc_dec_conceal_color_10bit, &conceal_color_10bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2554         memset(&controls, 0, sizeof(controls));
2555         memset(ctrl, 0, sizeof(ctrl));
2556         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT;
2557         ctrl[0].value = conceal_color_8bit;
2558         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT;
2559         ctrl[1].value = conceal_color_10bit;
2560 
2561         controls.count = 2;
2562         controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
2563         controls.controls = ctrl;
2564         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
2565         if (ret) {
2566             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
2567         }
2568 
2569         //Get the hardware capabilities
2570         memset((void *)&frmsize,0,sizeof(frmsize));
2571         frmsize.index = 0;
2572         frmsize.pixel_format = output_capability;
2573         ret = ioctl(drv_ctx.video_driver_fd,
2574                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
2575         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
2576             DEBUG_PRINT_ERROR("Failed to get framesizes");
2577             return OMX_ErrorHardware;
2578         }
2579 
2580         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
2581             m_decoder_capability.min_width = frmsize.stepwise.min_width;
2582             m_decoder_capability.max_width = frmsize.stepwise.max_width;
2583             m_decoder_capability.min_height = frmsize.stepwise.min_height;
2584             m_decoder_capability.max_height = frmsize.stepwise.max_height;
2585         }
2586 
2587         /* Based on UBWC enable, decide split mode to driver before calling S_FMT */
2588         eRet = set_dpb(m_disable_ubwc_mode);
2589 
2590         memset(&fmt, 0x0, sizeof(struct v4l2_format));
2591         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2592         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2593         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2594         fmt.fmt.pix_mp.pixelformat = capture_capability;
2595         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2596         if (ret) {
2597             /*TODO: How to handle this case */
2598             DEBUG_PRINT_ERROR("Failed to set format on capture port");
2599         }
2600         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
2601         framesize.nWidth = drv_ctx.video_resolution.frame_width;
2602         framesize.nHeight = drv_ctx.video_resolution.frame_height;
2603 
2604         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
2605         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
2606         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
2607 
2608         DEBUG_PRINT_HIGH("Set Format was successful");
2609         if (secure_mode) {
2610             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
2611             control.value = 1;
2612             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
2613             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2614             if (ret) {
2615                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
2616                 return OMX_ErrorInsufficientResources;
2617             }
2618         }
2619 
2620         /*Get the Buffer requirements for input and output ports*/
2621         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
2622         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2623 
2624         if (secure_mode) {
2625             drv_ctx.op_buf.alignment = SECURE_ALIGN;
2626             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
2627         } else {
2628             drv_ctx.op_buf.alignment = SZ_4K;
2629             drv_ctx.ip_buf.alignment = SZ_4K;
2630         }
2631 
2632         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
2633         drv_ctx.extradata = 0;
2634         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
2635         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
2636         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
2637         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
2638         drv_ctx.idr_only_decoding = 0;
2639 
2640 #ifdef _ANDROID_
2641         if (m_dec_hfr_fps) {
2642             memset(&query, 0, sizeof(struct v4l2_queryctrl));
2643 
2644             query.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
2645             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &query);
2646             if (!ret)
2647                 m_dec_hfr_fps = MIN(query.maximum, m_dec_hfr_fps);
2648 
2649             DEBUG_PRINT_HIGH("Updated HFR fps value = %d", m_dec_hfr_fps);
2650         }
2651 
2652 #endif
2653         m_state = OMX_StateLoaded;
2654 
2655         unsigned long long extradata_mask = DEFAULT_EXTRADATA;
2656         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc) {
2657             extradata_mask |= OMX_HDR_COLOR_INFO_EXTRADATA | OMX_EXTNUSER_EXTRADATA;
2658         }
2659         enable_extradata(extradata_mask, true, true);
2660 
2661         eRet = get_buffer_req(&drv_ctx.ip_buf);
2662         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
2663         get_buffer_req(&drv_ctx.op_buf);
2664         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2665                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
2666                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2667                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
2668                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
2669                     h264_scratch.nFilledLen = 0;
2670                     h264_scratch.nOffset = 0;
2671 
2672                     if (h264_scratch.pBuffer == NULL) {
2673                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
2674                         return OMX_ErrorInsufficientResources;
2675                     }
2676         }
2677         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2678             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2679             if (m_frame_parser.mutils == NULL) {
2680                 m_frame_parser.mutils = new H264_Utils();
2681                 if (m_frame_parser.mutils == NULL) {
2682                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
2683                     eRet = OMX_ErrorInsufficientResources;
2684                 } else {
2685                     m_frame_parser.mutils->initialize_frame_checking_environment();
2686                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
2687                 }
2688             }
2689 
2690             h264_parser = new h264_stream_parser();
2691             if (!h264_parser) {
2692                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
2693                 eRet = OMX_ErrorInsufficientResources;
2694             }
2695         }
2696         msg_thread_created = true;
2697         r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
2698 
2699         if (r < 0) {
2700             DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
2701             msg_thread_created = false;
2702             eRet = OMX_ErrorInsufficientResources;
2703         } else if (secure_mode) {
2704             this->post_event(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL);
2705             this->post_event(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL);
2706         }
2707     }
2708 
2709     {
2710         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
2711         init_vendor_extensions(*extStore);
2712         mVendorExtensionStore.dumpExtensions((const char *)role);
2713     }
2714 
2715     if (eRet != OMX_ErrorNone) {
2716         DEBUG_PRINT_ERROR("Component Init Failed");
2717     } else {
2718         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
2719                 drv_ctx.video_driver_fd);
2720     }
2721     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
2722 
2723     OMX_INIT_STRUCT(&m_sParamLowLatency, QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE);
2724     m_sParamLowLatency.nNumFrames = 0;
2725     m_sParamLowLatency.bEnableLowLatencyMode = OMX_FALSE;
2726 
2727     return eRet;
2728 }
2729 
2730 /* ======================================================================
2731    FUNCTION
2732    omx_vdec::GetComponentVersion
2733 
2734    DESCRIPTION
2735    Returns the component version.
2736 
2737    PARAMETERS
2738    TBD.
2739 
2740    RETURN VALUE
2741    OMX_ErrorNone.
2742 
2743    ========================================================================== */
2744 OMX_ERRORTYPE  omx_vdec::get_component_version
2745 (
2746  OMX_IN OMX_HANDLETYPE hComp,
2747  OMX_OUT OMX_STRING componentName,
2748  OMX_OUT OMX_VERSIONTYPE* componentVersion,
2749  OMX_OUT OMX_VERSIONTYPE* specVersion,
2750  OMX_OUT OMX_UUIDTYPE* componentUUID
2751  )
2752 {
2753     (void) hComp;
2754     (void) componentName;
2755     (void) componentVersion;
2756     (void) componentUUID;
2757     if (m_state == OMX_StateInvalid) {
2758         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
2759         return OMX_ErrorInvalidState;
2760     }
2761     /* TBD -- Return the proper version */
2762     if (specVersion) {
2763         specVersion->nVersion = OMX_SPEC_VERSION;
2764     }
2765     return OMX_ErrorNone;
2766 }
2767 /* ======================================================================
2768    FUNCTION
2769    omx_vdec::SendCommand
2770 
2771    DESCRIPTION
2772    Returns zero if all the buffers released..
2773 
2774    PARAMETERS
2775    None.
2776 
2777    RETURN VALUE
2778    true/false
2779 
2780    ========================================================================== */
2781 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
2782         OMX_IN OMX_COMMANDTYPE cmd,
2783         OMX_IN OMX_U32 param1,
2784         OMX_IN OMX_PTR cmdData
2785         )
2786 {
2787     (void) hComp;
2788     (void) cmdData;
2789     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
2790     if (m_state == OMX_StateInvalid) {
2791         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
2792         return OMX_ErrorInvalidState;
2793     }
2794     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
2795             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
2796         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
2797                 "to invalid port: %u", (unsigned int)param1);
2798         return OMX_ErrorBadPortIndex;
2799     }
2800 
2801     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2802     sem_wait(&m_cmd_lock);
2803     DEBUG_PRINT_LOW("send_command: Command Processed");
2804     return OMX_ErrorNone;
2805 }
2806 
2807 /* ======================================================================
2808    FUNCTION
2809    omx_vdec::SendCommand
2810 
2811    DESCRIPTION
2812    Returns zero if all the buffers released..
2813 
2814    PARAMETERS
2815    None.
2816 
2817    RETURN VALUE
2818    true/false
2819 
2820    ========================================================================== */
2821 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
2822         OMX_IN OMX_COMMANDTYPE cmd,
2823         OMX_IN OMX_U32 param1,
2824         OMX_IN OMX_PTR cmdData
2825         )
2826 {
2827     (void) hComp;
2828     (void) cmdData;
2829     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2830     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2831     int bFlag = 1,sem_posted = 0,ret=0;
2832 
2833     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2834     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
2835             m_state, eState);
2836 
2837     if (cmd == OMX_CommandStateSet) {
2838         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2839         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
2840         /***************************/
2841         /* Current State is Loaded */
2842         /***************************/
2843         if (m_state == OMX_StateLoaded) {
2844             if (eState == OMX_StateIdle) {
2845                 //if all buffers are allocated or all ports disabled
2846                 if (allocate_done() ||
2847                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
2848                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
2849                 } else {
2850                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
2851                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2852                     // Skip the event notification
2853                     bFlag = 0;
2854                 }
2855             }
2856             /* Requesting transition from Loaded to Loaded */
2857             else if (eState == OMX_StateLoaded) {
2858                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
2859                 post_event(OMX_EventError,OMX_ErrorSameState,\
2860                         OMX_COMPONENT_GENERATE_EVENT);
2861                 eRet = OMX_ErrorSameState;
2862             }
2863             /* Requesting transition from Loaded to WaitForResources */
2864             else if (eState == OMX_StateWaitForResources) {
2865                 /* Since error is None , we will post an event
2866                    at the end of this function definition */
2867                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
2868             }
2869             /* Requesting transition from Loaded to Executing */
2870             else if (eState == OMX_StateExecuting) {
2871                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
2872                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2873                         OMX_COMPONENT_GENERATE_EVENT);
2874                 eRet = OMX_ErrorIncorrectStateTransition;
2875             }
2876             /* Requesting transition from Loaded to Pause */
2877             else if (eState == OMX_StatePause) {
2878                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
2879                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2880                         OMX_COMPONENT_GENERATE_EVENT);
2881                 eRet = OMX_ErrorIncorrectStateTransition;
2882             }
2883             /* Requesting transition from Loaded to Invalid */
2884             else if (eState == OMX_StateInvalid) {
2885                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
2886                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2887                 eRet = OMX_ErrorInvalidState;
2888             } else {
2889                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
2890                         eState);
2891                 eRet = OMX_ErrorBadParameter;
2892             }
2893         }
2894 
2895         /***************************/
2896         /* Current State is IDLE */
2897         /***************************/
2898         else if (m_state == OMX_StateIdle) {
2899             if (eState == OMX_StateLoaded) {
2900                 if (release_done()) {
2901                     /*
2902                      * Since error is None , we will post an event at the end
2903                      * of this function definition
2904                      * Reset buffer requirements here to ensure setting buffer requirement
2905                      * when component move to executing state from loaded state via Idle.
2906                      */
2907                     drv_ctx.op_buf.buffer_size = 0;
2908                     drv_ctx.op_buf.actualcount = 0;
2909                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
2910                 } else {
2911                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
2912                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2913                     // Skip the event notification
2914                     bFlag = 0;
2915                 }
2916             }
2917             /* Requesting transition from Idle to Executing */
2918             else if (eState == OMX_StateExecuting) {
2919                 bFlag = 1;
2920                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2921                 m_state=OMX_StateExecuting;
2922             }
2923             /* Requesting transition from Idle to Idle */
2924             else if (eState == OMX_StateIdle) {
2925                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
2926                 post_event(OMX_EventError,OMX_ErrorSameState,\
2927                         OMX_COMPONENT_GENERATE_EVENT);
2928                 eRet = OMX_ErrorSameState;
2929             }
2930             /* Requesting transition from Idle to WaitForResources */
2931             else if (eState == OMX_StateWaitForResources) {
2932                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
2933                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2934                         OMX_COMPONENT_GENERATE_EVENT);
2935                 eRet = OMX_ErrorIncorrectStateTransition;
2936             }
2937             /* Requesting transition from Idle to Pause */
2938             else if (eState == OMX_StatePause) {
2939                 /*To pause the Video core we need to start the driver*/
2940                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2941                       NULL) < */0) {
2942                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
2943                     omx_report_error ();
2944                     eRet = OMX_ErrorHardware;
2945                 } else {
2946                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2947                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
2948                     bFlag = 0;
2949                 }
2950             }
2951             /* Requesting transition from Idle to Invalid */
2952             else if (eState == OMX_StateInvalid) {
2953                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
2954                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2955                 eRet = OMX_ErrorInvalidState;
2956             } else {
2957                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
2958                 eRet = OMX_ErrorBadParameter;
2959             }
2960         }
2961 
2962         /******************************/
2963         /* Current State is Executing */
2964         /******************************/
2965         else if (m_state == OMX_StateExecuting) {
2966             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
2967             /* Requesting transition from Executing to Idle */
2968             if (eState == OMX_StateIdle) {
2969                 /* Since error is None , we will post an event
2970                    at the end of this function definition
2971                  */
2972                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
2973                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2974                 if (!sem_posted) {
2975                     sem_posted = 1;
2976                     sem_post (&m_cmd_lock);
2977                     execute_omx_flush(OMX_ALL);
2978                 }
2979                 bFlag = 0;
2980             }
2981             /* Requesting transition from Executing to Paused */
2982             else if (eState == OMX_StatePause) {
2983                 DEBUG_PRINT_LOW("PAUSE Command Issued");
2984                 m_state = OMX_StatePause;
2985                 bFlag = 1;
2986             }
2987             /* Requesting transition from Executing to Loaded */
2988             else if (eState == OMX_StateLoaded) {
2989                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
2990                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2991                         OMX_COMPONENT_GENERATE_EVENT);
2992                 eRet = OMX_ErrorIncorrectStateTransition;
2993             }
2994             /* Requesting transition from Executing to WaitForResources */
2995             else if (eState == OMX_StateWaitForResources) {
2996                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
2997                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2998                         OMX_COMPONENT_GENERATE_EVENT);
2999                 eRet = OMX_ErrorIncorrectStateTransition;
3000             }
3001             /* Requesting transition from Executing to Executing */
3002             else if (eState == OMX_StateExecuting) {
3003                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
3004                 post_event(OMX_EventError,OMX_ErrorSameState,\
3005                         OMX_COMPONENT_GENERATE_EVENT);
3006                 eRet = OMX_ErrorSameState;
3007             }
3008             /* Requesting transition from Executing to Invalid */
3009             else if (eState == OMX_StateInvalid) {
3010                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
3011                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3012                 eRet = OMX_ErrorInvalidState;
3013             } else {
3014                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
3015                 eRet = OMX_ErrorBadParameter;
3016             }
3017         }
3018         /***************************/
3019         /* Current State is Pause  */
3020         /***************************/
3021         else if (m_state == OMX_StatePause) {
3022             /* Requesting transition from Pause to Executing */
3023             if (eState == OMX_StateExecuting) {
3024                 DEBUG_PRINT_LOW("Pause --> Executing");
3025                 m_state = OMX_StateExecuting;
3026                 bFlag = 1;
3027             }
3028             /* Requesting transition from Pause to Idle */
3029             else if (eState == OMX_StateIdle) {
3030                 /* Since error is None , we will post an event
3031                    at the end of this function definition */
3032                 DEBUG_PRINT_LOW("Pause --> Idle");
3033                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
3034                 if (!sem_posted) {
3035                     sem_posted = 1;
3036                     sem_post (&m_cmd_lock);
3037                     execute_omx_flush(OMX_ALL);
3038                 }
3039                 bFlag = 0;
3040             }
3041             /* Requesting transition from Pause to loaded */
3042             else if (eState == OMX_StateLoaded) {
3043                 DEBUG_PRINT_ERROR("Pause --> loaded");
3044                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3045                         OMX_COMPONENT_GENERATE_EVENT);
3046                 eRet = OMX_ErrorIncorrectStateTransition;
3047             }
3048             /* Requesting transition from Pause to WaitForResources */
3049             else if (eState == OMX_StateWaitForResources) {
3050                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
3051                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3052                         OMX_COMPONENT_GENERATE_EVENT);
3053                 eRet = OMX_ErrorIncorrectStateTransition;
3054             }
3055             /* Requesting transition from Pause to Pause */
3056             else if (eState == OMX_StatePause) {
3057                 DEBUG_PRINT_ERROR("Pause --> Pause");
3058                 post_event(OMX_EventError,OMX_ErrorSameState,\
3059                         OMX_COMPONENT_GENERATE_EVENT);
3060                 eRet = OMX_ErrorSameState;
3061             }
3062             /* Requesting transition from Pause to Invalid */
3063             else if (eState == OMX_StateInvalid) {
3064                 DEBUG_PRINT_ERROR("Pause --> Invalid");
3065                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3066                 eRet = OMX_ErrorInvalidState;
3067             } else {
3068                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
3069                 eRet = OMX_ErrorBadParameter;
3070             }
3071         }
3072         /***************************/
3073         /* Current State is WaitForResources  */
3074         /***************************/
3075         else if (m_state == OMX_StateWaitForResources) {
3076             /* Requesting transition from WaitForResources to Loaded */
3077             if (eState == OMX_StateLoaded) {
3078                 /* Since error is None , we will post an event
3079                    at the end of this function definition */
3080                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
3081             }
3082             /* Requesting transition from WaitForResources to WaitForResources */
3083             else if (eState == OMX_StateWaitForResources) {
3084                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
3085                 post_event(OMX_EventError,OMX_ErrorSameState,
3086                         OMX_COMPONENT_GENERATE_EVENT);
3087                 eRet = OMX_ErrorSameState;
3088             }
3089             /* Requesting transition from WaitForResources to Executing */
3090             else if (eState == OMX_StateExecuting) {
3091                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
3092                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3093                         OMX_COMPONENT_GENERATE_EVENT);
3094                 eRet = OMX_ErrorIncorrectStateTransition;
3095             }
3096             /* Requesting transition from WaitForResources to Pause */
3097             else if (eState == OMX_StatePause) {
3098                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
3099                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3100                         OMX_COMPONENT_GENERATE_EVENT);
3101                 eRet = OMX_ErrorIncorrectStateTransition;
3102             }
3103             /* Requesting transition from WaitForResources to Invalid */
3104             else if (eState == OMX_StateInvalid) {
3105                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
3106                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3107                 eRet = OMX_ErrorInvalidState;
3108             }
3109             /* Requesting transition from WaitForResources to Loaded -
3110                is NOT tested by Khronos TS */
3111 
3112         } else {
3113             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
3114             eRet = OMX_ErrorBadParameter;
3115         }
3116     }
3117     /********************************/
3118     /* Current State is Invalid */
3119     /*******************************/
3120     else if (m_state == OMX_StateInvalid) {
3121         /* State Transition from Inavlid to any state */
3122         if ((eState ==  OMX_StateLoaded) ||
3123             (eState == OMX_StateWaitForResources) ||
3124             (eState == OMX_StateIdle) ||
3125             (eState == OMX_StateExecuting) ||
3126             (eState == OMX_StatePause) ||
3127             (eState == OMX_StateInvalid)
3128         ) {
3129             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
3130             post_event(OMX_EventError,OMX_ErrorInvalidState,\
3131                     OMX_COMPONENT_GENERATE_EVENT);
3132             eRet = OMX_ErrorInvalidState;
3133         }
3134     } else if (cmd == OMX_CommandFlush) {
3135         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
3136                 "with param1: %u", (unsigned int)param1);
3137         send_codec_config();
3138         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
3139                     param1 == OMX_ALL)) {
3140             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
3141                struct timespec ts;
3142 
3143                clock_gettime(CLOCK_REALTIME, &ts);
3144                ts.tv_sec += 2;
3145                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
3146                        m_queued_codec_config_count);
3147                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
3148                if (sem_timedwait(&m_safe_flush, &ts)) {
3149                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
3150                }
3151                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
3152             }
3153         }
3154 
3155         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3156             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
3157         }
3158         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3159             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3160         }
3161         if (!sem_posted) {
3162             sem_posted = 1;
3163             DEBUG_PRINT_LOW("Set the Semaphore");
3164             sem_post (&m_cmd_lock);
3165             execute_omx_flush(param1);
3166         }
3167         bFlag = 0;
3168     } else if ( cmd == OMX_CommandPortEnable) {
3169         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
3170                 "with param1: %u", (unsigned int)param1);
3171         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3172             m_inp_bEnabled = OMX_TRUE;
3173 
3174             if ( (m_state == OMX_StateLoaded &&
3175                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3176                     || allocate_input_done()) {
3177                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
3178                         OMX_COMPONENT_GENERATE_EVENT);
3179             } else {
3180                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3181                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
3182                 // Skip the event notification
3183                 bFlag = 0;
3184             }
3185         }
3186         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3187             DEBUG_PRINT_LOW("Enable output Port command recieved");
3188             m_out_bEnabled = OMX_TRUE;
3189 
3190             if ( (m_state == OMX_StateLoaded &&
3191                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3192                     || (allocate_output_done())) {
3193                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
3194                         OMX_COMPONENT_GENERATE_EVENT);
3195 
3196             } else {
3197                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3198                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3199                 // Skip the event notification
3200                 bFlag = 0;
3201                 /* enable/disable downscaling if required */
3202                 ret = decide_downscalar();
3203                 if (ret) {
3204                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
3205                 }
3206             }
3207         }
3208     } else if (cmd == OMX_CommandPortDisable) {
3209         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
3210                 "with param1: %u", (unsigned int)param1);
3211         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3212             codec_config_flag = false;
3213             m_inp_bEnabled = OMX_FALSE;
3214             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3215                     && release_input_done()) {
3216                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
3217                         OMX_COMPONENT_GENERATE_EVENT);
3218             } else {
3219                 DEBUG_PRINT_HIGH("Set input port disable pending");
3220                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
3221                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3222                     if (!sem_posted) {
3223                         sem_posted = 1;
3224                         sem_post (&m_cmd_lock);
3225                     }
3226                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
3227                 }
3228 
3229                 // Skip the event notification
3230                 bFlag = 0;
3231             }
3232         }
3233         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3234             m_out_bEnabled = OMX_FALSE;
3235             DEBUG_PRINT_LOW("Disable output Port command recieved");
3236             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3237                     && release_output_done()) {
3238                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
3239                         OMX_COMPONENT_GENERATE_EVENT);
3240             } else {
3241                 DEBUG_PRINT_HIGH("Set output port disable pending");
3242                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3243                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3244                     if (!sem_posted) {
3245                         sem_posted = 1;
3246                         sem_post (&m_cmd_lock);
3247                     }
3248                     DEBUG_PRINT_HIGH("Set output port flush in disable pending");
3249                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
3250                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
3251                 }
3252                 // Skip the event notification
3253                 bFlag = 0;
3254 
3255             }
3256         }
3257     } else {
3258         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
3259         eRet = OMX_ErrorNotImplemented;
3260     }
3261     if (eRet == OMX_ErrorNone && bFlag) {
3262         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
3263     }
3264     if (!sem_posted) {
3265         sem_post(&m_cmd_lock);
3266     }
3267 
3268     return eRet;
3269 }
3270 
3271 /* ======================================================================
3272    FUNCTION
3273    omx_vdec::ExecuteOmxFlush
3274 
3275    DESCRIPTION
3276    Executes the OMX flush.
3277 
3278    PARAMETERS
3279    flushtype - input flush(1)/output flush(0)/ both.
3280 
3281    RETURN VALUE
3282    true/false
3283 
3284    ========================================================================== */
3285 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
3286 {
3287     bool bRet = false;
3288     struct v4l2_plane plane;
3289     struct v4l2_buffer v4l2_buf;
3290     struct v4l2_decoder_cmd dec;
3291     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
3292     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
3293     dec.cmd = V4L2_QCOM_CMD_FLUSH;
3294 
3295     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
3296 
3297     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
3298         output_flush_progress = true;
3299         dec.flags = V4L2_QCOM_CMD_FLUSH_CAPTURE;
3300     } else {
3301         /* XXX: The driver/hardware does not support flushing of individual ports
3302          * in all states. So we pretty much need to flush both ports internally,
3303          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
3304          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
3305          * we automatically omit sending the FLUSH done for the "opposite" port. */
3306         input_flush_progress = true;
3307         output_flush_progress = true;
3308         dec.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3309     }
3310 
3311     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
3312         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
3313         bRet = false;
3314     }
3315 
3316     return bRet;
3317 }
3318 /*=========================================================================
3319 FUNCTION : execute_output_flush
3320 
3321 DESCRIPTION
3322 Executes the OMX flush at OUTPUT PORT.
3323 
3324 PARAMETERS
3325 None.
3326 
3327 RETURN VALUE
3328 true/false
3329 ==========================================================================*/
3330 bool omx_vdec::execute_output_flush()
3331 {
3332     unsigned long p1 = 0; // Parameter - 1
3333     unsigned long p2 = 0; // Parameter - 2
3334     unsigned long ident = 0;
3335     bool bRet = true;
3336 
3337     /*Generate FBD for all Buffers in the FTBq*/
3338     pthread_mutex_lock(&m_lock);
3339     DEBUG_PRINT_LOW("Initiate Output Flush");
3340 
3341     //reset last render TS
3342     if(m_last_rendered_TS > 0) {
3343         m_last_rendered_TS = 0;
3344     }
3345 
3346     while (m_ftb_q.m_size) {
3347         m_ftb_q.pop_entry(&p1,&p2,&ident);
3348         if (ident == m_fill_output_msg ) {
3349             print_omx_buffer("Flush FBD", (OMX_BUFFERHEADERTYPE *)p2);
3350             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
3351         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
3352             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
3353         }
3354     }
3355     pthread_mutex_unlock(&m_lock);
3356     output_flush_progress = false;
3357 
3358     if (arbitrary_bytes) {
3359         prev_ts = LLONG_MAX;
3360         rst_prev_ts = true;
3361     }
3362     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
3363     return bRet;
3364 }
3365 /*=========================================================================
3366 FUNCTION : execute_input_flush
3367 
3368 DESCRIPTION
3369 Executes the OMX flush at INPUT PORT.
3370 
3371 PARAMETERS
3372 None.
3373 
3374 RETURN VALUE
3375 true/false
3376 ==========================================================================*/
3377 bool omx_vdec::execute_input_flush()
3378 {
3379     unsigned       i =0;
3380     unsigned long p1 = 0; // Parameter - 1
3381     unsigned long p2 = 0; // Parameter - 2
3382     unsigned long ident = 0;
3383     bool bRet = true;
3384 
3385     /*Generate EBD for all Buffers in the ETBq*/
3386     DEBUG_PRINT_LOW("Initiate Input Flush");
3387 
3388     pthread_mutex_lock(&m_lock);
3389     DEBUG_PRINT_LOW("Check if the Queue is empty");
3390     while (m_etb_q.m_size) {
3391         m_etb_q.pop_entry(&p1,&p2,&ident);
3392 
3393         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
3394             print_omx_buffer("Flush ETB_ARBITRARY", (OMX_BUFFERHEADERTYPE *)p2);
3395             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
3396         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
3397             pending_input_buffers++;
3398             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
3399             print_omx_buffer("Flush ETB", (OMX_BUFFERHEADERTYPE *)p2);
3400             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
3401         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
3402             print_omx_buffer("Flush EBD", (OMX_BUFFERHEADERTYPE *)p1);
3403             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
3404         }
3405     }
3406     time_stamp_dts.flush_timestamp();
3407     /*Check if Heap Buffers are to be flushed*/
3408     if (arbitrary_bytes && !(codec_config_flag)) {
3409         DEBUG_PRINT_LOW("Reset all the variables before flusing");
3410         h264_scratch.nFilledLen = 0;
3411         nal_count = 0;
3412         look_ahead_nal = false;
3413         frame_count = 0;
3414         h264_last_au_ts = LLONG_MAX;
3415         h264_last_au_flags = 0;
3416         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
3417         m_demux_entries = 0;
3418         DEBUG_PRINT_LOW("Initialize parser");
3419         if (m_frame_parser.mutils) {
3420             m_frame_parser.mutils->initialize_frame_checking_environment();
3421         }
3422 
3423         while (m_input_pending_q.m_size) {
3424             m_input_pending_q.pop_entry(&p1,&p2,&ident);
3425             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
3426         }
3427 
3428         if (psource_frame) {
3429             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
3430             psource_frame = NULL;
3431         }
3432 
3433         if (pdest_frame) {
3434             pdest_frame->nFilledLen = 0;
3435             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
3436                     (unsigned int)NULL);
3437             pdest_frame = NULL;
3438         }
3439         m_frame_parser.flush();
3440     } else if (codec_config_flag) {
3441         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
3442                 "is not sent to the driver yet");
3443     }
3444     pthread_mutex_unlock(&m_lock);
3445     input_flush_progress = false;
3446     if (!arbitrary_bytes) {
3447         prev_ts = LLONG_MAX;
3448         rst_prev_ts = true;
3449     }
3450 
3451     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
3452     return bRet;
3453 }
3454 
3455 /*=========================================================================
3456 FUNCTION : notify_flush_done
3457 
3458 DESCRIPTION
3459 Notifies flush done to the OMX Client.
3460 
3461 PARAMETERS
3462 ctxt -- Context information related to the self..
3463 
3464 RETURN VALUE
3465 NONE
3466 ==========================================================================*/
3467 void omx_vdec::notify_flush_done(void *ctxt) {
3468 
3469     omx_vdec *pThis = (omx_vdec *) ctxt;
3470 
3471     if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
3472         if (BITMASK_PRESENT(&pThis->m_flags,
3473                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
3474             DEBUG_PRINT_LOW("Notify Output Flush done");
3475             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3476             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3477                 OMX_EventCmdComplete,OMX_CommandFlush,
3478                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
3479         }
3480 
3481         if (BITMASK_PRESENT(&pThis->m_flags,
3482                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
3483             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
3484             DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
3485             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3486                     OMX_EventCmdComplete,OMX_CommandFlush,
3487                     OMX_CORE_INPUT_PORT_INDEX,NULL );
3488             //clear hdr10plusinfo list upon input flush done
3489             clear_hdr10plusinfo();
3490         }
3491     }
3492 }
3493 
3494 /* ======================================================================
3495    FUNCTION
3496    omx_vdec::SendCommandEvent
3497 
3498    DESCRIPTION
3499    Send the event to decoder pipe.  This is needed to generate the callbacks
3500    in decoder thread context.
3501 
3502    PARAMETERS
3503    None.
3504 
3505    RETURN VALUE
3506    true/false
3507 
3508    ========================================================================== */
3509 bool omx_vdec::post_event(unsigned long p1,
3510         unsigned long p2,
3511         unsigned long id)
3512 {
3513     bool bRet = false;
3514 
3515     /* Just drop messages typically generated by hardware (w/o client request),
3516      * if we've reported an error to client. */
3517     if (m_error_propogated) {
3518         switch (id) {
3519             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
3520             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
3521                 DEBUG_PRINT_ERROR("Dropping message %lx "
3522                         "since client expected to be in error state", id);
3523                 return false;
3524             default:
3525                 /* whatever */
3526                 break;
3527         }
3528     }
3529 
3530     pthread_mutex_lock(&m_lock);
3531 
3532     if (id == m_fill_output_msg ||
3533             id == OMX_COMPONENT_GENERATE_FBD ||
3534             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
3535             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
3536         m_ftb_q.insert_entry(p1,p2,id);
3537     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
3538             id == OMX_COMPONENT_GENERATE_EBD ||
3539             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
3540             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
3541         m_etb_q.insert_entry(p1,p2,id);
3542     } else {
3543         DEBUG_PRINT_HIGH("post_event(%ld, %ld, %ld)", p1, p2, id);
3544         m_cmd_q.insert_entry(p1,p2,id);
3545     }
3546 
3547     bRet = true;
3548     post_message(this, id);
3549 
3550     pthread_mutex_unlock(&m_lock);
3551 
3552     return bRet;
3553 }
3554 
3555 bool inline omx_vdec::vdec_query_cap(struct v4l2_queryctrl &cap) {
3556 
3557     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &cap)) {
3558         DEBUG_PRINT_ERROR("Query caps for id = %u failed\n", cap.id);
3559         return false;
3560     }
3561     return true;
3562 }
3563 
3564 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
3565 {
3566     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3567     struct v4l2_queryctrl profile_cap, level_cap;
3568     int v4l2_profile;
3569     int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
3570                             QOMX_VIDEO_AVCProfileBaseline,
3571                             QOMX_VIDEO_AVCProfileMain,
3572                             QOMX_VIDEO_AVCProfileConstrainedHigh,
3573                             QOMX_VIDEO_AVCProfileHigh };
3574     int hevc_profiles[3] = { OMX_VIDEO_HEVCProfileMain,
3575                              OMX_VIDEO_HEVCProfileMain10,
3576                              OMX_VIDEO_HEVCProfileMain10HDR10 };
3577     int mpeg2_profiles[2] = { OMX_VIDEO_MPEG2ProfileSimple,
3578                               OMX_VIDEO_MPEG2ProfileMain};
3579     int vp9_profiles[4] = { OMX_VIDEO_VP9Profile0,
3580                             OMX_VIDEO_VP9Profile2,
3581                             OMX_VIDEO_VP9Profile2HDR,
3582                             OMX_VIDEO_VP9Profile2HDR10Plus};
3583 
3584     if (!profileLevelType)
3585         return OMX_ErrorBadParameter;
3586 
3587     memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
3588     memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
3589 
3590     if (output_capability == V4L2_PIX_FMT_H264) {
3591         level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3592         profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3593     } else if (output_capability == V4L2_PIX_FMT_VP8) {
3594         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3595     } else if (output_capability == V4L2_PIX_FMT_VP9) {
3596         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL;
3597         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE;
3598     } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3599         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
3600         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
3601     } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3602         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL;
3603         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE;
3604     } else {
3605         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
3606         return OMX_ErrorInvalidComponent;
3607     }
3608 
3609     if (profile_cap.id) {
3610         if(!vdec_query_cap(profile_cap)) {
3611             DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
3612             return OMX_ErrorHardware;
3613         }
3614     }
3615 
3616     if (level_cap.id) {
3617         if(!vdec_query_cap(level_cap)) {
3618             DEBUG_PRINT_ERROR("Getting capabilities for level failed");
3619             return OMX_ErrorHardware;
3620         }
3621     }
3622 
3623     /* Get the corresponding omx level from v4l2 level */
3624     if (!profile_level_converter::convert_v4l2_level_to_omx(output_capability, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
3625         DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
3626         return OMX_ErrorHardware;
3627     }
3628 
3629     /* For given profile index get corresponding profile that needs to be supported */
3630     if (profileLevelType->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
3631         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
3632         return OMX_ErrorBadPortIndex;
3633     }
3634 
3635     if (output_capability == V4L2_PIX_FMT_H264) {
3636         if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
3637             profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
3638         } else {
3639             DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3640                                           (unsigned int)profileLevelType->nProfileIndex);
3641             return OMX_ErrorNoMore;
3642         }
3643     } else if (output_capability == V4L2_PIX_FMT_VP8) {
3644         if (profileLevelType->nProfileIndex == 0) {
3645             profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
3646         } else {
3647             DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3648                                           (unsigned int)profileLevelType->nProfileIndex);
3649             return OMX_ErrorNoMore;
3650         }
3651         /* Driver has no notion of VP8 profile. Only one profile is supported.  Return this */
3652         return OMX_ErrorNone;
3653     } else if (output_capability == V4L2_PIX_FMT_VP9) {
3654         if (profileLevelType->nProfileIndex < (sizeof(vp9_profiles)/sizeof(int))) {
3655             profileLevelType->eProfile = vp9_profiles[profileLevelType->nProfileIndex];
3656         } else {
3657             DEBUG_PRINT_LOW("VP9: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3658                                           (unsigned int)profileLevelType->nProfileIndex);
3659             return OMX_ErrorNoMore;
3660         }
3661     } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3662         if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
3663             profileLevelType->eProfile =  hevc_profiles[profileLevelType->nProfileIndex];
3664         } else {
3665             DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3666                                          (unsigned int)profileLevelType->nProfileIndex);
3667             return OMX_ErrorNoMore;
3668         }
3669     } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3670         if (profileLevelType->nProfileIndex < (sizeof(mpeg2_profiles)/sizeof(int))) {
3671             profileLevelType->eProfile = mpeg2_profiles[profileLevelType->nProfileIndex];
3672         } else {
3673             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3674                                          (unsigned int)profileLevelType->nProfileIndex);
3675             return OMX_ErrorNoMore;
3676         }
3677     }
3678 
3679     /* Check if the profile is supported by driver or not  */
3680     /* During query caps of profile driver sends a mask of */
3681     /* of all v4l2 profiles supported(in the flags field)  */
3682     if((output_capability != V4L2_PIX_FMT_HEVC) &&
3683          (output_capability != V4L2_PIX_FMT_VP9)) {
3684         if (!profile_level_converter::convert_omx_profile_to_v4l2(output_capability, profileLevelType->eProfile, &v4l2_profile)) {
3685             DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3686             return OMX_ErrorHardware;
3687         }
3688     }else if(output_capability == V4L2_PIX_FMT_HEVC) { //convert omx profile to v4l2 profile for HEVC Main10 and Main10HDR10 profiles,seperately
3689         switch (profileLevelType->eProfile) {
3690             case OMX_VIDEO_HEVCProfileMain:
3691                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
3692                 break;
3693             case OMX_VIDEO_HEVCProfileMain10:
3694             case OMX_VIDEO_HEVCProfileMain10HDR10:
3695                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
3696                 break;
3697             default:
3698                 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3699                 return OMX_ErrorHardware;
3700         }
3701     }else { //convert omx profile to v4l2 profile for VP9 Profile2 and VP9 Profile2HDR profiles,seperately
3702         switch (profileLevelType->eProfile) {
3703             case OMX_VIDEO_VP9Profile0:
3704                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0;
3705                 break;
3706             case OMX_VIDEO_VP9Profile2:
3707             case OMX_VIDEO_VP9Profile2HDR:
3708                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10;
3709                 break;
3710             default:
3711                 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3712                 return OMX_ErrorHardware;
3713         }
3714     }
3715     if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
3716         DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
3717         eRet = OMX_ErrorNoMore;
3718     }
3719 
3720     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
3721             (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
3722     return eRet;
3723 }
3724 
3725 /* ======================================================================
3726    FUNCTION
3727    omx_vdec::GetParameter
3728 
3729    DESCRIPTION
3730    OMX Get Parameter method implementation
3731 
3732    PARAMETERS
3733    <TBD>.
3734 
3735    RETURN VALUE
3736    Error None if successful.
3737 
3738    ========================================================================== */
3739 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
3740         OMX_IN OMX_INDEXTYPE paramIndex,
3741         OMX_INOUT OMX_PTR     paramData)
3742 {
3743     (void) hComp;
3744     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3745 
3746     DEBUG_PRINT_LOW("get_parameter:");
3747     if (m_state == OMX_StateInvalid) {
3748         DEBUG_PRINT_ERROR("Get Param in Invalid State");
3749         return OMX_ErrorInvalidState;
3750     }
3751     if (paramData == NULL) {
3752         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
3753         return OMX_ErrorBadParameter;
3754     }
3755     switch ((unsigned long)paramIndex) {
3756         case OMX_IndexParamPortDefinition: {
3757                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
3758                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
3759                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3760                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
3761 
3762                                OMX_COLOR_FORMATTYPE drv_color_format;
3763                                bool status = false;
3764 
3765                                if (!client_buffers.is_color_conversion_enabled()) {
3766                                    status = client_buffers.get_color_format(drv_color_format);
3767                                }
3768 
3769                                if (decide_dpb_buffer_mode()) {
3770                                    DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
3771                                    return OMX_ErrorBadParameter;
3772                                }
3773 
3774                               if (status) {
3775                                  if (!client_buffers.is_color_conversion_enabled()) {
3776                                          client_buffers.set_client_buffers_disabled(true);
3777                                          client_buffers.set_color_format(drv_color_format);
3778                                  }
3779                               }
3780 
3781                                eRet = update_portdef(portDefn);
3782                                if (eRet == OMX_ErrorNone)
3783                                    m_port_def = *portDefn;
3784                                break;
3785                            }
3786         case OMX_IndexParamVideoInit: {
3787                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3788                               OMX_PORT_PARAM_TYPE *portParamType =
3789                                   (OMX_PORT_PARAM_TYPE *) paramData;
3790                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
3791 
3792                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3793                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3794                               portParamType->nPorts           = 2;
3795                               portParamType->nStartPortNumber = 0;
3796                               break;
3797                           }
3798         case OMX_IndexParamVideoPortFormat: {
3799                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3800                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3801                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3802                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
3803 
3804                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
3805                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
3806 
3807                                 if (0 == portFmt->nPortIndex) {
3808                                     if (0 == portFmt->nIndex) {
3809                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
3810                                         portFmt->eCompressionFormat = eCompressionFormat;
3811                                     } else {
3812                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
3813                                                 " NoMore compression formats");
3814                                         eRet =  OMX_ErrorNoMore;
3815                                     }
3816                                 } else if (1 == portFmt->nPortIndex) {
3817                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
3818 
3819                                     // Distinguish non-surface mode from normal playback use-case based on
3820                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
3821                                     // For non-android, use the default list
3822                                     // Also use default format-list if FLEXIBLE YUV is supported,
3823                                     // as the client negotiates the standard color-format if it needs to
3824                                     bool useNonSurfaceMode = false;
3825 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) && !defined(USE_GBM)
3826                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
3827 #endif
3828                                     portFmt->eColorFormat = useNonSurfaceMode ?
3829                                         getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
3830                                         getPreferredColorFormatDefaultMode(portFmt->nIndex);
3831 
3832                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
3833                                         eRet = OMX_ErrorNoMore;
3834                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
3835                                                 " NoMore Color formats");
3836                                     }
3837                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
3838                                 } else {
3839                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
3840                                             (int)portFmt->nPortIndex);
3841                                     eRet = OMX_ErrorBadPortIndex;
3842                                 }
3843                                 break;
3844                             }
3845                             /*Component should support this port definition*/
3846         case OMX_IndexParamAudioInit: {
3847                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3848                               OMX_PORT_PARAM_TYPE *audioPortParamType =
3849                                   (OMX_PORT_PARAM_TYPE *) paramData;
3850                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
3851                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3852                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3853                               audioPortParamType->nPorts           = 0;
3854                               audioPortParamType->nStartPortNumber = 0;
3855                               break;
3856                           }
3857                           /*Component should support this port definition*/
3858         case OMX_IndexParamImageInit: {
3859                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3860                               OMX_PORT_PARAM_TYPE *imagePortParamType =
3861                                   (OMX_PORT_PARAM_TYPE *) paramData;
3862                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
3863                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3864                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3865                               imagePortParamType->nPorts           = 0;
3866                               imagePortParamType->nStartPortNumber = 0;
3867                               break;
3868 
3869                           }
3870                           /*Component should support this port definition*/
3871         case OMX_IndexParamOtherInit: {
3872                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
3873                                       paramIndex);
3874                               eRet =OMX_ErrorUnsupportedIndex;
3875                               break;
3876                           }
3877         case OMX_IndexParamStandardComponentRole: {
3878                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
3879                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
3880                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3881                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
3882                                   comp_role->nSize = sizeof(*comp_role);
3883 
3884                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
3885                                           paramIndex);
3886                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
3887                                           OMX_MAX_STRINGNAME_SIZE);
3888                                   break;
3889                               }
3890                               /* Added for parameter test */
3891         case OMX_IndexParamPriorityMgmt: {
3892                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
3893                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
3894                                  (OMX_PRIORITYMGMTTYPE *) paramData;
3895                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
3896                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
3897                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
3898 
3899                              break;
3900                          }
3901                          /* Added for parameter test */
3902         case OMX_IndexParamCompBufferSupplier: {
3903                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
3904                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
3905                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3906                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
3907 
3908                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
3909                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
3910                                    if (0 == bufferSupplierType->nPortIndex)
3911                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3912                                    else if (1 == bufferSupplierType->nPortIndex)
3913                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3914                                    else
3915                                        eRet = OMX_ErrorBadPortIndex;
3916 
3917 
3918                                    break;
3919                                }
3920         case OMX_IndexParamVideoAvc: {
3921                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
3922                                      paramIndex);
3923                              break;
3924                          }
3925         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
3926                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
3927                                      paramIndex);
3928                              break;
3929                          }
3930         case OMX_IndexParamVideoMpeg2: {
3931                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
3932                                        paramIndex);
3933                                break;
3934                            }
3935         case OMX_IndexParamVideoProfileLevelQuerySupported: {
3936                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3937                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
3938                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3939                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3940                                         eRet = get_supported_profile_level(profileLevelType);
3941                                         break;
3942                                     }
3943 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3944         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
3945                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
3946                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
3947                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3948                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3949 
3950                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
3951                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
3952                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
3953                                             } else {
3954                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
3955                                             }
3956                                         } else {
3957                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
3958                                             eRet = OMX_ErrorBadParameter;
3959                                         }
3960                                     }
3961                                     break;
3962 #endif
3963 
3964 #ifdef FLEXYUV_SUPPORTED
3965         case OMX_QcomIndexFlexibleYUVDescription: {
3966                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
3967                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
3968                 eRet = describeColorFormat(paramData);
3969                 if (eRet == OMX_ErrorUnsupportedSetting) {
3970                     DEBUG_PRINT_LOW("The standard OMX linear formats are understood by client. Please ignore this  Unsupported Setting (0x80001019).");
3971                 }
3972                 break;
3973             }
3974 #endif
3975         case OMX_IndexParamVideoProfileLevelCurrent: {
3976              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3977              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3978              struct v4l2_control profile_control, level_control;
3979 
3980              switch (drv_ctx.decoder_format) {
3981                  case VDEC_CODECTYPE_H264:
3982                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3983                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3984                      break;
3985                  default:
3986                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
3987                      eRet = OMX_ErrorNotImplemented;
3988                      break;
3989              }
3990 
3991              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
3992                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
3993                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
3994                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
3995                         break;
3996                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
3997                         pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
3998                         break;
3999                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
4000                         pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
4001                         break;
4002                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4003                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
4004                         break;
4005                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4006                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
4007                         break;
4008                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4009                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
4010                         break;
4011                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4012                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
4013                         break;
4014                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4015                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
4016                         break;
4017                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4018                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
4019                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
4020                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
4021                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
4022                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
4023                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
4024                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
4025                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
4026                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
4027                         eRet = OMX_ErrorUnsupportedIndex;
4028                         break;
4029                 }
4030              } else {
4031                  eRet = OMX_ErrorUnsupportedIndex;
4032              }
4033 
4034 
4035              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
4036                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
4037                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
4038                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
4039                         break;
4040                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
4041                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
4042                         break;
4043                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
4044                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
4045                         break;
4046                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
4047                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
4048                         break;
4049                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
4050                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
4051                         break;
4052                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4053                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
4054                         break;
4055                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4056                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
4057                         break;
4058                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4059                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
4060                         break;
4061                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4062                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
4063                         break;
4064                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4065                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
4066                         break;
4067                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4068                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
4069                         break;
4070                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4071                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
4072                         break;
4073                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4074                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
4075                         break;
4076                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4077                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
4078                         break;
4079                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4080                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
4081                         break;
4082                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4083                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
4084                         break;
4085                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4086                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
4087                         break;
4088                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_0:
4089                         pParam->eLevel = OMX_VIDEO_AVCLevel6;
4090                         break;
4091                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_1:
4092                         pParam->eLevel = OMX_VIDEO_AVCLevel61;
4093                         break;
4094                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_2:
4095                         pParam->eLevel = OMX_VIDEO_AVCLevel62;
4096                         break;
4097                     default:
4098                         eRet = OMX_ErrorUnsupportedIndex;
4099                         break;
4100                 }
4101              } else {
4102                  eRet = OMX_ErrorUnsupportedIndex;
4103              }
4104 
4105              break;
4106 
4107          }
4108         case OMX_QTIIndexParamVideoClientExtradata:
4109         {
4110             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4111             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
4112             QOMX_EXTRADATA_ENABLE *pParam =
4113                 (QOMX_EXTRADATA_ENABLE *)paramData;
4114             if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4115                 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE;
4116                 eRet = OMX_ErrorNone;
4117             } else {
4118                 eRet = OMX_ErrorUnsupportedIndex;
4119             }
4120             break;
4121         }
4122         case OMX_QTIIndexParamDitherControl:
4123         {
4124             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
4125             DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL");
4126             QOMX_VIDEO_DITHER_CONTROL *pParam =
4127                 (QOMX_VIDEO_DITHER_CONTROL *) paramData;
4128             pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config;
4129             eRet = OMX_ErrorNone;
4130             break;
4131         }
4132         case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
4133         {
4134             VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
4135             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
4136             OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam =
4137                 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) paramData;
4138             pParam->eProfile = mClientSetProfile;
4139             pParam->eLevel = mClientSetLevel;
4140             eRet = OMX_ErrorNone;
4141             break;
4142         }
4143         default: {
4144                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
4145                  eRet =OMX_ErrorUnsupportedIndex;
4146              }
4147 
4148     }
4149 
4150     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
4151             drv_ctx.video_resolution.frame_width,
4152             drv_ctx.video_resolution.frame_height,
4153             drv_ctx.video_resolution.stride,
4154             drv_ctx.video_resolution.scan_lines);
4155 
4156     return eRet;
4157 }
4158 
4159 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4160 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
4161 {
4162     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
4163     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4164     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
4165 
4166     if ((params == NULL) ||
4167             (params->nativeBuffer == NULL) ||
4168             (params->nativeBuffer->handle == NULL) ||
4169             !m_enable_android_native_buffers)
4170         return OMX_ErrorBadParameter;
4171     m_use_android_native_buffers = OMX_TRUE;
4172     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4173     private_handle_t *handle = (private_handle_t *)nBuf->handle;
4174     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
4175         OMX_U8 *buffer = NULL;
4176         if (!secure_mode) {
4177             buffer = (OMX_U8*)mmap(0, handle->size,
4178                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4179             if (buffer == MAP_FAILED) {
4180                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4181                 return OMX_ErrorInsufficientResources;
4182             }
4183         }
4184         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
4185     } else {
4186         eRet = OMX_ErrorBadParameter;
4187     }
4188     return eRet;
4189 }
4190 #endif
4191 
4192 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
4193     struct v4l2_control control;
4194     struct v4l2_format fmt;
4195     /*control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
4196     control.value = 1;
4197     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
4198     if (rc < 0) {
4199         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
4200         return OMX_ErrorHardware;
4201     }*/
4202     m_smoothstreaming_mode = true;
4203     return OMX_ErrorNone;
4204 }
4205 
4206 /* ======================================================================
4207    FUNCTION
4208    omx_vdec::Setparameter
4209 
4210    DESCRIPTION
4211    OMX Set Parameter method implementation.
4212 
4213    PARAMETERS
4214    <TBD>.
4215 
4216    RETURN VALUE
4217    OMX Error None if successful.
4218 
4219    ========================================================================== */
4220 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
4221         OMX_IN OMX_INDEXTYPE paramIndex,
4222         OMX_IN OMX_PTR        paramData)
4223 {
4224     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4225     int ret=0;
4226     struct v4l2_format fmt;
4227 #ifdef _ANDROID_
4228     char property_value[PROPERTY_VALUE_MAX] = {0};
4229 #endif
4230     if (m_state == OMX_StateInvalid) {
4231         DEBUG_PRINT_ERROR("Set Param in Invalid State");
4232         return OMX_ErrorInvalidState;
4233     }
4234     if (paramData == NULL) {
4235         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
4236         return OMX_ErrorBadParameter;
4237     }
4238     if ((m_state != OMX_StateLoaded) &&
4239             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
4240             (m_out_bEnabled == OMX_TRUE) &&
4241             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
4242             (m_inp_bEnabled == OMX_TRUE)) {
4243         DEBUG_PRINT_ERROR("Set Param in Invalid State");
4244         return OMX_ErrorIncorrectStateOperation;
4245     }
4246     switch ((unsigned long)paramIndex) {
4247         case OMX_IndexParamPortDefinition: {
4248                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
4249                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
4250                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
4251                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
4252                                //been called.
4253                                DEBUG_PRINT_LOW(
4254                                        "set_parameter: OMX_IndexParamPortDefinition: dir %d port %d wxh %dx%d count: min %d actual %d size %d",
4255                                        (int)portDefn->eDir, (int)portDefn->nPortIndex,
4256                                        (int)portDefn->format.video.nFrameWidth,
4257                                        (int)portDefn->format.video.nFrameHeight,
4258                                        (int)portDefn->nBufferCountMin,
4259                                        (int)portDefn->nBufferCountActual,
4260                                        (int)portDefn->nBufferSize);
4261 
4262                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4263                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
4264                                                           portDefn->nBufferCountActual);
4265                                    eRet = OMX_ErrorBadParameter;
4266                                    break;
4267                                }
4268                                if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
4269                                    if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
4270                                         portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
4271                                         DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
4272                                                           portDefn->nBufferCountActual, portDefn->nBufferSize);
4273                                         eRet = OMX_ErrorBadParameter;
4274                                         break;
4275                                    }
4276                                     m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
4277                                             portDefn->nBufferCountActual);
4278                                     break;
4279                                }
4280 
4281                                if (OMX_DirOutput == portDefn->eDir) {
4282                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
4283                                    bool port_format_changed = false;
4284                                    m_display_id = portDefn->format.video.pNativeWindow;
4285                                    unsigned int buffer_size;
4286                                    /* update output port resolution with client supplied dimensions
4287                                       in case scaling is enabled, else it follows input resolution set
4288                                    */
4289                                    if (decide_dpb_buffer_mode()) {
4290                                        DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
4291                                        return OMX_ErrorBadParameter;
4292                                    }
4293                                    if (is_down_scalar_enabled) {
4294                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
4295                                                (unsigned int)portDefn->format.video.nFrameWidth,
4296                                                (unsigned int)portDefn->format.video.nFrameHeight);
4297                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
4298                                                portDefn->format.video.nFrameWidth != 0x0) {
4299                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
4300                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4301                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
4302                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4303                                            if (ret) {
4304                                                DEBUG_PRINT_ERROR("Get Resolution failed");
4305                                                eRet = OMX_ErrorHardware;
4306                                                break;
4307                                            }
4308                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
4309                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
4310                                                    port_format_changed = true;
4311                                            }
4312 
4313                                            /* set crop info */
4314                                            rectangle.nLeft = 0;
4315                                            rectangle.nTop = 0;
4316                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
4317                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
4318 
4319                                            m_extradata_info.output_crop_rect.nLeft = 0;
4320                                            m_extradata_info.output_crop_rect.nTop = 0;
4321                                            m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth;
4322                                            m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight;
4323 
4324                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
4325                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4326                                            fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
4327                                            fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
4328                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
4329                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
4330                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
4331                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4332                                            if (ret) {
4333                                                DEBUG_PRINT_ERROR("Set Resolution failed");
4334                                                eRet = errno == EBUSY ? OMX_ErrorInsufficientResources : OMX_ErrorUnsupportedSetting;
4335                                            } else
4336                                                eRet = get_buffer_req(&drv_ctx.op_buf);
4337                                        }
4338 
4339                                        if (eRet) {
4340                                            break;
4341                                        }
4342                                    }
4343 
4344                                    if (eRet) {
4345                                        break;
4346                                    }
4347 
4348                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4349                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
4350                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4351                                        eRet = OMX_ErrorBadParameter;
4352                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
4353                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
4354                                        eRet = OMX_ErrorBadParameter;
4355                                    } else if (!port_format_changed) {
4356 
4357                                        // Buffer count can change only when port is unallocated
4358                                        if (m_out_mem_ptr &&
4359                                                 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
4360                                                 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
4361 
4362                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
4363                                            eRet = OMX_ErrorInvalidState;
4364                                            break;
4365                                        }
4366 
4367                                        // route updating of buffer requirements via c2d proxy.
4368                                        // Based on whether c2d is enabled, requirements will be handed
4369                                        // to the vidc driver appropriately
4370                                        eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
4371                                                 portDefn->nBufferCountActual);
4372                                        if (eRet == OMX_ErrorNone) {
4373                                            m_port_def = *portDefn;
4374                                        } else {
4375                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
4376                                                    drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
4377                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4378                                            eRet = OMX_ErrorBadParameter;
4379                                        }
4380                                    }
4381                                } else if (OMX_DirInput == portDefn->eDir) {
4382                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
4383                                    bool port_format_changed = false;
4384                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
4385                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
4386                                        // Frame rate only should be set if this is a "known value" or to
4387                                        // activate ts prediction logic (arbitrary mode only) sending input
4388                                        // timestamps with max value (LLONG_MAX).
4389                                        m_fps_received = portDefn->format.video.xFramerate;
4390                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
4391                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
4392                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
4393                                                drv_ctx.frame_rate.fps_denominator);
4394                                        if (!drv_ctx.frame_rate.fps_numerator) {
4395                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4396                                            drv_ctx.frame_rate.fps_numerator = 30;
4397                                        }
4398                                        if (drv_ctx.frame_rate.fps_denominator)
4399                                            drv_ctx.frame_rate.fps_numerator = (int)
4400                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4401                                        drv_ctx.frame_rate.fps_denominator = 1;
4402                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4403                                            drv_ctx.frame_rate.fps_numerator;
4404                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
4405                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
4406                                                (float)drv_ctx.frame_rate.fps_denominator);
4407 
4408                                        struct v4l2_outputparm oparm;
4409                                        /*XXX: we're providing timing info as seconds per frame rather than frames
4410                                         * per second.*/
4411                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4412                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4413 
4414                                        struct v4l2_streamparm sparm;
4415                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4416                                        sparm.parm.output = oparm;
4417                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4418                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
4419                                            eRet = OMX_ErrorHardware;
4420                                            break;
4421                                        }
4422                                    }
4423 
4424                                    if (drv_ctx.video_resolution.frame_height !=
4425                                            portDefn->format.video.nFrameHeight ||
4426                                            drv_ctx.video_resolution.frame_width  !=
4427                                            portDefn->format.video.nFrameWidth) {
4428                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
4429                                                (unsigned int)portDefn->format.video.nFrameWidth,
4430                                                (unsigned int)portDefn->format.video.nFrameHeight);
4431                                        port_format_changed = true;
4432                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
4433                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
4434                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
4435                                            if (m_smoothstreaming_mode &&
4436                                                    ((frameWidth * frameHeight) <
4437                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
4438                                                frameWidth = m_smoothstreaming_width;
4439                                                frameHeight = m_smoothstreaming_height;
4440                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
4441                                                        "for adaptive-playback/smooth-streaming",
4442                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
4443                                            }
4444 
4445                                            m_extradata_info.output_crop_rect.nLeft = 0;
4446                                            m_extradata_info.output_crop_rect.nTop = 0;
4447                                            m_extradata_info.output_crop_rect.nWidth = frameWidth;
4448                                            m_extradata_info.output_crop_rect.nHeight = frameHeight;
4449 
4450                                            update_resolution(frameWidth, frameHeight,
4451                                                    frameWidth, frameHeight);
4452                                            if (is_down_scalar_enabled) {
4453                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
4454                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4455                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4456                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4457                                                fmt.fmt.pix_mp.pixelformat = output_capability;
4458                                                DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d",
4459                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4460                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4461                                            } else {
4462                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
4463                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4464                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4465                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4466                                                fmt.fmt.pix_mp.pixelformat = output_capability;
4467                                                DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
4468                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4469                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4470                                                fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4471                                                fmt.fmt.pix_mp.pixelformat = capture_capability;
4472                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4473                                            }
4474                                            if (ret) {
4475                                                DEBUG_PRINT_ERROR("Set Resolution failed");
4476                                                eRet = errno == EBUSY ? OMX_ErrorInsufficientResources : OMX_ErrorUnsupportedSetting;
4477                                            } else {
4478                                                if (!is_down_scalar_enabled)
4479                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
4480                                            }
4481                                            if (eRet)
4482                                                break;
4483                                        }
4484                                    }
4485                                    if (m_custom_buffersize.input_buffersize
4486                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
4487                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
4488                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
4489                                        eRet = OMX_ErrorBadParameter;
4490                                        break;
4491                                    }
4492                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4493                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
4494                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4495                                        eRet = OMX_ErrorBadParameter;
4496                                        break;
4497                                    }
4498                                    // Buffer count can change only when port is unallocated
4499                                    if (m_inp_mem_ptr &&
4500                                             (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
4501                                             portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
4502                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
4503                                        eRet = OMX_ErrorInvalidState;
4504                                        break;
4505                                    }
4506 
4507                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
4508                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
4509                                        port_format_changed = true;
4510                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
4511                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
4512                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
4513                                            (~(buffer_prop->alignment - 1));
4514                                        eRet = set_buffer_req(buffer_prop);
4515                                    }
4516                                    if (false == port_format_changed) {
4517                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
4518                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
4519                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4520                                        eRet = OMX_ErrorBadParameter;
4521                                    }
4522                                } else if (portDefn->eDir ==  OMX_DirMax) {
4523                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
4524                                            (int)portDefn->nPortIndex);
4525                                    eRet = OMX_ErrorBadPortIndex;
4526                                }
4527                            }
4528                            break;
4529         case OMX_IndexParamVideoPortFormat: {
4530                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
4531                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
4532                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
4533                                 int ret=0;
4534                                 struct v4l2_format fmt;
4535                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
4536                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
4537 
4538                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4539                                 if (1 == portFmt->nPortIndex) {
4540                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4541                                     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4542                                     if (ret < 0) {
4543                                         DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
4544                                         return OMX_ErrorBadParameter;
4545                                     }
4546                                     enum vdec_output_format op_format;
4547                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4548                                                      QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
4549                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
4550                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
4551                                         //check if the required color format is a supported flexible format
4552                                         is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4553                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4554                                                    QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
4555                                                portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
4556                                         portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
4557                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12_UBWC;
4558                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
4559                                         //check if the required color format is a supported flexible format
4560                                         is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4561                                     } else {
4562                                         eRet = OMX_ErrorBadParameter;
4563                                     }
4564 
4565                                     if (eRet == OMX_ErrorNone) {
4566                                         drv_ctx.output_format = op_format;
4567                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4568                                         if (ret) {
4569                                             DEBUG_PRINT_ERROR("Set output format failed");
4570                                             eRet = OMX_ErrorUnsupportedSetting;
4571                                             /*TODO: How to handle this case */
4572                                         } else {
4573                                             eRet = get_buffer_req(&drv_ctx.op_buf);
4574                                         }
4575                                     }
4576                                     if (eRet == OMX_ErrorNone) {
4577                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
4578                                             DEBUG_PRINT_ERROR("Set color format failed");
4579                                             eRet = OMX_ErrorBadParameter;
4580                                         }
4581                                     }
4582                                 }
4583                             }
4584                             break;
4585         case OMX_QcomIndexPortDefn: {
4586                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
4587                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
4588                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
4589                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
4590                                     (unsigned int)portFmt->nFramePackingFormat);
4591 
4592                             /* Input port */
4593                             if (portFmt->nPortIndex == 0) {
4594                                 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
4595                                 //   - headers are allocated and
4596                                 //   - headers-indices are derived
4597                                 // Avoid changing arbitrary_bytes when the port is already allocated
4598                                 if (m_inp_mem_ptr) {
4599                                     DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
4600                                     return OMX_ErrorUnsupportedSetting;
4601                                 }
4602                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
4603                                     if (secure_mode || m_input_pass_buffer_fd) {
4604                                         arbitrary_bytes = false;
4605                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
4606                                         eRet = OMX_ErrorUnsupportedSetting;
4607                                     } else {
4608                                         arbitrary_bytes = true;
4609                                     }
4610                                 } else if (portFmt->nFramePackingFormat ==
4611                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
4612                                     arbitrary_bytes = false;
4613                                 } else {
4614                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
4615                                             (unsigned int)portFmt->nFramePackingFormat);
4616                                     eRet = OMX_ErrorUnsupportedSetting;
4617                                 }
4618                                 //Explicitly disable arb mode for unsupported codecs
4619                                 bool is_arb_supported = false;
4620                                 if (arbitrary_bytes) {
4621                                    switch (drv_ctx.decoder_format) {
4622                                    case VDEC_CODECTYPE_H264:
4623                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_H264;
4624                                       break;
4625                                    case VDEC_CODECTYPE_HEVC:
4626                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_HEVC;
4627                                       break;
4628                                    case VDEC_CODECTYPE_MPEG2:
4629                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_MPEG2;
4630                                       break;
4631                                    default:
4632                                       DEBUG_PRINT_HIGH("Arbitrary bytes mode not enabled for this Codec");
4633                                       break;
4634                                    }
4635 
4636                                    if (!is_arb_supported) {
4637                                        DEBUG_PRINT_ERROR("Setparameter: Disabling arbitrary bytes mode explicitly");
4638                                        arbitrary_bytes = false;
4639                                        eRet = OMX_ErrorUnsupportedSetting;
4640                                    }
4641                                 }
4642                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
4643                                 DEBUG_PRINT_ERROR("Unsupported at O/P port");
4644                                 eRet = OMX_ErrorUnsupportedSetting;
4645                             }
4646                             break;
4647                         }
4648         case OMX_QTIIndexParamVideoClientExtradata: {
4649                                   VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4650                                   DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
4651                                   QOMX_EXTRADATA_ENABLE *pParam =
4652                                       (QOMX_EXTRADATA_ENABLE *)paramData;
4653 
4654                                   if (m_state != OMX_StateLoaded) {
4655                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
4656                                       return OMX_ErrorIncorrectStateOperation;
4657                                   }
4658 
4659                                   if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4660                                       m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
4661                                   } else {
4662                                       DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
4663                                       eRet = OMX_ErrorUnsupportedIndex;
4664                                   }
4665                                   break;
4666                               }
4667         case OMX_IndexParamStandardComponentRole: {
4668                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
4669                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
4670                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
4671                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
4672                                           comp_role->cRole);
4673 
4674                                   if ((m_state == OMX_StateLoaded)&&
4675                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
4676                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
4677                                   } else {
4678                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4679                                       return OMX_ErrorIncorrectStateOperation;
4680                                   }
4681 
4682                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4683                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4684                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
4685                                       } else {
4686                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4687                                           eRet =OMX_ErrorUnsupportedSetting;
4688                                       }
4689                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4690                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4691                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
4692                                       } else {
4693                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4694                                           eRet = OMX_ErrorUnsupportedSetting;
4695                                       }
4696                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4697                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4698                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
4699                                       } else {
4700                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4701                                           eRet = OMX_ErrorUnsupportedSetting;
4702                                       }
4703                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
4704                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
4705                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4706                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
4707                                       } else {
4708                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4709                                           eRet = OMX_ErrorUnsupportedSetting;
4710                                       }
4711                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
4712                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
4713                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4714                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
4715                                       } else {
4716                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4717                                           eRet = OMX_ErrorUnsupportedSetting;
4718                                       }
4719                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4720                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4721                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4722                                       } else {
4723                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4724                                           eRet = OMX_ErrorUnsupportedSetting;
4725                                       }
4726                                   } else {
4727                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
4728                                       eRet = OMX_ErrorInvalidComponentName;
4729                                   }
4730                                   break;
4731                               }
4732 
4733         case OMX_IndexParamPriorityMgmt: {
4734                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
4735                              if (m_state != OMX_StateLoaded) {
4736                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4737                                  return OMX_ErrorIncorrectStateOperation;
4738                              }
4739                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
4740                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
4741                                      (unsigned int)priorityMgmtype->nGroupID);
4742 
4743                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
4744                                      (unsigned int)priorityMgmtype->nGroupPriority);
4745 
4746                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
4747                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
4748 
4749                              break;
4750                          }
4751 
4752         case OMX_IndexParamCompBufferSupplier: {
4753                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
4754                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
4755                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
4756                                            bufferSupplierType->eBufferSupplier);
4757                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
4758                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
4759 
4760                                    else
4761 
4762                                        eRet = OMX_ErrorBadPortIndex;
4763 
4764                                    break;
4765 
4766                                }
4767         case OMX_IndexParamVideoAvc: {
4768                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
4769                                      paramIndex);
4770                              break;
4771                          }
4772         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
4773                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
4774                                      paramIndex);
4775                              break;
4776                         }
4777         case OMX_IndexParamVideoMpeg2: {
4778                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
4779                                        paramIndex);
4780                                break;
4781                            }
4782         case OMX_QTIIndexParamLowLatencyMode: {
4783                                struct v4l2_control control;
4784                                int rc = 0;
4785                                QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE* pParam =
4786                                    (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
4787                                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
4788                                 if (pParam->bEnableLowLatencyMode)
4789                                     control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4790                                 else
4791                                     control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
4792 
4793                                 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4794                                 if (rc) {
4795                                     DEBUG_PRINT_ERROR("Set low latency failed");
4796                                     eRet = OMX_ErrorUnsupportedSetting;
4797                                 } else {
4798                                     m_sParamLowLatency.bEnableLowLatencyMode = pParam->bEnableLowLatencyMode;
4799                                 }
4800                                break;
4801                            }
4802         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
4803                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
4804                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
4805                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
4806                                      struct v4l2_control control;
4807                                      int pic_order,rc=0;
4808                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
4809                                              pictureOrder->eOutputPictureOrder);
4810                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
4811                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
4812                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
4813                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4814                                          time_stamp_dts.set_timestamp_reorder_mode(false);
4815                                      } else
4816                                          eRet = OMX_ErrorBadParameter;
4817                                      if (eRet == OMX_ErrorNone) {
4818                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4819                                          control.value = pic_order;
4820                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4821                                          if (rc) {
4822                                              DEBUG_PRINT_ERROR("Set picture order failed");
4823                                              eRet = OMX_ErrorUnsupportedSetting;
4824                                          }
4825                                      }
4826                                      m_decode_order_mode =
4827                                             pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
4828                                      break;
4829                                  }
4830         case OMX_QcomIndexParamConcealMBMapExtraData:
4831                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4832                                eRet = enable_extradata(OMX_MB_ERROR_MAP_EXTRADATA, false,
4833                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4834                                break;
4835         case OMX_QcomIndexParamFrameInfoExtraData:
4836                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4837                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
4838                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4839                                break;
4840         case OMX_ExtraDataFrameDimension:
4841                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4842                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
4843                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4844                                break;
4845         case OMX_QcomIndexParamInterlaceExtraData:
4846                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4847                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
4848                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4849                                break;
4850         case OMX_QcomIndexParamOutputCropExtraData:
4851                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4852                                eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4853                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4854                                break;
4855         case OMX_QcomIndexParamH264TimeInfo:
4856                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4857                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
4858                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4859                                break;
4860         case OMX_QcomIndexParamVideoFramePackingExtradata:
4861                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4862                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
4863                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4864                                break;
4865         case OMX_QcomIndexParamVideoQPExtraData:
4866                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4867                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
4868                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4869                                break;
4870         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
4871                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4872                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
4873                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4874                                break;
4875         case OMX_QcomIndexEnableExtnUserData:
4876                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4877                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
4878                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
4879                                 break;
4880         case OMX_QTIIndexParamVQZipSEIExtraData:
4881                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4882                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
4883                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
4884                                 break;
4885         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
4886                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
4887                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
4888                                        struct v4l2_control control;
4889                                        int rc;
4890                                        drv_ctx.idr_only_decoding = 1;
4891                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4892                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4893                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4894                                        if (rc) {
4895                                            DEBUG_PRINT_ERROR("Set picture order failed");
4896                                            eRet = OMX_ErrorUnsupportedSetting;
4897                                        } else {
4898                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
4899                                            control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4900                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4901                                            if (rc) {
4902                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
4903                                                eRet = OMX_ErrorUnsupportedSetting;
4904                                            }
4905                                            /*Setting sync frame decoding on driver might change buffer
4906                                             * requirements so update them here*/
4907                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
4908                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
4909                                                eRet = OMX_ErrorUnsupportedSetting;
4910                                            }
4911                                            if (get_buffer_req(&drv_ctx.op_buf)) {
4912                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
4913                                                eRet = OMX_ErrorUnsupportedSetting;
4914                                            }
4915                                        }
4916                                    }
4917                                    break;
4918 
4919         case OMX_QcomIndexParamIndexExtraDataType: {
4920                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
4921                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
4922                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
4923                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
4924                                             (extradataIndexType->nPortIndex == 1)) {
4925                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
4926                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
4927                                     } else if ((extradataIndexType->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataOutputCropInfo) &&
4928                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
4929                                             (extradataIndexType->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)) {
4930                                         eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4931                                             ((QOMX_ENABLETYPE *)paramData)->bEnable);
4932                                     }
4933                                 }
4934                                 break;
4935         case OMX_QcomIndexParamEnableSmoothStreaming: {
4936 #ifndef SMOOTH_STREAMING_DISABLED
4937                                       eRet = enable_smoothstreaming();
4938 #else
4939                                       eRet = OMX_ErrorUnsupportedSetting;
4940 #endif
4941                                   }
4942                                   break;
4943 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4944                                   /* Need to allow following two set_parameters even in Idle
4945                                    * state. This is ANDROID architecture which is not in sync
4946                                    * with openmax standard. */
4947         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
4948                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
4949                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
4950                                            if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
4951                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
4952                                                 eRet = OMX_ErrorUnsupportedSetting;
4953                                                 break;
4954                                            } else if (m_out_mem_ptr) {
4955                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
4956                                                 eRet = OMX_ErrorInvalidState;
4957                                                 break;
4958                                            }
4959                                            if (enableNativeBuffers) {
4960                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
4961                                            }
4962 #if !defined(FLEXYUV_SUPPORTED)
4963                                            if (m_enable_android_native_buffers) {
4964                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
4965                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
4966                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
4967                                                    eRet = OMX_ErrorUnsupportedSetting;
4968                                                }
4969                                            }
4970 #endif
4971                                        }
4972                                        break;
4973         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
4974                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
4975                                        eRet = use_android_native_buffer(hComp, paramData);
4976                                    }
4977                                    break;
4978 #if ALLOCATE_OUTPUT_NATIVEHANDLE
4979         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
4980 
4981                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
4982                 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
4983 
4984                 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
4985                     DEBUG_PRINT_LOW("Enable/Disable allocate-native-handle allowed only on input port!. Please ignore this Unsupported Setting (0x80001019).");
4986                     eRet = OMX_ErrorUnsupportedSetting;
4987                     break;
4988                 } else if (m_inp_mem_ptr) {
4989                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
4990                     eRet = OMX_ErrorInvalidState;
4991                     break;
4992                 }
4993 
4994                 if (allocateNativeHandleParams != NULL) {
4995                     allocate_native_handle = allocateNativeHandleParams->enable;
4996                 }
4997             }
4998             break;
4999 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
5000 #endif
5001         case OMX_QcomIndexParamEnableTimeStampReorder: {
5002                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
5003                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
5004                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
5005                                            if (reorder->bEnable == OMX_TRUE) {
5006                                                frm_int =0;
5007                                                time_stamp_dts.set_timestamp_reorder_mode(true);
5008                                            } else
5009                                                time_stamp_dts.set_timestamp_reorder_mode(false);
5010                                        } else {
5011                                            time_stamp_dts.set_timestamp_reorder_mode(false);
5012                                            if (reorder->bEnable == OMX_TRUE) {
5013                                                eRet = OMX_ErrorUnsupportedSetting;
5014                                            }
5015                                        }
5016                                    }
5017                                    break;
5018         case OMX_IndexParamVideoProfileLevelCurrent: {
5019                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
5020                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
5021                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
5022                                      if (pParam) {
5023                                          m_profile_lvl.eProfile = pParam->eProfile;
5024                                          m_profile_lvl.eLevel = pParam->eLevel;
5025                                      }
5026                                      break;
5027 
5028                                  }
5029         case OMX_QcomIndexParamVideoMetaBufferMode:
5030         {
5031             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
5032             StoreMetaDataInBuffersParams *metabuffer =
5033                 (StoreMetaDataInBuffersParams *)paramData;
5034             if (!metabuffer) {
5035                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
5036                 eRet = OMX_ErrorBadParameter;
5037                 break;
5038             }
5039             if (m_disable_dynamic_buf_mode) {
5040                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
5041                 eRet = OMX_ErrorUnsupportedSetting;
5042                 break;
5043             }
5044             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
5045 
5046                 if (m_out_mem_ptr) {
5047                     DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
5048                     eRet = OMX_ErrorInvalidState;
5049                     break;
5050                 }
5051 
5052                 dynamic_buf_mode = metabuffer->bStoreMetaData;
5053                 DEBUG_PRINT_HIGH("%s buffer mode",
5054                     (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
5055 
5056             } else {
5057                 DEBUG_PRINT_ERROR(
5058                    "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
5059                    (unsigned int)metabuffer->nPortIndex);
5060                 eRet = OMX_ErrorUnsupportedSetting;
5061             }
5062             break;
5063         }
5064         case OMX_QcomIndexParamVideoDownScalar:
5065         {
5066             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
5067             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
5068             struct v4l2_control control;
5069             int rc;
5070             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
5071 
5072             if (pParam && pParam->bEnable) {
5073                 rc = enable_downscalar();
5074                 if (rc < 0) {
5075                     DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
5076                     return OMX_ErrorUnsupportedSetting;
5077                 }
5078                 m_force_down_scalar = pParam->bEnable;
5079             } else {
5080                 rc = disable_downscalar();
5081                 if (rc < 0) {
5082                     DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
5083                     return OMX_ErrorUnsupportedSetting;
5084                 }
5085                 m_force_down_scalar = pParam->bEnable;
5086             }
5087             break;
5088         }
5089 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5090         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
5091         {
5092             VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
5093             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
5094             PrepareForAdaptivePlaybackParams* pParams =
5095                     (PrepareForAdaptivePlaybackParams *) paramData;
5096             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
5097                 if (!pParams->bEnable) {
5098                     return OMX_ErrorNone;
5099                 }
5100                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
5101                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
5102                     DEBUG_PRINT_ERROR(
5103                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
5104                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
5105                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
5106                     eRet = OMX_ErrorBadParameter;
5107                 } else {
5108                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
5109                 }
5110             } else {
5111                 DEBUG_PRINT_ERROR(
5112                         "Prepare for adaptive playback supported only on output port");
5113                 eRet = OMX_ErrorBadParameter;
5114             }
5115             break;
5116         }
5117 
5118         case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
5119         {
5120             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5121             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
5122             m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5123             if (m_disable_dynamic_buf_mode) {
5124                 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
5125             }
5126             break;
5127         }
5128 #endif
5129         case OMX_QcomIndexParamVideoCustomBufferSize:
5130         {
5131             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
5132             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
5133             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
5134             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5135                 struct v4l2_control control;
5136                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
5137                 control.value = pParam->nBufferSize;
5138                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5139                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
5140                     eRet = OMX_ErrorUnsupportedSetting;
5141                 } else {
5142                     eRet = get_buffer_req(&drv_ctx.ip_buf);
5143                     if (eRet == OMX_ErrorNone) {
5144                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
5145                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
5146                             m_custom_buffersize.input_buffersize);
5147                     } else {
5148                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
5149                     }
5150                 }
5151             } else {
5152                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
5153                 eRet = OMX_ErrorBadParameter;
5154             }
5155             break;
5156         }
5157         case OMX_QTIIndexParamVQZIPSEIType:
5158         {
5159             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
5160             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
5161             OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
5162                 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
5163                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
5164 
5165             eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
5166                 ((QOMX_ENABLETYPE *)paramData)->bEnable);
5167             if (eRet != OMX_ErrorNone) {
5168                 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
5169                 eRet = OMX_ErrorBadParameter;
5170                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5171                 break;
5172             }
5173             eRet = enable_extradata(OMX_QP_EXTRADATA, false,
5174                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
5175             if (eRet != OMX_ErrorNone) {
5176                 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
5177                 eRet = OMX_ErrorBadParameter;
5178                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5179                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5180                 break;
5181             }
5182             eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
5183                         ((QOMX_ENABLETYPE *)paramData)->bEnable);
5184             if (eRet != OMX_ErrorNone) {
5185                 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata");
5186                 eRet = OMX_ErrorBadParameter;
5187                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5188                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5189                 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA;
5190             }
5191             break;
5192         }
5193         case OMX_QTIIndexParamPassInputBufferFd:
5194         {
5195             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5196             if (arbitrary_bytes) {
5197                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
5198                 eRet = OMX_ErrorUnsupportedSetting;
5199                 break;
5200             }
5201 
5202             m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5203             if (m_input_pass_buffer_fd)
5204                 DEBUG_PRINT_LOW("Enable passing input buffer FD");
5205             break;
5206         }
5207         case OMX_QTIIndexParamForceCompressedForDPB:
5208         {
5209             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
5210             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
5211             OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
5212                 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
5213             if (m_disable_ubwc_mode) {
5214                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
5215                 eRet = OMX_ErrorUnsupportedSetting;
5216                 break;
5217             }
5218             if (!paramData) {
5219                DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
5220                eRet = OMX_ErrorBadParameter;
5221                break;
5222             }
5223 
5224             m_force_compressed_for_dpb = pParam->bEnable;
5225             break;
5226         }
5227         case OMX_QTIIndexParamForceUnCompressedForOPB:
5228         {
5229             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
5230             OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
5231                 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
5232             if (!paramData) {
5233                 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
5234                 eRet = OMX_ErrorBadParameter;
5235                 break;
5236             }
5237             m_disable_ubwc_mode = pParam->bEnable;
5238             DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
5239             break;
5240         }
5241         case OMX_QTIIndexParamDitherControl:
5242         {
5243             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
5244             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl");
5245             QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData;
5246             DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType);
5247             if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) ||
5248                 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) {
5249                 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range");
5250                 eRet = OMX_ErrorBadParameter;
5251                 break;
5252             }
5253             m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE;
5254             DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config);
5255             break;
5256         }
5257         case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
5258         {
5259             VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
5260             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
5261             OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
5262 
5263             if ((output_capability != V4L2_PIX_FMT_H264) ||
5264                 (output_capability != V4L2_PIX_FMT_HEVC)) {
5265                 DEBUG_PRINT_ERROR("set_parameter: Unsupported codec for client configured profile and level");
5266                 eRet = OMX_ErrorBadParameter;
5267             }
5268 
5269             DEBUG_PRINT_LOW("set_parameter: Client set profile is: %d", pParam->eProfile);
5270             DEBUG_PRINT_LOW("set_parameter: Client set level is: %d", pParam->eLevel);
5271             mClientSessionForSufficiency = true;
5272             mClientSetProfile = pParam->eProfile;
5273             mClientSetLevel = pParam->eLevel;
5274             break;
5275         }
5276         case OMX_QTIIndexParamVideoDecoderOutputFrameRate:
5277         {
5278             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_OUTPUT_FRAME_RATE);
5279             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoDecoderOutputFrameRate");
5280             QOMX_VIDEO_OUTPUT_FRAME_RATE *pParam = (QOMX_VIDEO_OUTPUT_FRAME_RATE*)paramData;
5281             DEBUG_PRINT_LOW("set_parameter: decoder output-frame-rate %d", pParam->fps);
5282             m_dec_hfr_fps=pParam->fps;
5283             DEBUG_PRINT_HIGH("output-frame-rate value = %d", m_dec_hfr_fps);
5284             if (m_dec_hfr_fps) {
5285                 m_last_rendered_TS = 0;
5286             }
5287             break;
5288         }
5289         default: {
5290                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
5291                  eRet = OMX_ErrorUnsupportedIndex;
5292              }
5293     }
5294     if (eRet != OMX_ErrorNone)
5295         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
5296     return eRet;
5297 }
5298 
5299 /* ======================================================================
5300    FUNCTION
5301    omx_vdec::GetConfig
5302 
5303    DESCRIPTION
5304    OMX Get Config Method implementation.
5305 
5306    PARAMETERS
5307    <TBD>.
5308 
5309    RETURN VALUE
5310    OMX Error None if successful.
5311 
5312    ========================================================================== */
5313 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
5314         OMX_IN OMX_INDEXTYPE configIndex,
5315         OMX_INOUT OMX_PTR     configData)
5316 {
5317     (void) hComp;
5318     OMX_ERRORTYPE eRet = OMX_ErrorNone;
5319 
5320     if (m_state == OMX_StateInvalid) {
5321         DEBUG_PRINT_ERROR("Get Config in Invalid State");
5322         return OMX_ErrorInvalidState;
5323     }
5324 
5325     switch ((unsigned long)configIndex) {
5326         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
5327                                      VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
5328                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
5329                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
5330                                      decoderinstances->nNumOfInstances = 16;
5331                                      /*TODO: How to handle this case */
5332                                      break;
5333                                  }
5334         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
5335                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
5336                                               VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
5337                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
5338                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
5339                                               memcpy(configFmt, &m_frame_pack_arrangement,
5340                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
5341                                           } else {
5342                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
5343                                           }
5344                                           break;
5345                                       }
5346         case OMX_IndexConfigCommonOutputCrop: {
5347                                   VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
5348                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
5349                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
5350                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
5351                                         rectangle.nLeft, rectangle.nTop,
5352                                         rectangle.nWidth, rectangle.nHeight);
5353                                   break;
5354                               }
5355         case OMX_QcomIndexConfigH264EntropyCodingCabac: {
5356             VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
5357             QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
5358             struct v4l2_control control;
5359 
5360             if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
5361                 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
5362                 eRet = OMX_ErrorNotImplemented;
5363                 break;
5364             }
5365 
5366             control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
5367             if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
5368                 coding->bCabac = (OMX_BOOL)
5369                     (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
5370                 /* We can't query driver at the moment for the cabac mode, so
5371                  * just use 0xff...f as a place holder for future improvement */
5372                 coding->nCabacInitIdc = ~0;
5373             } else {
5374                 eRet = OMX_ErrorUnsupportedIndex;
5375             }
5376 
5377             break;
5378         }
5379         case OMX_QTIIndexConfigDescribeColorAspects:
5380         {
5381             VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5382             DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5383 
5384             if (params->bRequestingDataSpace) {
5385                 DEBUG_PRINT_LOW("Does not handle dataspace request. Please ignore this Unsupported Setting (0x80001019).");
5386                 return OMX_ErrorUnsupportedSetting;
5387             }
5388 
5389             print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
5390             print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
5391             get_preferred_color_aspects(params->sAspects);
5392             print_debug_color_aspects(&(params->sAspects), "Frameworks path GetConfig Color Aspects");
5393 
5394             break;
5395         }
5396         case OMX_QTIIndexConfigDescribeHDRColorInfo:
5397         {
5398             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5399             DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5400             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR");
5401             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR");
5402             get_preferred_hdr_info(params->sInfo);
5403             print_debug_hdr_color_info(&(params->sInfo), "Frameworks path GetConfig HDR");
5404 
5405             break;
5406         }
5407         case OMX_QTIIndexConfigDescribeHDR10PlusInfo:
5408         {
5409             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
5410             DescribeHDR10PlusInfoParams *params = (DescribeHDR10PlusInfoParams *)configData;
5411             get_hdr10plusinfo(params);
5412             print_hdr10plusinfo(params);
5413             break;
5414         }
5415         case OMX_IndexConfigAndroidVendorExtension:
5416         {
5417             VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5418 
5419             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5420                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5421             VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5422             return get_vendor_extension_config(ext);
5423         }
5424         default:
5425         {
5426             DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
5427             eRet = OMX_ErrorBadParameter;
5428         }
5429 
5430     }
5431 
5432     return eRet;
5433 }
5434 
5435 /* ======================================================================
5436    FUNCTION
5437    omx_vdec::SetConfig
5438 
5439    DESCRIPTION
5440    OMX Set Config method implementation
5441 
5442    PARAMETERS
5443    <TBD>.
5444 
5445    RETURN VALUE
5446    OMX Error None if successful.
5447    ========================================================================== */
5448 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
5449         OMX_IN OMX_INDEXTYPE configIndex,
5450         OMX_IN OMX_PTR        configData)
5451 {
5452     (void) hComp;
5453     if (m_state == OMX_StateInvalid) {
5454         DEBUG_PRINT_ERROR("Get Config in Invalid State");
5455         return OMX_ErrorInvalidState;
5456     }
5457 
5458     OMX_ERRORTYPE ret = OMX_ErrorNone;
5459     OMX_VIDEO_CONFIG_NALSIZE *pNal;
5460 
5461     DEBUG_PRINT_LOW("Set Config Called");
5462 
5463 
5464     if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
5465         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
5466         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
5467 
5468         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5469             if (config->bEnabled) {
5470                 if ((config->nFps >> 16) > 0 &&
5471                         (config->nFps >> 16) <= MAX_SUPPORTED_FPS) {
5472                     m_fps_received = config->nFps;
5473                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
5474                             (unsigned int)config->nFps >> 16);
5475                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
5476                             drv_ctx.frame_rate.fps_denominator);
5477 
5478                     if (!drv_ctx.frame_rate.fps_numerator) {
5479                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
5480                         drv_ctx.frame_rate.fps_numerator = 30;
5481                     }
5482 
5483                     if (drv_ctx.frame_rate.fps_denominator) {
5484                         drv_ctx.frame_rate.fps_numerator = (int)
5485                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
5486                     }
5487 
5488                     drv_ctx.frame_rate.fps_denominator = 1;
5489                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
5490                         drv_ctx.frame_rate.fps_numerator;
5491 
5492                     struct v4l2_outputparm oparm;
5493                     /*XXX: we're providing timing info as seconds per frame rather than frames
5494                      * per second.*/
5495                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
5496                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
5497 
5498                     struct v4l2_streamparm sparm;
5499                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5500                     sparm.parm.output = oparm;
5501                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
5502                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
5503                                 performance might be affected");
5504                         ret = OMX_ErrorHardware;
5505                     }
5506                     client_set_fps = true;
5507                 } else {
5508                     DEBUG_PRINT_ERROR("Frame rate not supported.");
5509                     ret = OMX_ErrorUnsupportedSetting;
5510                 }
5511             } else {
5512                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
5513                 client_set_fps = false;
5514             }
5515         } else {
5516             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
5517                     (int)config->nPortIndex);
5518             ret = OMX_ErrorBadPortIndex;
5519         }
5520 
5521         return ret;
5522     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
5523         OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
5524             (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
5525         struct v4l2_control control;
5526         DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
5527         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
5528 
5529         switch (config->eDecodeType) {
5530             case OMX_QCOM_PictypeDecode_I:
5531                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I;
5532                 break;
5533             case OMX_QCOM_PictypeDecode_IPB:
5534             default:
5535                 control.value = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I|
5536                                   V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P|
5537                                   V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B);
5538                 break;
5539         }
5540 
5541         ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
5542                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
5543         if (ret)
5544             DEBUG_PRINT_ERROR("Failed to set picture type decode");
5545 
5546         return ret;
5547     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
5548         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
5549         DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
5550 
5551         struct v4l2_control control;
5552 
5553         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
5554         if (priority->nU32 == 0)
5555             control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
5556         else
5557             control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
5558 
5559         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5560             DEBUG_PRINT_ERROR("Failed to set Priority");
5561             ret = OMX_ErrorUnsupportedSetting;
5562         }
5563         return ret;
5564     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
5565         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
5566         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
5567 
5568         struct v4l2_control control;
5569 
5570         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
5571         control.value = rate->nU32;
5572 
5573         if (rate->nU32 == QOMX_VIDEO_HIGH_PERF_OPERATING_MODE) {
5574             DEBUG_PRINT_LOW("Turbo mode requested");
5575             m_client_req_turbo_mode = true;
5576         } else {
5577             operating_frame_rate = rate->nU32 >> 16;
5578             m_client_req_turbo_mode = false;
5579             DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  operating_frame_rate);
5580         }
5581 
5582         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5583             ret = errno == EBUSY ? OMX_ErrorInsufficientResources :
5584                     OMX_ErrorUnsupportedSetting;
5585             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
5586                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
5587         }
5588         return ret;
5589 
5590     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
5591         VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5592         DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5593         if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
5594             enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, false, true);
5595         }
5596 
5597         print_debug_color_aspects(&(params->sAspects), "Set Config");
5598         memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
5599         return ret;
5600     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) {
5601         VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5602         DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5603         ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, false, true);
5604         if (ret != OMX_ErrorNone) {
5605             DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA");
5606             return ret;
5607         }
5608 
5609         print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR");
5610         memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams));
5611         return ret;
5612 
5613     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDR10PlusInfo) {
5614         VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
5615         if (!store_vp9_hdr10plusinfo((DescribeHDR10PlusInfoParams *)configData)) {
5616             DEBUG_PRINT_ERROR("Failed to set hdr10plus info");
5617         }
5618         return ret;
5619 
5620     } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
5621         VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5622 
5623         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5624                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5625         VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5626 
5627         return set_vendor_extension_config(ext);
5628     }
5629 
5630     return OMX_ErrorNotImplemented;
5631 }
5632 
5633 #define extn_equals(param, extn) (!strcmp(param, extn))
5634 
5635 /* ======================================================================
5636    FUNCTION
5637    omx_vdec::GetExtensionIndex
5638 
5639    DESCRIPTION
5640    OMX GetExtensionIndex method implementaion.  <TBD>
5641 
5642    PARAMETERS
5643    <TBD>.
5644 
5645    RETURN VALUE
5646    OMX Error None if everything successful.
5647 
5648    ========================================================================== */
5649 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
5650         OMX_IN OMX_STRING      paramName,
5651         OMX_OUT OMX_INDEXTYPE* indexType)
5652 {
5653     (void) hComp;
5654     if (m_state == OMX_StateInvalid) {
5655         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
5656         return OMX_ErrorInvalidState;
5657     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
5658         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
5659     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
5660         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
5661     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
5662         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
5663     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
5664         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
5665     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
5666         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
5667     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
5668         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
5669     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
5670         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
5671     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNOUTPUTCROP_EXTRADATA)) {
5672         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamOutputCropExtraData;
5673     }
5674 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
5675     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
5676         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
5677     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
5678         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
5679     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
5680         DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
5681         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
5682     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
5683         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
5684     }
5685 #if ALLOCATE_OUTPUT_NATIVEHANDLE
5686     else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
5687         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
5688     }
5689 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
5690 #endif
5691     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
5692         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
5693     }
5694 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5695     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
5696         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
5697     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
5698         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
5699     }
5700 #endif
5701 #ifdef FLEXYUV_SUPPORTED
5702     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
5703         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
5704     }
5705 #endif
5706     else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
5707         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
5708     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
5709         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
5710     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
5711         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
5712     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
5713         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
5714     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
5715         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
5716     } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
5717         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
5718     } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) {
5719         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo;
5720     } else if (extn_equals(paramName, "OMX.QTI.index.param.ClientConfiguredProfileLevel")) {
5721         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency;
5722     } else if (extn_equals(paramName, "OMX.google.android.index.describeHDR10PlusInfo")) {
5723         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDR10PlusInfo;
5724     }else {
5725         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
5726         return OMX_ErrorNotImplemented;
5727     }
5728     return OMX_ErrorNone;
5729 }
5730 
5731 /* ======================================================================
5732    FUNCTION
5733    omx_vdec::GetState
5734 
5735    DESCRIPTION
5736    Returns the state information back to the caller.<TBD>
5737 
5738    PARAMETERS
5739    <TBD>.
5740 
5741    RETURN VALUE
5742    Error None if everything is successful.
5743    ========================================================================== */
5744 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
5745         OMX_OUT OMX_STATETYPE* state)
5746 {
5747     (void) hComp;
5748     *state = m_state;
5749     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
5750     return OMX_ErrorNone;
5751 }
5752 
5753 /* ======================================================================
5754    FUNCTION
5755    omx_vdec::ComponentTunnelRequest
5756 
5757    DESCRIPTION
5758    OMX Component Tunnel Request method implementation. <TBD>
5759 
5760    PARAMETERS
5761    None.
5762 
5763    RETURN VALUE
5764    OMX Error None if everything successful.
5765 
5766    ========================================================================== */
5767 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
5768         OMX_IN OMX_U32                        port,
5769         OMX_IN OMX_HANDLETYPE        peerComponent,
5770         OMX_IN OMX_U32                    peerPort,
5771         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
5772 {
5773     (void) hComp;
5774     (void) port;
5775     (void) peerComponent;
5776     (void) peerPort;
5777     (void) tunnelSetup;
5778     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
5779     return OMX_ErrorNotImplemented;
5780 }
5781 
5782 
5783 
5784 /* ======================================================================
5785    FUNCTION
5786    omx_vdec::ion_map
5787 
5788    DESCRIPTION
5789    Map the memory and run the ioctl SYNC operations
5790    on ION fd with DMA_BUF_IOCTL_SYNC
5791 
5792    PARAMETERS
5793    fd    : ION fd
5794    len   : Lenth of the memory
5795 
5796    RETURN VALUE
5797    ERROR: mapped memory pointer
5798 
5799    ========================================================================== */
5800 char *omx_vdec::ion_map(int fd, int len)
5801 {
5802     char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
5803                                 MAP_SHARED, fd, 0);
5804     if (bufaddr != MAP_FAILED) {
5805 #ifdef USE_ION
5806     do_cache_operations(fd);
5807 #endif
5808     }
5809     return bufaddr;
5810 }
5811 
5812 /* ======================================================================
5813    FUNCTION
5814    omx_vdec::ion_unmap
5815 
5816    DESCRIPTION
5817    Unmap the memory
5818 
5819    PARAMETERS
5820    fd      : ION fd
5821    bufaddr : buffer address
5822    len     : Lenth of the memory
5823 
5824    RETURN VALUE
5825    OMX_Error*
5826 
5827    ========================================================================== */
5828 OMX_ERRORTYPE omx_vdec::ion_unmap(int fd, void *bufaddr, int len)
5829 {
5830 #ifdef USE_ION
5831     do_cache_operations(fd);
5832 #else
5833     (void)fd;
5834 #endif
5835     if (-1 == munmap(bufaddr, len)) {
5836         DEBUG_PRINT_ERROR("munmap failed.");
5837         return OMX_ErrorInsufficientResources;
5838     }
5839     return OMX_ErrorNone;
5840 }
5841 
5842 /* ======================================================================
5843    FUNCTION
5844    omx_vdec::UseOutputBuffer
5845 
5846    DESCRIPTION
5847    Helper function for Use buffer in the input pin
5848 
5849    PARAMETERS
5850    None.
5851 
5852    RETURN VALUE
5853    true/false
5854 
5855    ========================================================================== */
5856 OMX_ERRORTYPE omx_vdec::allocate_extradata()
5857 {
5858 #ifdef USE_ION
5859     if (drv_ctx.extradata_info.buffer_size) {
5860         if (drv_ctx.extradata_info.ion.data_fd >= 0) {
5861             free_extradata();
5862         }
5863 
5864         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
5865         // Decoder extradata is always uncached as buffer sizes are very small
5866         bool status = alloc_map_ion_memory(
5867                 drv_ctx.extradata_info.size, &drv_ctx.extradata_info.ion, 0);
5868         if (status == false) {
5869             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
5870             return OMX_ErrorInsufficientResources;
5871         }
5872         DEBUG_PRINT_HIGH("Allocated extradata size : %d fd: %d",
5873             drv_ctx.extradata_info.size, drv_ctx.extradata_info.ion.data_fd);
5874         drv_ctx.extradata_info.uaddr = ion_map(drv_ctx.extradata_info.ion.data_fd,
5875                                                drv_ctx.extradata_info.size);
5876         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
5877             DEBUG_PRINT_ERROR("Failed to map extradata memory");
5878             free_ion_memory(&drv_ctx.extradata_info.ion);
5879             return OMX_ErrorInsufficientResources;
5880         }
5881     }
5882 #endif
5883     return OMX_ErrorNone;
5884 }
5885 
5886 void omx_vdec::free_extradata()
5887 {
5888 #ifdef USE_ION
5889     if (drv_ctx.extradata_info.uaddr) {
5890         ion_unmap(drv_ctx.extradata_info.ion.data_fd,
5891                   (void *)drv_ctx.extradata_info.uaddr,
5892                   drv_ctx.extradata_info.ion.alloc_data.len);
5893         free_ion_memory(&drv_ctx.extradata_info.ion);
5894         drv_ctx.extradata_info.uaddr = NULL;
5895         drv_ctx.extradata_info.ion.data_fd = -1;
5896     }
5897 #endif
5898 }
5899 
5900 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
5901         OMX_IN OMX_HANDLETYPE            hComp,
5902         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5903         OMX_IN OMX_U32                   port,
5904         OMX_IN OMX_PTR                   appData,
5905         OMX_IN OMX_U32                   bytes,
5906         OMX_IN OMX_U8*                   buffer)
5907 {
5908     OMX_ERRORTYPE eRet = OMX_ErrorNone;
5909     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
5910     unsigned                         i= 0; // Temporary counter
5911     OMX_PTR privateAppData = NULL;
5912     private_handle_t *handle = NULL;
5913     OMX_U8 *buff = buffer;
5914     bool intermediate = client_buffers.is_color_conversion_enabled();
5915     (void) hComp;
5916     (void) port;
5917 
5918     if (!m_out_mem_ptr) {
5919         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers C2D(%d)",
5920                          client_buffers.is_color_conversion_enabled());
5921         eRet = allocate_output_headers();
5922         if (eRet == OMX_ErrorNone)
5923             eRet = allocate_extradata();
5924         output_use_buffer = true;
5925     }
5926 
5927     OMX_BUFFERHEADERTYPE  **omx_base_address =
5928         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
5929 
5930     if (eRet == OMX_ErrorNone) {
5931         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5932             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
5933                 break;
5934             }
5935         }
5936     }
5937 
5938     if (i >= drv_ctx.op_buf.actualcount) {
5939         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
5940         return OMX_ErrorInsufficientResources;
5941     }
5942 
5943     if (intermediate) {
5944         DEBUG_PRINT_HIGH("Use_op_buf:Allocating intermediate output. %d", i);
5945         OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
5946         eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
5947                                       port, appData,
5948                                       drv_ctx.op_buf.buffer_size,
5949                                       true, i);
5950     }
5951 
5952     if (eRet == OMX_ErrorNone && dynamic_buf_mode) {
5953         *bufferHdr = (m_out_mem_ptr + i );
5954         (*bufferHdr)->pBuffer = NULL;
5955         if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
5956             enum v4l2_buf_type buf_type;
5957             int rr = 0;
5958             DEBUG_PRINT_LOW("USE intermediate bufferSTREAMON(CAPTURE_MPLANE)");
5959             set_buffer_req(&drv_ctx.op_buf);
5960             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5961             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
5962                 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
5963                 return OMX_ErrorInsufficientResources;
5964             } else {
5965                 streaming[CAPTURE_PORT] = true;
5966                 DEBUG_PRINT_LOW("STREAMON Successful");
5967             }
5968         }
5969         BITMASK_SET(&m_out_bm_count,i);
5970         (*bufferHdr)->pAppPrivate = appData;
5971         (*bufferHdr)->pBuffer = buffer;
5972         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
5973         return eRet;
5974     }
5975 
5976     if (eRet == OMX_ErrorNone) {
5977 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
5978         if (m_enable_android_native_buffers) {
5979             if (m_use_android_native_buffers) {
5980                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
5981                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
5982                 handle = (private_handle_t *)nBuf->handle;
5983                 privateAppData = params->pAppPrivate;
5984             } else {
5985                 handle = (private_handle_t *)buff;
5986                 privateAppData = appData;
5987             }
5988             if (!handle) {
5989                 DEBUG_PRINT_ERROR("handle is invalid");
5990                 return OMX_ErrorBadParameter;
5991             }
5992 
5993             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
5994                 if (secure_mode && secure_scaling_to_non_secure_opb) {
5995                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
5996                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
5997                 } else {
5998                     DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
5999                             " expected %u, got %u",
6000                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
6001                     return OMX_ErrorBadParameter;
6002                 }
6003             }
6004 
6005             drv_ctx.op_buf.buffer_size = handle->size;
6006 
6007             if (!m_use_android_native_buffers) {
6008                 if (!secure_mode) {
6009                     buff = (OMX_U8*)ion_map(handle->fd, handle->size);
6010                     if (buff == MAP_FAILED) {
6011                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
6012                         return OMX_ErrorInsufficientResources;
6013                     }
6014                 }
6015             }
6016 #if defined(_ANDROID_ICS_)
6017             native_buffer[i].nativehandle = handle;
6018             native_buffer[i].privatehandle = handle;
6019 #endif
6020             if (!handle) {
6021                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
6022                 return OMX_ErrorBadParameter;
6023             }
6024             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
6025             drv_ctx.ptr_outputbuffer[i].offset = 0;
6026             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
6027             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
6028             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
6029         } else
6030 #endif
6031             if (!ouput_egl_buffers && !m_use_output_pmem) {
6032 #ifdef USE_GBM
6033                bool status = alloc_map_gbm_memory(
6034                        drv_ctx.video_resolution.frame_width,
6035                        drv_ctx.video_resolution.frame_height,
6036                        drv_ctx.gbm_device_fd,
6037                        &drv_ctx.op_buf_gbm_info[i],
6038                        secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
6039                 if (status == false) {
6040                     DEBUG_PRINT_ERROR("ION device fd is bad %d",
6041                                       (int) drv_ctx.op_buf_ion_info[i].data_fd);
6042                     return OMX_ErrorInsufficientResources;
6043                 }
6044                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
6045                                      drv_ctx.op_buf_gbm_info[i].bo_fd;
6046                 if (intermediate)
6047                    m_pmem_info[i].pmeta_fd = drv_ctx.op_buf_gbm_info[i].meta_fd;
6048 #elif defined USE_ION
6049                 bool status = alloc_map_ion_memory(
6050                         drv_ctx.op_buf.buffer_size, &drv_ctx.op_buf_ion_info[i],
6051                         secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
6052                 if (status == false) {
6053                     DEBUG_PRINT_ERROR("ION device fd is bad %d",
6054                                       (int) drv_ctx.op_buf_ion_info[i].data_fd);
6055                     return OMX_ErrorInsufficientResources;
6056                 }
6057                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
6058                                      drv_ctx.op_buf_ion_info[i].data_fd;
6059 #endif
6060                 if (!secure_mode) {
6061                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
6062                         (unsigned char *)ion_map(drv_ctx.ptr_outputbuffer[i].pmem_fd,
6063                                                  drv_ctx.op_buf.buffer_size);
6064                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
6065 #ifdef USE_GBM
6066                         free_gbm_memory(&drv_ctx.op_buf_gbm_info[i]);
6067 #elif defined USE_ION
6068                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
6069 #endif
6070                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
6071                         return OMX_ErrorInsufficientResources;
6072                     }
6073                 }
6074                 drv_ctx.ptr_outputbuffer[i].offset = 0;
6075                 privateAppData = appData;
6076             } else {
6077                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
6078                 if (!appData || !bytes ) {
6079                     if (!secure_mode && !buffer) {
6080                         DEBUG_PRINT_ERROR("Bad parameters for use buffer");
6081                         return OMX_ErrorBadParameter;
6082                     }
6083                 }
6084 
6085                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
6086                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
6087                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
6088                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
6089                         !pmem_list->nEntries ||
6090                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
6091                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
6092                     return OMX_ErrorBadParameter;
6093                 }
6094                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6095                     pmem_list->entryList->entry;
6096                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
6097                         pmem_info->pmem_fd);
6098                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
6099 #ifdef USE_GBM
6100                 if (intermediate)
6101                    m_pmem_info[i].pmeta_fd = pmem_info->pmeta_fd;
6102 #endif
6103                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
6104                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
6105                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
6106                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
6107                 privateAppData = appData;
6108             }
6109         if (intermediate) {
6110             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
6111             m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
6112             m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
6113             m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
6114             m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
6115         }
6116         *bufferHdr = (m_out_mem_ptr + i );
6117 
6118         if (secure_mode)
6119             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
6120 
6121         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
6122             enum v4l2_buf_type buf_type;
6123             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6124             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
6125                 return OMX_ErrorInsufficientResources;
6126             } else {
6127                 streaming[CAPTURE_PORT] = true;
6128                 DEBUG_PRINT_LOW("STREAMON Successful");
6129             }
6130         }
6131 
6132         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
6133         if (m_enable_android_native_buffers) {
6134             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
6135             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
6136         } else {
6137             (*bufferHdr)->pBuffer = buff;
6138         }
6139         (*bufferHdr)->pAppPrivate = privateAppData;
6140         BITMASK_SET(&m_out_bm_count,i);
6141     }
6142     return eRet;
6143 }
6144 
6145 OMX_ERRORTYPE omx_vdec::allocate_client_output_extradata_headers() {
6146     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6147     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
6148     int i = 0;
6149 
6150     if (!m_client_output_extradata_mem_ptr) {
6151         int nBufferCount       = 0;
6152 
6153         nBufferCount = m_client_out_extradata_info.getBufferCount();
6154         DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount);
6155 
6156         m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
6157 
6158         if (m_client_output_extradata_mem_ptr) {
6159             bufHdr          =  m_client_output_extradata_mem_ptr;
6160             for (i=0; i < nBufferCount; i++) {
6161                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
6162                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
6163                 // Set the values when we determine the right HxW param
6164                 bufHdr->nAllocLen          = 0;
6165                 bufHdr->nFilledLen         = 0;
6166                 bufHdr->pAppPrivate        = NULL;
6167                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_EXTRADATA_INDEX;
6168                 bufHdr->pBuffer            = NULL;
6169                 bufHdr->pOutputPortPrivate = NULL;
6170                 bufHdr++;
6171             }
6172         } else {
6173              DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
6174                     m_client_output_extradata_mem_ptr);
6175               eRet =  OMX_ErrorInsufficientResources;
6176         }
6177     }
6178     return eRet;
6179 }
6180 OMX_ERRORTYPE  omx_vdec::use_client_output_extradata_buffer(
6181         OMX_IN OMX_HANDLETYPE            hComp,
6182         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6183         OMX_IN OMX_U32                   port,
6184         OMX_IN OMX_PTR                   appData,
6185         OMX_IN OMX_U32                   bytes,
6186         OMX_IN OMX_U8*                   buffer)
6187 {
6188     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6189     unsigned i = 0; // Temporary counter
6190     unsigned buffer_count = m_client_out_extradata_info.getBufferCount();;
6191     OMX_U32 buffer_size = m_client_out_extradata_info.getSize();
6192     (void) hComp;
6193 
6194     if (port != OMX_CORE_OUTPUT_EXTRADATA_INDEX ||
6195             !client_extradata || bytes != buffer_size|| bufferHdr == NULL) {
6196         DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
6197             "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
6198             OMX_CORE_OUTPUT_EXTRADATA_INDEX, client_extradata, bytes, buffer_size, bufferHdr);
6199         eRet = OMX_ErrorBadParameter;
6200         return eRet;
6201     }
6202 
6203     if (!m_client_output_extradata_mem_ptr) {
6204         eRet = allocate_client_output_extradata_headers();
6205     }
6206 
6207     if (eRet == OMX_ErrorNone) {
6208         for (i = 0; i < buffer_count; i++) {
6209             if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) {
6210                 break;
6211             }
6212         }
6213     }
6214 
6215     if (i >= buffer_count) {
6216         DEBUG_PRINT_ERROR("Already using %d Extradata o/p buffers", buffer_count);
6217         eRet = OMX_ErrorInsufficientResources;
6218     }
6219 
6220     if (eRet == OMX_ErrorNone) {
6221         BITMASK_SET(&m_out_extradata_bm_count,i);
6222         *bufferHdr = (m_client_output_extradata_mem_ptr + i );
6223         (*bufferHdr)->pAppPrivate = appData;
6224         (*bufferHdr)->pBuffer = buffer;
6225         (*bufferHdr)->nAllocLen = bytes;
6226     }
6227 
6228     return eRet;
6229 }
6230 /* ======================================================================
6231    FUNCTION
6232    omx_vdec::use_input_heap_buffers
6233 
6234    DESCRIPTION
6235    OMX Use Buffer Heap allocation method implementation.
6236 
6237    PARAMETERS
6238    <TBD>.
6239 
6240    RETURN VALUE
6241    OMX Error None , if everything successful.
6242 
6243    ========================================================================== */
6244 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
6245         OMX_IN OMX_HANDLETYPE            hComp,
6246         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6247         OMX_IN OMX_U32                   port,
6248         OMX_IN OMX_PTR                   appData,
6249         OMX_IN OMX_U32                   bytes,
6250         OMX_IN OMX_U8*                   buffer)
6251 {
6252     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
6253     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6254 
6255     if (secure_mode) {
6256         DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
6257         return OMX_ErrorUndefined;
6258     }
6259 
6260     if (!m_inp_heap_ptr)
6261         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
6262             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6263                     drv_ctx.ip_buf.actualcount);
6264     if (!m_phdr_pmem_ptr)
6265         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
6266             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6267                     drv_ctx.ip_buf.actualcount);
6268     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
6269         DEBUG_PRINT_ERROR("Insufficent memory");
6270         eRet = OMX_ErrorInsufficientResources;
6271     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
6272         input_use_buffer = true;
6273         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
6274         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
6275         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
6276         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
6277         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
6278         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
6279         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
6280         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
6281         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
6282         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
6283                     (unsigned)NULL, (unsigned)NULL)) {
6284             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6285             return OMX_ErrorInsufficientResources;
6286         }
6287         m_in_alloc_cnt++;
6288     } else {
6289         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
6290         eRet = OMX_ErrorInsufficientResources;
6291     }
6292     return eRet;
6293 }
6294 
6295 /* ======================================================================
6296    FUNCTION
6297    omx_vdec::UseBuffer
6298 
6299    DESCRIPTION
6300    OMX Use Buffer method implementation.
6301 
6302    PARAMETERS
6303    <TBD>.
6304 
6305    RETURN VALUE
6306    OMX Error None , if everything successful.
6307 
6308    ========================================================================== */
6309 OMX_ERRORTYPE  omx_vdec::use_buffer(
6310         OMX_IN OMX_HANDLETYPE            hComp,
6311         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6312         OMX_IN OMX_U32                   port,
6313         OMX_IN OMX_PTR                   appData,
6314         OMX_IN OMX_U32                   bytes,
6315         OMX_IN OMX_U8*                   buffer)
6316 {
6317     OMX_ERRORTYPE error = OMX_ErrorNone;
6318 
6319     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
6320             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
6321             return OMX_ErrorBadParameter;
6322     }
6323     if (m_state == OMX_StateInvalid) {
6324         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
6325         return OMX_ErrorInvalidState;
6326     }
6327     if (port == OMX_CORE_INPUT_PORT_INDEX) {
6328         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
6329         // ensure that use-buffer was called for previous allocation.
6330         // Mix-and-match of useBuffer and allocateBuffer is not allowed
6331         if (m_inp_mem_ptr && !input_use_buffer) {
6332             DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
6333             return OMX_ErrorUndefined;
6334         }
6335         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
6336     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
6337         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
6338     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
6339         error = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
6340     } else {
6341         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
6342         error = OMX_ErrorBadPortIndex;
6343     }
6344     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
6345     if (error == OMX_ErrorNone) {
6346         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
6347             // Send the callback now
6348             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
6349             post_event(OMX_CommandStateSet,OMX_StateIdle,
6350                     OMX_COMPONENT_GENERATE_EVENT);
6351         }
6352         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
6353                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
6354             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
6355             post_event(OMX_CommandPortEnable,
6356                     OMX_CORE_INPUT_PORT_INDEX,
6357                     OMX_COMPONENT_GENERATE_EVENT);
6358         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
6359                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
6360             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
6361             post_event(OMX_CommandPortEnable,
6362                     OMX_CORE_OUTPUT_PORT_INDEX,
6363                     OMX_COMPONENT_GENERATE_EVENT);
6364         }
6365     }
6366     return error;
6367 }
6368 
6369 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
6370         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
6371 {
6372     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
6373         if (m_inp_heap_ptr[bufferindex].pBuffer)
6374             free(m_inp_heap_ptr[bufferindex].pBuffer);
6375         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
6376     }
6377     if (pmem_bufferHdr)
6378         free_input_buffer(pmem_bufferHdr);
6379     return OMX_ErrorNone;
6380 }
6381 
6382 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
6383 {
6384     unsigned int index = 0;
6385     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
6386         return OMX_ErrorBadParameter;
6387     }
6388     print_omx_buffer("free_input_buffer", bufferHdr);
6389 
6390     index = bufferHdr - m_inp_mem_ptr;
6391     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
6392 
6393     bufferHdr->pInputPortPrivate = NULL;
6394 
6395     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
6396         if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
6397             if (!secure_mode) {
6398                 ion_unmap(drv_ctx.ptr_inputbuffer[index].pmem_fd,
6399                           drv_ctx.ptr_inputbuffer[index].bufferaddr,
6400                           drv_ctx.ptr_inputbuffer[index].mmaped_size);
6401             }
6402 
6403             if (allocate_native_handle){
6404                 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
6405                 native_handle_close(nh);
6406                 native_handle_delete(nh);
6407             } else {
6408 #ifndef USE_ION
6409                 // Close fd for non-secure and secure non-native-handle case
6410                 close(drv_ctx.ptr_inputbuffer[index].pmem_fd);
6411 #endif
6412             }
6413             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
6414 
6415             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
6416                 free(m_desc_buffer_ptr[index].buf_addr);
6417                 m_desc_buffer_ptr[index].buf_addr = NULL;
6418                 m_desc_buffer_ptr[index].desc_data_size = 0;
6419             }
6420 #ifdef USE_ION
6421             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
6422 #endif
6423             m_in_alloc_cnt--;
6424         } else {
6425             DEBUG_PRINT_ERROR("Invalid input buffer fd %d", drv_ctx.ptr_inputbuffer[index].pmem_fd);
6426         }
6427     } else {
6428         DEBUG_PRINT_ERROR("Invalid input buffer index %d, drv_ctx.ptr_inputbuffer %p",
6429             index, drv_ctx.ptr_inputbuffer);
6430     }
6431 
6432     return OMX_ErrorNone;
6433 }
6434 
6435 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr,
6436                                            bool                 intermediate)
6437 {
6438     unsigned int index = 0;
6439 
6440     OMX_BUFFERHEADERTYPE  *omx_base_address =
6441              intermediate?m_intermediate_out_mem_ptr:m_out_mem_ptr;
6442     vdec_bufferpayload *omx_ptr_outputbuffer =
6443          intermediate?drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
6444     vdec_ion *omx_op_buf_ion_info =
6445         intermediate?drv_ctx.op_intermediate_buf_ion_info:drv_ctx.op_buf_ion_info;
6446 #ifdef USE_GBM
6447     vdec_gbm *omx_op_buf_gbm_info =
6448         intermediate?drv_ctx.op_intermediate_buf_gbm_info:drv_ctx.op_buf_gbm_info;
6449 #endif
6450     if (bufferHdr == NULL || omx_base_address == NULL) {
6451         return OMX_ErrorBadParameter;
6452     }
6453     print_omx_buffer("free_output_buffer", bufferHdr);
6454 
6455     index = bufferHdr - omx_base_address;
6456 
6457     if (index < drv_ctx.op_buf.actualcount
6458         && omx_ptr_outputbuffer) {
6459         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
6460                         omx_ptr_outputbuffer[index].bufferaddr);
6461 
6462         if (!dynamic_buf_mode) {
6463             if (streaming[CAPTURE_PORT] &&
6464                 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
6465                 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
6466                     DEBUG_PRINT_ERROR("STREAMOFF(CAPTURE_MPLANE) Failed");
6467                 } else {
6468                     DEBUG_PRINT_LOW("STREAMOFF(CAPTURE_MPLANE) Successful");
6469                 }
6470             }
6471 #ifdef _ANDROID_
6472             if (m_enable_android_native_buffers) {
6473                 if (!secure_mode) {
6474                     if (omx_ptr_outputbuffer[index].pmem_fd > 0) {
6475                         ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6476                                   omx_ptr_outputbuffer[index].bufferaddr,
6477                                   omx_ptr_outputbuffer[index].mmaped_size);
6478                     }
6479                 }
6480             } else {
6481 #endif
6482                 if (omx_ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
6483                     if (!secure_mode) {
6484                         ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6485                                   omx_ptr_outputbuffer[index].bufferaddr,
6486                                   omx_ptr_outputbuffer[index].mmaped_size);
6487                         omx_ptr_outputbuffer[index].bufferaddr = NULL;
6488                         omx_ptr_outputbuffer[index].mmaped_size = 0;
6489                     }
6490 #ifdef USE_GBM
6491                     free_gbm_memory(&omx_op_buf_gbm_info[index]);
6492 #elif defined USE_ION
6493                     free_ion_memory(&omx_op_buf_ion_info[index]);
6494 #endif
6495 
6496                     omx_ptr_outputbuffer[index].pmem_fd = -1;
6497                 }
6498 #ifdef _ANDROID_
6499             }
6500 #endif
6501         } //!dynamic_buf_mode
6502         if (intermediate == false) {
6503             OMX_BUFFERHEADERTYPE *tempBufHdr = m_intermediate_out_mem_ptr + index;
6504             if (client_buffers.is_color_conversion_enabled() &&
6505                 free_output_buffer(tempBufHdr, true) != OMX_ErrorNone) {
6506                 return OMX_ErrorBadParameter;
6507             }
6508 
6509             if (release_output_done()) {
6510             DEBUG_PRINT_HIGH("All output buffers released, free extradata");
6511             free_extradata();
6512             }
6513         }
6514     }
6515 
6516     return OMX_ErrorNone;
6517 }
6518 
6519 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
6520         OMX_BUFFERHEADERTYPE **bufferHdr,
6521         OMX_U32              port,
6522         OMX_PTR              appData,
6523         OMX_U32              bytes)
6524 {
6525     OMX_BUFFERHEADERTYPE *input = NULL;
6526     unsigned char *buf_addr = NULL;
6527     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6528     unsigned   i = 0;
6529 
6530     /* Sanity Check*/
6531     if (bufferHdr == NULL) {
6532         return OMX_ErrorBadParameter;
6533     }
6534 
6535     if (m_inp_heap_ptr == NULL) {
6536         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
6537                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6538                          drv_ctx.ip_buf.actualcount);
6539         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
6540                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6541                           drv_ctx.ip_buf.actualcount);
6542 
6543         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
6544             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
6545             return OMX_ErrorInsufficientResources;
6546         }
6547     }
6548 
6549     /*Find a Free index*/
6550     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6551         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
6552             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6553             break;
6554         }
6555     }
6556 
6557     if (i < drv_ctx.ip_buf.actualcount) {
6558         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
6559 
6560         if (buf_addr == NULL) {
6561             return OMX_ErrorInsufficientResources;
6562         }
6563 
6564         *bufferHdr = (m_inp_heap_ptr + i);
6565         input = *bufferHdr;
6566         BITMASK_SET(&m_heap_inp_bm_count,i);
6567 
6568         input->pBuffer           = (OMX_U8 *)buf_addr;
6569         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
6570         input->nVersion.nVersion = OMX_SPEC_VERSION;
6571         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
6572         input->pAppPrivate       = appData;
6573         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
6574         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
6575         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
6576         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
6577         /*Add the Buffers to freeq*/
6578         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
6579                     (unsigned)NULL, (unsigned)NULL)) {
6580             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6581             return OMX_ErrorInsufficientResources;
6582         }
6583     } else {
6584         return OMX_ErrorBadParameter;
6585     }
6586 
6587     return eRet;
6588 }
6589 
6590 
6591 /* ======================================================================
6592    FUNCTION
6593    omx_vdec::AllocateInputBuffer
6594 
6595    DESCRIPTION
6596    Helper function for allocate buffer in the input pin
6597 
6598    PARAMETERS
6599    None.
6600 
6601    RETURN VALUE
6602    true/false
6603 
6604    ========================================================================== */
6605 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
6606         OMX_IN OMX_HANDLETYPE            hComp,
6607         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6608         OMX_IN OMX_U32                   port,
6609         OMX_IN OMX_PTR                   appData,
6610         OMX_IN OMX_U32                   bytes)
6611 {
6612     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6613     OMX_BUFFERHEADERTYPE *input = NULL;
6614     unsigned   i = 0;
6615     unsigned char *buf_addr = NULL;
6616     int pmem_fd = -1, ret = 0;
6617     unsigned int align_size = 0;
6618 
6619     (void) hComp;
6620     (void) port;
6621 
6622 
6623     if (bytes != drv_ctx.ip_buf.buffer_size) {
6624         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
6625                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
6626         return OMX_ErrorBadParameter;
6627     }
6628 
6629     if (!m_inp_mem_ptr) {
6630         /* Currently buffer reqs is being set only in set port defn                          */
6631         /* Client need not do set port definition if he sees enough buffers in get port defn */
6632         /* In such cases we need to do a set buffer reqs to driver. Doing it here            */
6633         struct v4l2_requestbuffers bufreq;
6634 
6635         DEBUG_PRINT_HIGH("Calling REQBUFS in %s ",__FUNCTION__);
6636         bufreq.memory = V4L2_MEMORY_USERPTR;
6637         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6638         bufreq.count = drv_ctx.ip_buf.actualcount;
6639         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
6640         if (ret) {
6641             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
6642             /*TODO: How to handle this case */
6643             eRet = OMX_ErrorInsufficientResources;
6644         } else if (bufreq.count != drv_ctx.ip_buf.actualcount) {
6645             DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d",
6646                 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count);
6647             eRet = OMX_ErrorInsufficientResources;
6648         }
6649 
6650         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
6651                 drv_ctx.ip_buf.actualcount,
6652                 (unsigned int)drv_ctx.ip_buf.buffer_size);
6653 
6654         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
6655                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
6656 
6657         if (m_inp_mem_ptr == NULL) {
6658             return OMX_ErrorInsufficientResources;
6659         }
6660 
6661         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
6662                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
6663 
6664         if (drv_ctx.ptr_inputbuffer == NULL) {
6665             return OMX_ErrorInsufficientResources;
6666         }
6667 #ifdef USE_ION
6668         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
6669                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
6670 
6671         if (drv_ctx.ip_buf_ion_info == NULL) {
6672             return OMX_ErrorInsufficientResources;
6673         }
6674 #endif
6675 
6676         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
6677             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
6678 #ifdef USE_ION
6679             drv_ctx.ip_buf_ion_info[i].data_fd = -1;
6680             drv_ctx.ip_buf_ion_info[i].dev_fd = -1;
6681 #endif
6682         }
6683     }
6684 
6685     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6686         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6687             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6688             break;
6689         }
6690     }
6691 
6692     if (i < drv_ctx.ip_buf.actualcount) {
6693         int rc;
6694         DEBUG_PRINT_LOW("Allocate input Buffer");
6695 #ifdef USE_ION
6696         align_size = drv_ctx.ip_buf.buffer_size + 512;
6697         align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
6698         // Input buffers are cached to make parsing faster
6699         bool status = alloc_map_ion_memory(
6700                 align_size, &drv_ctx.ip_buf_ion_info[i],
6701                 secure_mode ? SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
6702         if (status == false) {
6703             return OMX_ErrorInsufficientResources;
6704         }
6705         pmem_fd = drv_ctx.ip_buf_ion_info[i].data_fd;
6706 #endif
6707         if (!secure_mode) {
6708             buf_addr = (unsigned char *)ion_map(pmem_fd, drv_ctx.ip_buf.buffer_size);
6709             if (buf_addr == MAP_FAILED) {
6710 #ifdef USE_ION
6711                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
6712 #endif
6713                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
6714                 return OMX_ErrorInsufficientResources;
6715             }
6716         }
6717         *bufferHdr = (m_inp_mem_ptr + i);
6718         if (secure_mode)
6719             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
6720         else
6721             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
6722         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
6723         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
6724         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
6725         drv_ctx.ptr_inputbuffer [i].offset = 0;
6726 
6727         input = *bufferHdr;
6728         BITMASK_SET(&m_inp_bm_count,i);
6729         if (allocate_native_handle) {
6730             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
6731             if (!nh) {
6732                 DEBUG_PRINT_ERROR("Native handle create failed");
6733                 return OMX_ErrorInsufficientResources;
6734             }
6735             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
6736             input->pBuffer = (OMX_U8 *)nh;
6737         } else if (secure_mode || m_input_pass_buffer_fd) {
6738             /*Legacy method, pass ion fd stashed directly in pBuffer*/
6739             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
6740         } else {
6741             input->pBuffer           = (OMX_U8 *)buf_addr;
6742         }
6743         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
6744         input->nVersion.nVersion = OMX_SPEC_VERSION;
6745         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
6746         input->pAppPrivate       = appData;
6747         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
6748         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
6749 
6750         if (drv_ctx.disable_dmx) {
6751             eRet = allocate_desc_buffer(i);
6752         }
6753     } else {
6754         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
6755         eRet = OMX_ErrorInsufficientResources;
6756     }
6757 
6758     if (eRet == OMX_ErrorNone)
6759         DEBUG_PRINT_HIGH("Allocate_input_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d",
6760             i, input, input->pBuffer, input->nAllocLen,
6761             input->nOffset, drv_ctx.ptr_inputbuffer[i].pmem_fd);
6762 
6763     return eRet;
6764 }
6765 
6766 
6767 /* ======================================================================
6768    FUNCTION
6769    omx_vdec::AllocateOutputBuffer
6770 
6771    DESCRIPTION
6772    Helper fn for AllocateBuffer in the output pin
6773 
6774    PARAMETERS
6775    <TBD>.
6776 
6777    RETURN VALUE
6778    OMX Error None if everything went well.
6779 
6780    ========================================================================== */
6781 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
6782         OMX_IN OMX_HANDLETYPE            hComp,
6783         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6784         OMX_IN OMX_U32                   port,
6785         OMX_IN OMX_PTR                   appData,
6786         OMX_IN OMX_U32                   bytes,
6787         OMX_IN bool                      intermediate,
6788         OMX_IN int                       index)
6789 {
6790     (void)hComp;
6791     (void)port;
6792 
6793     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6794     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
6795     unsigned                         i= 0; // Temporary counter
6796 #ifdef USE_ION
6797     struct ion_allocation_data ion_alloc_data;
6798 #endif
6799     OMX_BUFFERHEADERTYPE  **omx_base_address =
6800         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
6801 
6802     vdec_bufferpayload **omx_ptr_outputbuffer =
6803         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
6804     vdec_output_frameinfo **omx_ptr_respbuffer =
6805         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
6806     vdec_ion **omx_op_buf_ion_info =
6807         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
6808 #ifdef USE_GBM
6809     vdec_gbm **omx_op_buf_gbm_info =
6810         intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
6811 #endif
6812 
6813     if (!*omx_base_address) {
6814         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
6815                 drv_ctx.op_buf.actualcount,
6816                 (unsigned int)drv_ctx.op_buf.buffer_size);
6817         int nBufHdrSize        = 0;
6818         int nPlatformEntrySize = 0;
6819         int nPlatformListSize  = 0;
6820         int nPMEMInfoSize = 0;
6821 
6822         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
6823         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
6824         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
6825 
6826         nBufHdrSize        = drv_ctx.op_buf.actualcount *
6827             sizeof(OMX_BUFFERHEADERTYPE);
6828         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
6829             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
6830         nPlatformListSize  = drv_ctx.op_buf.actualcount *
6831             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
6832         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
6833             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
6834 
6835         *omx_base_address = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
6836         // Alloc mem for platform specific info
6837         char *pPtr=NULL;
6838         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
6839                 nPMEMInfoSize,1);
6840         *omx_ptr_outputbuffer = (struct vdec_bufferpayload *)    \
6841                        calloc (sizeof(struct vdec_bufferpayload),
6842                                drv_ctx.op_buf.actualcount);
6843         *omx_ptr_respbuffer = (struct vdec_output_frameinfo  *)\
6844                      calloc (sizeof (struct vdec_output_frameinfo),
6845                              drv_ctx.op_buf.actualcount);
6846         if (!*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
6847             DEBUG_PRINT_ERROR("Failed to alloc outputbuffer or respbuffer ");
6848             free(pPtr);
6849             return OMX_ErrorInsufficientResources;
6850         }
6851 
6852 #ifdef USE_GBM
6853         *omx_op_buf_gbm_info = (struct vdec_gbm *)\
6854                       calloc (sizeof(struct vdec_gbm),
6855                       drv_ctx.op_buf.actualcount);
6856         if (!*omx_op_buf_gbm_info) {
6857                  DEBUG_PRINT_ERROR("Failed to alloc op_buf_gbm_info");
6858             return OMX_ErrorInsufficientResources;
6859         }
6860         drv_ctx.gbm_device_fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
6861         if (drv_ctx.gbm_device_fd < 0) {
6862            DEBUG_PRINT_ERROR("opening dri device for gbm failed with fd = %d", drv_ctx.gbm_device_fd);
6863            return OMX_ErrorInsufficientResources;
6864         }
6865 #elif defined USE_ION
6866         *omx_op_buf_ion_info = (struct vdec_ion *)\
6867                       calloc (sizeof(struct vdec_ion),
6868                               drv_ctx.op_buf.actualcount);
6869         if (!*omx_op_buf_ion_info) {
6870             DEBUG_PRINT_ERROR("Failed to alloc op_buf_ion_info");
6871             return OMX_ErrorInsufficientResources;
6872         }
6873 #endif
6874 
6875         if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
6876             && *omx_ptr_respbuffer) {
6877             bufHdr          =  *omx_base_address;
6878             if (m_platform_list) {
6879                 free(m_platform_list);
6880             }
6881             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
6882             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
6883                 (((char *) m_platform_list)  + nPlatformListSize);
6884             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6885                 (((char *) m_platform_entry) + nPlatformEntrySize);
6886             pPlatformList   = m_platform_list;
6887             pPlatformEntry  = m_platform_entry;
6888             pPMEMInfo       = m_pmem_info;
6889 
6890             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
6891 
6892             // Settting the entire storage nicely
6893             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
6894                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
6895                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
6896                 // Set the values when we determine the right HxW param
6897                 bufHdr->nAllocLen          = bytes;
6898                 bufHdr->nFilledLen         = 0;
6899                 bufHdr->pAppPrivate        = appData;
6900                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
6901                 // Platform specific PMEM Information
6902                 // Initialize the Platform Entry
6903                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
6904                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6905                 pPlatformEntry->entry      = pPMEMInfo;
6906                 // Initialize the Platform List
6907                 pPlatformList->nEntries    = 1;
6908                 pPlatformList->entryList   = pPlatformEntry;
6909                 // Keep pBuffer NULL till vdec is opened
6910                 bufHdr->pBuffer            = NULL;
6911                 bufHdr->nOffset            = 0;
6912                 pPMEMInfo->offset = 0;
6913                 pPMEMInfo->pmem_fd = -1;
6914                 bufHdr->pPlatformPrivate = pPlatformList;
6915                 /*Create a mapping between buffers*/
6916                 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
6917                 (*omx_ptr_respbuffer)[i].client_data = (void *) \
6918                     &(*omx_ptr_outputbuffer)[i];
6919                 // Move the buffer and buffer header pointers
6920                 bufHdr++;
6921                 pPMEMInfo++;
6922                 pPlatformEntry++;
6923                 pPlatformList++;
6924             }
6925         } else {
6926             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
6927                               *omx_base_address, pPtr);
6928             if (*omx_base_address) {
6929                 free(*omx_base_address);
6930                 *omx_base_address = NULL;
6931             }
6932             if (pPtr) {
6933                 free(pPtr);
6934                 pPtr = NULL;
6935             }
6936             if (*omx_ptr_outputbuffer) {
6937                 free(*omx_ptr_outputbuffer);
6938                 *omx_ptr_outputbuffer = NULL;
6939             }
6940             if (*omx_ptr_respbuffer) {
6941                 free(*omx_ptr_respbuffer);
6942                 *omx_ptr_respbuffer = NULL;
6943             }
6944 #ifdef USE_GBM
6945       if(drv_ctx.gbm_device_fd >= 0) {
6946        DEBUG_PRINT_LOW("Close gbm device");
6947        close(drv_ctx.gbm_device_fd);
6948        drv_ctx.gbm_device_fd = -1;
6949     }
6950             if (*omx_op_buf_gbm_info) {
6951                 DEBUG_PRINT_LOW("Free o/p gbm context");
6952                 free(*omx_op_buf_gbm_info);
6953                 *omx_op_buf_gbm_info = NULL;
6954             }
6955 #elif defined USE_ION
6956             if (*omx_op_buf_ion_info) {
6957                 DEBUG_PRINT_LOW("Free o/p ion context");
6958                 free(*omx_op_buf_ion_info);
6959                 *omx_op_buf_ion_info = NULL;
6960             }
6961 #endif
6962             eRet =  OMX_ErrorInsufficientResources;
6963         }
6964         if (eRet == OMX_ErrorNone)
6965             eRet = allocate_extradata();
6966     }
6967 
6968     if (intermediate == true && index != -1) {
6969         i = index;
6970     } else {
6971         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
6972             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
6973                 break;
6974             }
6975         }
6976     }
6977 
6978     if (eRet == OMX_ErrorNone) {
6979         if (i < drv_ctx.op_buf.actualcount) {
6980             int rc;
6981             int pmem_fd = -1;
6982             int fd = -1;
6983             unsigned char *pmem_baseaddress = NULL;
6984 #ifdef USE_GBM
6985             int pmeta_fd = -1;
6986             // Allocate output buffers as cached to improve performance of software-reading
6987             // of the YUVs. Output buffers are cache-invalidated in driver.
6988             // If color-conversion is involved, Only the C2D output buffers are cached, no
6989             // need to cache the decoder's output buffers
6990             int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
6991             bool status = alloc_map_gbm_memory(
6992                                drv_ctx.video_resolution.frame_width,
6993                                drv_ctx.video_resolution.frame_height,
6994                                drv_ctx.gbm_device_fd,
6995                                &(*omx_op_buf_gbm_info)[i],
6996                                (secure_mode && !secure_scaling_to_non_secure_opb) ?
6997                                       SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
6998             if (status == false) {
6999                 return OMX_ErrorInsufficientResources;
7000             }
7001             pmem_fd = (*omx_op_buf_gbm_info)[i].bo_fd;
7002             pmeta_fd = (*omx_op_buf_gbm_info)[i].meta_fd;
7003 #elif defined USE_ION
7004             // Allocate output buffers as cached to improve performance of software-reading
7005             // of the YUVs. Output buffers are cache-invalidated in driver.
7006             // If color-conversion is involved, Only the C2D output buffers are cached, no
7007             // need to cache the decoder's output buffers
7008             int cache_flag = ION_FLAG_CACHED;
7009             if (intermediate == true && client_buffers.is_color_conversion_enabled()) {
7010                 cache_flag = 0;
7011             }
7012             bool status = alloc_map_ion_memory(drv_ctx.op_buf.buffer_size,
7013                                                &(*omx_op_buf_ion_info)[i],
7014                     (secure_mode && !secure_scaling_to_non_secure_opb) ?
7015                     SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
7016             if (status == false) {
7017                 return OMX_ErrorInsufficientResources;
7018             }
7019             pmem_fd = (*omx_op_buf_ion_info)[i].data_fd;
7020 #endif
7021             if (!secure_mode) {
7022                 pmem_baseaddress = (unsigned char *)ion_map(pmem_fd, drv_ctx.op_buf.buffer_size);
7023                 if (pmem_baseaddress == MAP_FAILED) {
7024                     DEBUG_PRINT_ERROR("MMAP failed for Size %u",
7025                             (unsigned int)drv_ctx.op_buf.buffer_size);
7026 #ifdef USE_GBM
7027                     free_gbm_memory(&(*omx_op_buf_gbm_info)[i]);
7028 #elif defined USE_ION
7029                     free_ion_memory(&(*omx_op_buf_ion_info)[i]);
7030 #endif
7031                     return OMX_ErrorInsufficientResources;
7032                 }
7033             }
7034             (*omx_ptr_outputbuffer)[i].pmem_fd = pmem_fd;
7035 #ifdef USE_GBM
7036             m_pmem_info[i].pmeta_fd = pmeta_fd;
7037 #endif
7038             (*omx_ptr_outputbuffer)[i].offset = 0;
7039             (*omx_ptr_outputbuffer)[i].bufferaddr = pmem_baseaddress;
7040             (*omx_ptr_outputbuffer)[i].mmaped_size = drv_ctx.op_buf.buffer_size;
7041             (*omx_ptr_outputbuffer)[i].buffer_len = drv_ctx.op_buf.buffer_size;
7042             m_pmem_info[i].pmem_fd = pmem_fd;
7043             m_pmem_info[i].size = (*omx_ptr_outputbuffer)[i].buffer_len;
7044             m_pmem_info[i].mapped_size = (*omx_ptr_outputbuffer)[i].mmaped_size;
7045             m_pmem_info[i].buffer = (*omx_ptr_outputbuffer)[i].bufferaddr;
7046             m_pmem_info[i].offset = (*omx_ptr_outputbuffer)[i].offset;
7047 
7048             *bufferHdr = (*omx_base_address + i );
7049             if (secure_mode) {
7050 #ifdef USE_GBM
7051                 (*omx_ptr_outputbuffer)[i].bufferaddr =
7052                     (OMX_U8 *)(intptr_t)(*omx_op_buf_gbm_info)[i].bo_fd;
7053 #elif defined USE_ION
7054                 (*omx_ptr_outputbuffer)[i].bufferaddr =
7055                     (OMX_U8 *)(intptr_t)(*omx_op_buf_ion_info)[i].data_fd;
7056 #endif
7057             }
7058             if (intermediate == false &&
7059                 client_buffers.is_color_conversion_enabled()) {
7060                 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
7061                 eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
7062                                               port, appData,
7063                                               drv_ctx.op_buf.buffer_size,
7064                                               true, i);
7065             }
7066             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
7067                 enum v4l2_buf_type buf_type;
7068 
7069                 set_buffer_req(&drv_ctx.op_buf);
7070                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7071                 if (!client_buffers.is_color_conversion_enabled() ||
7072                     (client_buffers.is_color_conversion_enabled() && intermediate == true)) {
7073                     rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7074                     if (rc) {
7075                         DEBUG_PRINT_ERROR("STREAMON(CAPTURE_MPLANE) Failed");
7076                         return OMX_ErrorInsufficientResources;
7077                     } else {
7078                         streaming[CAPTURE_PORT] = true;
7079                         DEBUG_PRINT_LOW("STREAMON(CAPTURE_MPLANE) Successful");
7080                     }
7081                 }
7082             }
7083 
7084             (*bufferHdr)->pBuffer = (OMX_U8*)(*omx_ptr_outputbuffer)[i].bufferaddr;
7085             (*bufferHdr)->pAppPrivate = appData;
7086             BITMASK_SET(&m_out_bm_count,i);
7087         } else {
7088             DEBUG_PRINT_ERROR("Faile to allocate output buffer (%d) maxcount %d",
7089                 i, drv_ctx.op_buf.actualcount);
7090             eRet = OMX_ErrorInsufficientResources;
7091         }
7092     }
7093 
7094     if (eRet == OMX_ErrorNone)
7095         DEBUG_PRINT_HIGH("Allocate_output_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d intermediate %d",
7096                          i, (*bufferHdr), (*bufferHdr)->pBuffer, (*bufferHdr)->nAllocLen,
7097                          (*bufferHdr)->nOffset, (*omx_ptr_outputbuffer)[i].pmem_fd,
7098                          intermediate);
7099     return eRet;
7100 }
7101 
7102 
7103 // AllocateBuffer  -- API Call
7104 /* ======================================================================
7105    FUNCTION
7106    omx_vdec::AllocateBuffer
7107 
7108    DESCRIPTION
7109    Returns zero if all the buffers released..
7110 
7111    PARAMETERS
7112    None.
7113 
7114    RETURN VALUE
7115    true/false
7116 
7117    ========================================================================== */
7118 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
7119         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
7120         OMX_IN OMX_U32                        port,
7121         OMX_IN OMX_PTR                     appData,
7122         OMX_IN OMX_U32                       bytes)
7123 {
7124     unsigned i = 0;
7125     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
7126 
7127     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
7128     if (m_state == OMX_StateInvalid) {
7129         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
7130         return OMX_ErrorInvalidState;
7131     }
7132 
7133     if (port == OMX_CORE_INPUT_PORT_INDEX) {
7134         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
7135         // ensure that use-buffer was never called.
7136         // Mix-and-match of useBuffer and allocateBuffer is not allowed
7137         if (m_inp_mem_ptr && input_use_buffer) {
7138             DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
7139             return OMX_ErrorUndefined;
7140         }
7141         if (arbitrary_bytes) {
7142             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
7143         } else {
7144             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
7145         }
7146     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7147         if (output_use_buffer) {
7148             DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
7149             return OMX_ErrorBadParameter;
7150         }
7151         eRet = allocate_output_buffer(hComp, bufferHdr, port, appData, bytes);
7152     } else {
7153         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
7154         eRet = OMX_ErrorBadPortIndex;
7155     }
7156     if (eRet == OMX_ErrorNone) {
7157         if (allocate_done()) {
7158             DEBUG_PRINT_HIGH("Allocated all buffers on port %d", port);
7159             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
7160                 // Send the callback now
7161                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
7162                 post_event(OMX_CommandStateSet,OMX_StateIdle,
7163                         OMX_COMPONENT_GENERATE_EVENT);
7164             }
7165         }
7166         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
7167             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
7168                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
7169                 post_event(OMX_CommandPortEnable,
7170                         OMX_CORE_INPUT_PORT_INDEX,
7171                         OMX_COMPONENT_GENERATE_EVENT);
7172             }
7173         }
7174         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
7175             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
7176                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
7177                 post_event(OMX_CommandPortEnable,
7178                         OMX_CORE_OUTPUT_PORT_INDEX,
7179                         OMX_COMPONENT_GENERATE_EVENT);
7180             }
7181         }
7182     }
7183     return eRet;
7184 }
7185 
7186 // Free Buffer - API call
7187 /* ======================================================================
7188    FUNCTION
7189    omx_vdec::FreeBuffer
7190 
7191    DESCRIPTION
7192 
7193    PARAMETERS
7194    None.
7195 
7196    RETURN VALUE
7197    true/false
7198 
7199    ========================================================================== */
7200 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
7201         OMX_IN OMX_U32                 port,
7202         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7203 {
7204     OMX_ERRORTYPE eRet = OMX_ErrorNone;
7205     unsigned int nPortIndex;
7206     (void) hComp;
7207 
7208     auto_lock l(buf_lock);
7209     if (m_state == OMX_StateIdle &&
7210             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7211         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
7212     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
7213             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
7214         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
7215     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
7216                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
7217             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
7218              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
7219         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
7220     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
7221         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
7222         post_event(OMX_EventError,
7223                 OMX_ErrorPortUnpopulated,
7224                 OMX_COMPONENT_GENERATE_EVENT);
7225         m_buffer_error = true;
7226         return OMX_ErrorIncorrectStateOperation;
7227     } else if (m_state != OMX_StateInvalid) {
7228         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
7229         post_event(OMX_EventError,
7230                 OMX_ErrorPortUnpopulated,
7231                 OMX_COMPONENT_GENERATE_EVENT);
7232     }
7233 
7234     if (port == OMX_CORE_INPUT_PORT_INDEX) {
7235         /*Check if arbitrary bytes*/
7236         if (!arbitrary_bytes && !input_use_buffer)
7237             nPortIndex = buffer - m_inp_mem_ptr;
7238         else
7239             nPortIndex = buffer - m_inp_heap_ptr;
7240 
7241         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
7242         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
7243                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
7244             // Clear the bit associated with it.
7245             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
7246             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
7247             if (input_use_buffer == true) {
7248 
7249                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
7250                 if (m_phdr_pmem_ptr)
7251                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
7252             } else {
7253                 if (arbitrary_bytes) {
7254                     if (m_phdr_pmem_ptr)
7255                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
7256                     else
7257                         free_input_buffer(nPortIndex,NULL);
7258                 } else
7259                     free_input_buffer(buffer);
7260             }
7261             m_inp_bPopulated = OMX_FALSE;
7262             /*Free the Buffer Header*/
7263             if (release_input_done()) {
7264                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
7265                 free_input_buffer_header();
7266             }
7267         } else {
7268             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
7269             eRet = OMX_ErrorBadPortIndex;
7270         }
7271 
7272         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
7273                 && release_input_done()) {
7274             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7275             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
7276             post_event(OMX_CommandPortDisable,
7277                     OMX_CORE_INPUT_PORT_INDEX,
7278                     OMX_COMPONENT_GENERATE_EVENT);
7279         }
7280     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7281         // check if the buffer is valid
7282         OMX_BUFFERHEADERTYPE  *omx_base_address =
7283             client_buffers.is_color_conversion_enabled()?
7284             m_intermediate_out_mem_ptr:m_out_mem_ptr;
7285         nPortIndex = buffer - m_out_mem_ptr;
7286         if (nPortIndex < drv_ctx.op_buf.actualcount &&
7287                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
7288             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
7289             // Clear the bit associated with it.
7290             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
7291             m_out_bPopulated = OMX_FALSE;
7292             free_output_buffer (buffer);
7293 
7294             if (release_output_done()) {
7295                 DEBUG_PRINT_HIGH("All output buffers released.");
7296                 free_output_buffer_header();
7297             }
7298         } else {
7299             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
7300             eRet = OMX_ErrorBadPortIndex;
7301         }
7302         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
7303                 && release_output_done()) {
7304             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7305             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
7306 #ifdef _ANDROID_ICS_
7307             if (m_enable_android_native_buffers) {
7308                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
7309                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
7310             }
7311 #endif
7312 
7313             post_event(OMX_CommandPortDisable,
7314                     OMX_CORE_OUTPUT_PORT_INDEX,
7315                     OMX_COMPONENT_GENERATE_EVENT);
7316         }
7317     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
7318         nPortIndex = buffer - m_client_output_extradata_mem_ptr;
7319         DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
7320 
7321         BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
7322 
7323         if (release_output_extradata_done()) {
7324             free_output_extradata_buffer_header();
7325         }
7326     } else {
7327         eRet = OMX_ErrorBadPortIndex;
7328     }
7329     if ((eRet == OMX_ErrorNone) &&
7330             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7331         if (release_done()) {
7332             /*
7333              * Reset buffer requirements here to ensure setting buffer requirement
7334              * when component move to executing state from loaded state via idle.
7335              */
7336             drv_ctx.op_buf.buffer_size = 0;
7337             drv_ctx.op_buf.actualcount = 0;
7338 
7339             // Send the callback now
7340             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
7341             post_event(OMX_CommandStateSet, OMX_StateLoaded,
7342                     OMX_COMPONENT_GENERATE_EVENT);
7343             m_buffer_error = false;
7344         }
7345     }
7346     return eRet;
7347 }
7348 
7349 
7350 /* ======================================================================
7351    FUNCTION
7352    omx_vdec::EmptyThisBuffer
7353 
7354    DESCRIPTION
7355    This routine is used to push the encoded video frames to
7356    the video decoder.
7357 
7358    PARAMETERS
7359    None.
7360 
7361    RETURN VALUE
7362    OMX Error None if everything went successful.
7363 
7364    ========================================================================== */
7365 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
7366         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7367 {
7368     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
7369     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
7370 
7371     if (m_state != OMX_StateExecuting &&
7372             m_state != OMX_StatePause &&
7373             m_state != OMX_StateIdle) {
7374         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
7375         return OMX_ErrorInvalidState;
7376     }
7377 
7378     if (m_error_propogated) {
7379         DEBUG_PRINT_ERROR("Empty this buffer not allowed after error");
7380         return OMX_ErrorHardware;
7381     }
7382 
7383     if (buffer == NULL) {
7384         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
7385         return OMX_ErrorBadParameter;
7386     }
7387     print_omx_buffer("EmptyThisBuffer", buffer);
7388 
7389     if (!m_inp_bEnabled) {
7390         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
7391         return OMX_ErrorIncorrectStateOperation;
7392     }
7393 
7394     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
7395         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
7396         return OMX_ErrorBadPortIndex;
7397     }
7398 
7399     if (perf_flag) {
7400         if (!latency) {
7401             dec_time.stop();
7402             latency = dec_time.processing_time_us();
7403             dec_time.start();
7404         }
7405     }
7406 
7407     if (arbitrary_bytes) {
7408         nBufferIndex = buffer - m_inp_heap_ptr;
7409     } else {
7410         if (input_use_buffer == true) {
7411             nBufferIndex = buffer - m_inp_heap_ptr;
7412             if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7413                 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
7414                 return OMX_ErrorBadParameter;
7415             }
7416             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
7417             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
7418             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
7419             buffer = &m_inp_mem_ptr[nBufferIndex];
7420             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
7421                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
7422         } else {
7423             nBufferIndex = buffer - m_inp_mem_ptr;
7424         }
7425     }
7426 
7427     if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7428         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
7429         return OMX_ErrorBadParameter;
7430     }
7431 
7432     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7433         codec_config_flag = true;
7434         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
7435     }
7436 
7437     /* The client should not set this when codec is in arbitrary bytes mode */
7438     if (m_input_pass_buffer_fd) {
7439         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
7440     }
7441 
7442     /* Check if the input timestamp in seconds is greater than LONG_MAX
7443        or lesser than LONG_MIN. */
7444     if (buffer->nTimeStamp / 1000000 > LONG_MAX ||
7445        buffer->nTimeStamp / 1000000 < LONG_MIN) {
7446         /* This timestamp cannot be contained in driver timestamp field */
7447         DEBUG_PRINT_ERROR("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u) >> Invalid timestamp",
7448             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
7449         return OMX_ErrorBadParameter;
7450     }
7451 
7452     m_etb_count++;
7453     //To handle wrap around case. m_etb_count++ to ensure value is non-zero.
7454     if (!m_etb_count)
7455         m_etb_count++;
7456     m_etb_timestamp = buffer->nTimeStamp;
7457     DEBUG_PRINT_LOW("[ETB] nCnt(%u) BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
7458             m_etb_count, buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
7459     buffer->pMarkData = (OMX_PTR)(unsigned long)m_etb_count;
7460     if (arbitrary_bytes) {
7461         post_event ((unsigned long)hComp,(unsigned long)buffer,
7462                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
7463     } else {
7464         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
7465     }
7466 
7467     time_stamp_dts.insert_timestamp(buffer);
7468     return OMX_ErrorNone;
7469 }
7470 
7471 /* ======================================================================
7472    FUNCTION
7473    omx_vdec::empty_this_buffer_proxy
7474 
7475    DESCRIPTION
7476    This routine is used to push the encoded video frames to
7477    the video decoder.
7478 
7479    PARAMETERS
7480    None.
7481 
7482    RETURN VALUE
7483    OMX Error None if everything went successful.
7484 
7485    ========================================================================== */
7486 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
7487         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7488 {
7489     VIDC_TRACE_NAME_HIGH("ETB");
7490     (void) hComp;
7491     int push_cnt = 0,i=0;
7492     unsigned nPortIndex = 0;
7493     OMX_ERRORTYPE ret = OMX_ErrorNone;
7494     struct vdec_bufferpayload *temp_buffer;
7495     bool port_setting_changed = true;
7496 
7497     /*Should we generate a Aync error event*/
7498     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
7499         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
7500         return OMX_ErrorBadParameter;
7501     }
7502 
7503     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
7504 
7505     if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
7506         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
7507                 nPortIndex);
7508         return OMX_ErrorBadParameter;
7509     }
7510 
7511     pending_input_buffers++;
7512     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
7513 
7514     /* return zero length and not an EOS buffer */
7515     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
7516             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
7517         DEBUG_PRINT_HIGH("return zero length buffer");
7518         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7519                 OMX_COMPONENT_GENERATE_EBD);
7520         return OMX_ErrorNone;
7521     }
7522 
7523     if (input_flush_progress == true) {
7524         DEBUG_PRINT_LOW("Flush in progress return buffer ");
7525         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7526                 OMX_COMPONENT_GENERATE_EBD);
7527         return OMX_ErrorNone;
7528     }
7529 
7530     if (m_error_propogated == true) {
7531         DEBUG_PRINT_LOW("Return buffer in error state");
7532         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7533                 OMX_COMPONENT_GENERATE_EBD);
7534         return OMX_ErrorNone;
7535     }
7536 
7537     auto_lock l(buf_lock);
7538     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
7539 
7540     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
7541         return OMX_ErrorBadParameter;
7542     }
7543 
7544     if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
7545         DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
7546         return OMX_ErrorBadParameter;
7547     }
7548 
7549     VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000);
7550     VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen);
7551     /*for use buffer we need to memcpy the data*/
7552     temp_buffer->buffer_len = buffer->nFilledLen;
7553 
7554     if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
7555         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
7556             if (arbitrary_bytes) {
7557                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
7558             } else {
7559                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
7560                         buffer->nFilledLen);
7561             }
7562         } else {
7563             return OMX_ErrorBadParameter;
7564         }
7565 
7566     }
7567 
7568     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
7569         DEBUG_PRINT_LOW("ETB: dmx enabled");
7570         if (m_demux_entries == 0) {
7571             extract_demux_addr_offsets(buffer);
7572         }
7573 
7574         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
7575         handle_demux_data(buffer);
7576     }
7577 
7578     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len, buffer->nTimeStamp, temp_buffer->pmem_fd);
7579 
7580     if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
7581         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7582     }
7583 
7584     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7585         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
7586         h264_scratch.nFilledLen = 0;
7587         nal_count = 0;
7588         look_ahead_nal = false;
7589         frame_count = 0;
7590         if (m_frame_parser.mutils)
7591             m_frame_parser.mutils->initialize_frame_checking_environment();
7592         m_frame_parser.flush();
7593         h264_last_au_ts = LLONG_MAX;
7594         h264_last_au_flags = 0;
7595         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
7596         m_demux_entries = 0;
7597     }
7598     struct v4l2_buffer buf;
7599     struct v4l2_plane plane;
7600     memset( (void *)&buf, 0, sizeof(buf));
7601     memset( (void *)&plane, 0, sizeof(plane));
7602     int rc;
7603     unsigned long  print_count;
7604     if (temp_buffer->buffer_len == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7605         struct v4l2_decoder_cmd dec;
7606 
7607         if (!streaming[OUTPUT_PORT]) {
7608             enum v4l2_buf_type buf_type;
7609             int ret = 0;
7610 
7611             buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7612             DEBUG_PRINT_HIGH("Calling streamon before issuing stop command for EOS");
7613             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7614             if (!ret) {
7615                 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7616                 streaming[OUTPUT_PORT] = true;
7617             } else {
7618                 DEBUG_PRINT_ERROR("Streamon failed before sending stop command");
7619                 return OMX_ErrorHardware;
7620             }
7621         }
7622 
7623         DEBUG_PRINT_HIGH("Input EOS reached. Converted to STOP command") ;
7624         memset(&dec, 0, sizeof(dec));
7625         dec.cmd = V4L2_DEC_CMD_STOP;
7626         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec);
7627         post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7628             OMX_COMPONENT_GENERATE_EBD);
7629         if (rc < 0) {
7630             DEBUG_PRINT_ERROR("Decoder CMD failed");
7631             return OMX_ErrorHardware;
7632         }
7633         return OMX_ErrorNone;
7634     }
7635 
7636     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
7637         DEBUG_PRINT_HIGH("Input EOS reached") ;
7638         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
7639     }
7640 
7641     // update hdr10plusinfo list with cookie as pMarkData
7642     update_hdr10plusinfo_cookie_using_timestamp(buffer->pMarkData, buffer->nTimeStamp);
7643 
7644     OMX_ERRORTYPE eRet = OMX_ErrorNone;
7645     buf.index = nPortIndex;
7646     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7647     buf.memory = V4L2_MEMORY_USERPTR;
7648     plane.bytesused = temp_buffer->buffer_len;
7649     plane.length = drv_ctx.ip_buf.buffer_size;
7650     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
7651         (unsigned long)temp_buffer->offset;
7652     plane.reserved[0] = temp_buffer->pmem_fd;
7653     plane.reserved[1] = temp_buffer->offset;
7654     plane.reserved[3] = (unsigned long)buffer->pMarkData;
7655     plane.reserved[4] = (unsigned long)buffer->hMarkTargetComponent;
7656     plane.data_offset = 0;
7657     buf.m.planes = &plane;
7658     buf.length = 1;
7659     //assumption is that timestamp is in milliseconds
7660     buf.timestamp.tv_sec = buffer->nTimeStamp / 1000000;
7661     buf.timestamp.tv_usec = (buffer->nTimeStamp % 1000000);
7662     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
7663 #if NEED_TO_REVISIT
7664     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
7665 #endif
7666 
7667     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7668         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
7669         android_atomic_inc(&m_queued_codec_config_count);
7670     }
7671 
7672     print_v4l2_buffer("QBUF-ETB", &buf);
7673     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7674     if (rc) {
7675         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
7676         print_v4l2_buffer("QBUF failed", &buf);
7677         print_omx_buffer("EBD on qbuf failed", buffer);
7678         m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
7679         return OMX_ErrorHardware;
7680     }
7681 
7682     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7683         codec_config_flag = false;
7684     }
7685     if (!streaming[OUTPUT_PORT]) {
7686         enum v4l2_buf_type buf_type;
7687         int ret,r;
7688 
7689         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7690         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
7691         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7692         if (!ret) {
7693             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7694             streaming[OUTPUT_PORT] = true;
7695         } else if (errno == EBUSY) {
7696             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
7697             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7698                     OMX_COMPONENT_GENERATE_EBD);
7699             return OMX_ErrorInsufficientResources;
7700         } else {
7701             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
7702             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
7703             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7704                     OMX_COMPONENT_GENERATE_EBD);
7705             return OMX_ErrorBadParameter;
7706         }
7707     }
7708 
7709     return ret;
7710 }
7711 
7712 /* ======================================================================
7713    FUNCTION
7714    omx_vdec::FillThisBuffer
7715 
7716    DESCRIPTION
7717    IL client uses this method to release the frame buffer
7718    after displaying them.
7719 
7720    PARAMETERS
7721    None.
7722 
7723    RETURN VALUE
7724    true/false
7725 
7726    ========================================================================== */
7727 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
7728         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7729 {
7730     if (m_state != OMX_StateExecuting &&
7731             m_state != OMX_StatePause &&
7732             m_state != OMX_StateIdle) {
7733         DEBUG_PRINT_ERROR("FTB in Invalid State");
7734         return OMX_ErrorInvalidState;
7735     }
7736 
7737     if (buffer == NULL || buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
7738         DEBUG_PRINT_ERROR("ERROR:FTB invalid buffer %p or PortIndex - %d",
7739              buffer, buffer ? (int)buffer->nOutputPortIndex : -1);
7740         return OMX_ErrorBadPortIndex;
7741     }
7742     print_omx_buffer("FillThisBuffer", buffer);
7743 
7744     if (m_error_propogated) {
7745         DEBUG_PRINT_ERROR("Fill this buffer not allowed after error");
7746         return OMX_ErrorHardware;
7747     }
7748 
7749     if (!m_out_bEnabled) {
7750         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
7751         return OMX_ErrorIncorrectStateOperation;
7752     }
7753 
7754     unsigned nPortIndex = buffer - m_out_mem_ptr;
7755     if (dynamic_buf_mode) {
7756         private_handle_t *handle = NULL;
7757         struct VideoDecoderOutputMetaData *meta = NULL;
7758 
7759         if (!buffer || !buffer->pBuffer) {
7760             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
7761             return OMX_ErrorBadParameter;
7762         }
7763 
7764         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
7765         handle = (private_handle_t *)meta->pHandle;
7766 
7767         //get the buffer type and fd info
7768         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ",
7769                         meta, meta->eType, meta->pHandle);
7770 
7771         if (!handle) {
7772             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
7773             return OMX_ErrorBadParameter;
7774         }
7775 
7776         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
7777         if (nPortIndex < drv_ctx.op_buf.actualcount &&
7778             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
7779             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
7780             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
7781 
7782             //Store private handle from GraphicBuffer
7783             native_buffer[nPortIndex].privatehandle = handle;
7784             native_buffer[nPortIndex].nativehandle = handle;
7785         } else {
7786             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
7787             return OMX_ErrorBadParameter;
7788         }
7789 
7790         if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
7791             m_is_display_session = true;
7792         } else {
7793             m_is_display_session = false;
7794         }
7795         buffer->nAllocLen = handle->size;
7796         DEBUG_PRINT_LOW("%s: buffer size = d-%d:b-%d",
7797                         __func__, (int)drv_ctx.op_buf.buffer_size, (int)handle->size);
7798 
7799         if (!client_buffers.is_color_conversion_enabled()) {
7800             drv_ctx.op_buf.buffer_size = handle->size;
7801         }
7802 
7803         DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
7804     }
7805 
7806     if (client_buffers.is_color_conversion_enabled()) {
7807         buffer = m_intermediate_out_mem_ptr + nPortIndex;
7808         buffer->nAllocLen = drv_ctx.op_buf.buffer_size;
7809     }
7810 
7811     //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
7812     //this with a more sane size so that we don't compensate in rest of code
7813     //We'll restore this size later on, so that it's transparent to client
7814     buffer->nFilledLen = 0;
7815 
7816     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
7817     return OMX_ErrorNone;
7818 }
7819 
7820 /* ======================================================================
7821    FUNCTION
7822    omx_vdec::fill_this_buffer_proxy
7823 
7824    DESCRIPTION
7825    IL client uses this method to release the frame buffer
7826    after displaying them.
7827 
7828    PARAMETERS
7829    None.
7830 
7831    RETURN VALUE
7832    true/false
7833 
7834    ========================================================================== */
7835 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
7836         OMX_IN OMX_HANDLETYPE        hComp,
7837         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
7838 {
7839     VIDC_TRACE_NAME_HIGH("FTB");
7840     OMX_ERRORTYPE nRet = OMX_ErrorNone;
7841     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
7842     unsigned bufIndex = 0;
7843     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
7844     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
7845 
7846     auto_lock l(buf_lock);
7847     OMX_BUFFERHEADERTYPE  *omx_base_address =
7848         client_buffers.is_color_conversion_enabled()?
7849                            m_intermediate_out_mem_ptr:m_out_mem_ptr;
7850     vdec_bufferpayload *omx_ptr_outputbuffer =
7851         client_buffers.is_color_conversion_enabled()?
7852                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
7853     bufIndex = buffer-omx_base_address;
7854 
7855     if (bufferAdd == NULL || bufIndex >= drv_ctx.op_buf.actualcount) {
7856         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, bufIndex %u bufCount %u",
7857             bufIndex, drv_ctx.op_buf.actualcount);
7858         return OMX_ErrorBadParameter;
7859     }
7860 
7861     if (BITMASK_ABSENT(&m_out_bm_count, bufIndex) || m_buffer_error) {
7862         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, bufIndex %u", bufIndex);
7863         return OMX_ErrorBadParameter;
7864     }
7865 
7866     /*Return back the output buffer to client*/
7867     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) {
7868         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
7869         buffer->nFilledLen = 0;
7870         print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7871         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7872         return OMX_ErrorNone;
7873     }
7874     if (m_error_propogated == true) {
7875         DEBUG_PRINT_LOW("Return buffers in error state");
7876         buffer->nFilledLen = 0;
7877         print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7878         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7879         return OMX_ErrorNone;
7880     }
7881 
7882     if (dynamic_buf_mode) {
7883         omx_ptr_outputbuffer[bufIndex].offset = 0;
7884         omx_ptr_outputbuffer[bufIndex].buffer_len = buffer->nAllocLen;
7885         omx_ptr_outputbuffer[bufIndex].mmaped_size = buffer->nAllocLen;
7886     }
7887 
7888     pending_output_buffers++;
7889     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7890     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
7891     if (ptr_respbuffer) {
7892         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
7893     }
7894 
7895     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
7896         DEBUG_PRINT_ERROR("Invalid ptr_respbuffer %p, ptr_outputbuffer %p",
7897             ptr_respbuffer, ptr_outputbuffer);
7898         buffer->nFilledLen = 0;
7899         print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7900         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7901         pending_output_buffers--;
7902         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7903         return OMX_ErrorBadParameter;
7904     }
7905 
7906     int rc = 0;
7907     struct v4l2_buffer buf;
7908     struct v4l2_plane plane[VIDEO_MAX_PLANES];
7909     memset( (void *)&buf, 0, sizeof(buf));
7910     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
7911     unsigned int extra_idx = 0;
7912 
7913     buf.index = bufIndex;
7914     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7915     buf.memory = V4L2_MEMORY_USERPTR;
7916     plane[0].bytesused = buffer->nFilledLen;
7917     plane[0].length = buffer->nAllocLen;
7918     plane[0].m.userptr =
7919         (unsigned long)omx_ptr_outputbuffer[bufIndex].bufferaddr -
7920         (unsigned long)omx_ptr_outputbuffer[bufIndex].offset;
7921     plane[0].reserved[0] = omx_ptr_outputbuffer[bufIndex].pmem_fd;
7922     plane[0].reserved[1] = omx_ptr_outputbuffer[bufIndex].offset;
7923     plane[0].data_offset = 0;
7924     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7925     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7926         plane[extra_idx].bytesused = 0;
7927         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
7928         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + bufIndex * drv_ctx.extradata_info.buffer_size);
7929 #ifdef USE_ION
7930         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.data_fd;
7931 #endif
7932         plane[extra_idx].reserved[1] = bufIndex * drv_ctx.extradata_info.buffer_size;
7933         plane[extra_idx].data_offset = 0;
7934     } else if (extra_idx >= VIDEO_MAX_PLANES) {
7935         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
7936         return OMX_ErrorBadParameter;
7937     }
7938     buf.m.planes = plane;
7939     buf.length = drv_ctx.num_planes;
7940     print_v4l2_buffer("QBUF-FTB", &buf);
7941     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7942     if (rc) {
7943         buffer->nFilledLen = 0;
7944         DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno));
7945         print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7946         m_cb.FillBufferDone(hComp, m_app_data, &m_out_mem_ptr[bufIndex]);
7947         return OMX_ErrorHardware;
7948     }
7949 
7950     return OMX_ErrorNone;
7951 }
7952 
7953 /* ======================================================================
7954    FUNCTION
7955    omx_vdec::SetCallbacks
7956 
7957    DESCRIPTION
7958    Set the callbacks.
7959 
7960    PARAMETERS
7961    None.
7962 
7963    RETURN VALUE
7964    OMX Error None if everything successful.
7965 
7966    ========================================================================== */
7967 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
7968         OMX_IN OMX_CALLBACKTYPE* callbacks,
7969         OMX_IN OMX_PTR             appData)
7970 {
7971     (void) hComp;
7972 
7973     if (!callbacks)
7974         return OMX_ErrorBadParameter;
7975 
7976     m_cb       = *callbacks;
7977     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
7978             m_cb.EventHandler,m_cb.FillBufferDone);
7979     m_app_data =    appData;
7980     return OMX_ErrorNone;
7981 }
7982 
7983 /* ======================================================================
7984    FUNCTION
7985    omx_vdec::ComponentDeInit
7986 
7987    DESCRIPTION
7988    Destroys the component and release memory allocated to the heap.
7989 
7990    PARAMETERS
7991    <TBD>.
7992 
7993    RETURN VALUE
7994    OMX Error None if everything successful.
7995 
7996    ========================================================================== */
7997 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
7998 {
7999    (void) hComp;
8000    OMX_ERRORTYPE nRet = OMX_ErrorNone;
8001    OMX_BUFFERHEADERTYPE *buffer;
8002 
8003     unsigned i = 0;
8004     if (OMX_StateLoaded != m_state) {
8005         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
8006                 m_state);
8007         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
8008     } else {
8009         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
8010     }
8011 
8012     /*Check if the output buffers have to be cleaned up*/
8013     buffer = m_out_mem_ptr;
8014     if (buffer) {
8015         DEBUG_PRINT_LOW("Freeing the Output Memory");
8016         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
8017             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
8018                 BITMASK_CLEAR(&m_out_bm_count, i);
8019                     nRet = free_output_buffer (buffer+i);
8020                     if (OMX_ErrorNone != nRet)
8021                         break;
8022             }
8023             if (release_output_done()) {
8024                 DEBUG_PRINT_HIGH("All output buffers are released");
8025                 break;
8026             }
8027         }
8028 #ifdef _ANDROID_ICS_
8029         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
8030 #endif
8031     }
8032 
8033     /*Check if the input buffers have to be cleaned up*/
8034     if (m_inp_mem_ptr || m_inp_heap_ptr) {
8035         DEBUG_PRINT_LOW("Freeing the Input Memory");
8036         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
8037 
8038             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
8039                 BITMASK_CLEAR(&m_inp_bm_count, i);
8040                 if (m_inp_mem_ptr)
8041                     free_input_buffer (i,&m_inp_mem_ptr[i]);
8042                 else
8043                     free_input_buffer (i,NULL);
8044             }
8045 
8046             if (release_input_done()) {
8047                 DEBUG_PRINT_HIGH("All input buffers released");
8048                 break;
8049             }
8050        }
8051     }
8052     free_input_buffer_header();
8053     free_output_buffer_header();
8054     if (h264_scratch.pBuffer) {
8055         free(h264_scratch.pBuffer);
8056         h264_scratch.pBuffer = NULL;
8057     }
8058 
8059     if (h264_parser) {
8060         delete h264_parser;
8061         h264_parser = NULL;
8062     }
8063 
8064     if (m_frame_parser.mutils) {
8065         DEBUG_PRINT_LOW("Free utils parser");
8066         delete (m_frame_parser.mutils);
8067         m_frame_parser.mutils = NULL;
8068     }
8069 
8070     if (m_platform_list) {
8071         free(m_platform_list);
8072         m_platform_list = NULL;
8073     }
8074     if (m_vendor_config.pData) {
8075         free(m_vendor_config.pData);
8076         m_vendor_config.pData = NULL;
8077     }
8078 
8079     // Reset counters in mesg queues
8080     m_ftb_q.m_size=0;
8081     m_cmd_q.m_size=0;
8082     m_etb_q.m_size=0;
8083     m_ftb_q.m_read = m_ftb_q.m_write =0;
8084     m_cmd_q.m_read = m_cmd_q.m_write =0;
8085     m_etb_q.m_read = m_etb_q.m_write =0;
8086 
8087     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
8088     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
8089     // NULL);
8090     DEBUG_PRINT_HIGH("Close the driver instance");
8091 
8092     if (m_debug.infile) {
8093         fclose(m_debug.infile);
8094         m_debug.infile = NULL;
8095     }
8096     if (m_debug.outfile) {
8097         fclose(m_debug.outfile);
8098         m_debug.outfile = NULL;
8099     }
8100     if (m_debug.ccoutfile) {
8101         fclose(m_debug.ccoutfile);
8102         m_debug.ccoutfile = NULL;
8103     }
8104     if (m_debug.out_ymeta_file) {
8105         fclose(m_debug.out_ymeta_file);
8106         m_debug.out_ymeta_file = NULL;
8107     }
8108     if (m_debug.out_uvmeta_file) {
8109         fclose(m_debug.out_uvmeta_file);
8110         m_debug.out_uvmeta_file = NULL;
8111     }
8112 #ifdef OUTPUT_EXTRADATA_LOG
8113     if (outputExtradataFile)
8114         fclose (outputExtradataFile);
8115 #endif
8116     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
8117     return OMX_ErrorNone;
8118 }
8119 
8120 /* ======================================================================
8121    FUNCTION
8122    omx_vdec::UseEGLImage
8123 
8124    DESCRIPTION
8125    OMX Use EGL Image method implementation <TBD>.
8126 
8127    PARAMETERS
8128    <TBD>.
8129 
8130    RETURN VALUE
8131    Not Implemented error.
8132 
8133    ========================================================================== */
8134 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
8135         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
8136         OMX_IN OMX_U32                        port,
8137         OMX_IN OMX_PTR                     appData,
8138         OMX_IN void*                      eglImage)
8139 {
8140     (void) appData;
8141     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
8142     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
8143     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
8144 
8145 #ifdef USE_EGL_IMAGE_GPU
8146     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
8147     EGLint fd = -1, offset = 0,pmemPtr = 0;
8148 #else
8149     int fd = -1, offset = 0;
8150 #endif
8151     DEBUG_PRINT_HIGH("use EGL image support for decoder");
8152     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
8153         DEBUG_PRINT_ERROR("Invalid EGL image");
8154     }
8155 #ifdef USE_EGL_IMAGE_GPU
8156     if (m_display_id == NULL) {
8157         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
8158         return OMX_ErrorInsufficientResources;
8159     }
8160     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
8161         eglGetProcAddress("eglQueryImageKHR");
8162     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
8163     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
8164     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
8165 #else //with OMX test app
8166     struct temp_egl {
8167         int pmem_fd;
8168         int offset;
8169     };
8170     struct temp_egl *temp_egl_id = NULL;
8171     void * pmemPtr = (void *) eglImage;
8172     temp_egl_id = (struct temp_egl *)eglImage;
8173     if (temp_egl_id != NULL) {
8174         fd = temp_egl_id->pmem_fd;
8175         offset = temp_egl_id->offset;
8176     }
8177 #endif
8178     if (fd < 0) {
8179         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
8180         return OMX_ErrorInsufficientResources;
8181     }
8182     pmem_info.pmem_fd = (OMX_U32) fd;
8183     pmem_info.offset = (OMX_U32) offset;
8184     pmem_entry.entry = (void *) &pmem_info;
8185     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8186     pmem_list.entryList = &pmem_entry;
8187     pmem_list.nEntries = 1;
8188     ouput_egl_buffers = true;
8189     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
8190                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
8191                 (OMX_U8 *)pmemPtr)) {
8192         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
8193         return OMX_ErrorInsufficientResources;
8194     }
8195     return OMX_ErrorNone;
8196 }
8197 
8198 /* ======================================================================
8199    FUNCTION
8200    omx_vdec::ComponentRoleEnum
8201 
8202    DESCRIPTION
8203    OMX Component Role Enum method implementation.
8204 
8205    PARAMETERS
8206    <TBD>.
8207 
8208    RETURN VALUE
8209    OMX Error None if everything is successful.
8210    ========================================================================== */
8211 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
8212         OMX_OUT OMX_U8*        role,
8213         OMX_IN OMX_U32        index)
8214 {
8215     (void) hComp;
8216     OMX_ERRORTYPE eRet = OMX_ErrorNone;
8217 
8218     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
8219         if ((0 == index) && role) {
8220             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
8221             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8222         } else {
8223             eRet = OMX_ErrorNoMore;
8224         }
8225     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
8226         if ((0 == index) && role) {
8227             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
8228             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8229         } else {
8230             DEBUG_PRINT_LOW("No more roles");
8231             eRet = OMX_ErrorNoMore;
8232         }
8233     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
8234         if ((0 == index) && role) {
8235             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
8236             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8237         } else {
8238             DEBUG_PRINT_LOW("No more roles");
8239             eRet = OMX_ErrorNoMore;
8240         }
8241     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
8242         if ((0 == index) && role) {
8243             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
8244             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
8245         } else {
8246             DEBUG_PRINT_LOW("No more roles");
8247             eRet = OMX_ErrorNoMore;
8248         }
8249     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
8250         if ((0 == index) && role) {
8251             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
8252             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8253         } else {
8254             DEBUG_PRINT_LOW("No more roles");
8255             eRet = OMX_ErrorNoMore;
8256         }
8257     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
8258         if ((0 == index) && role) {
8259             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
8260             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8261         } else {
8262             DEBUG_PRINT_LOW("No more roles");
8263             eRet = OMX_ErrorNoMore;
8264         }
8265     } else {
8266         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
8267         eRet = OMX_ErrorInvalidComponentName;
8268     }
8269     return eRet;
8270 }
8271 
8272 
8273 
8274 
8275 /* ======================================================================
8276    FUNCTION
8277    omx_vdec::AllocateDone
8278 
8279    DESCRIPTION
8280    Checks if entire buffer pool is allocated by IL Client or not.
8281    Need this to move to IDLE state.
8282 
8283    PARAMETERS
8284    None.
8285 
8286    RETURN VALUE
8287    true/false.
8288 
8289    ========================================================================== */
8290 bool omx_vdec::allocate_done(void)
8291 {
8292     bool bRet = false;
8293     bool bRet_In = false;
8294     bool bRet_Out = false;
8295     bool bRet_Out_Extra = false;
8296 
8297     bRet_In = allocate_input_done();
8298     bRet_Out = allocate_output_done();
8299     bRet_Out_Extra = allocate_output_extradata_done();
8300 
8301     if (bRet_In && bRet_Out && bRet_Out_Extra) {
8302         DEBUG_PRINT_HIGH("All ports buffers are allocated");
8303         bRet = true;
8304     }
8305 
8306     return bRet;
8307 }
8308 /* ======================================================================
8309    FUNCTION
8310    omx_vdec::AllocateInputDone
8311 
8312    DESCRIPTION
8313    Checks if I/P buffer pool is allocated by IL Client or not.
8314 
8315    PARAMETERS
8316    None.
8317 
8318    RETURN VALUE
8319    true/false.
8320 
8321    ========================================================================== */
8322 bool omx_vdec::allocate_input_done(void)
8323 {
8324     bool bRet = false;
8325     unsigned i=0;
8326 
8327     if (m_inp_mem_ptr == NULL) {
8328         return bRet;
8329     }
8330     if (m_inp_mem_ptr ) {
8331         for (; i<drv_ctx.ip_buf.actualcount; i++) {
8332             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
8333                 break;
8334             }
8335         }
8336     }
8337     if (i == drv_ctx.ip_buf.actualcount) {
8338         bRet = true;
8339     }
8340     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
8341         m_inp_bPopulated = OMX_TRUE;
8342     }
8343     return bRet;
8344 }
8345 /* ======================================================================
8346    FUNCTION
8347    omx_vdec::AllocateOutputDone
8348 
8349    DESCRIPTION
8350    Checks if entire O/P buffer pool is allocated by IL Client or not.
8351 
8352    PARAMETERS
8353    None.
8354 
8355    RETURN VALUE
8356    true/false.
8357 
8358    ========================================================================== */
8359 bool omx_vdec::allocate_output_done(void)
8360 {
8361     bool bRet = false;
8362     unsigned j=0;
8363 
8364     if (m_out_mem_ptr == NULL) {
8365         return bRet;
8366     }
8367 
8368     if (m_out_mem_ptr) {
8369         for (; j < drv_ctx.op_buf.actualcount; j++) {
8370             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
8371                 break;
8372             }
8373         }
8374     }
8375 
8376     if (j == drv_ctx.op_buf.actualcount) {
8377         bRet = true;
8378         if (m_out_bEnabled)
8379             m_out_bPopulated = OMX_TRUE;
8380     }
8381 
8382     return bRet;
8383 }
8384 
8385 bool omx_vdec::allocate_output_extradata_done(void) {
8386     bool bRet = false;
8387     unsigned j=0;
8388     unsigned nBufferCount = 0;
8389 
8390     nBufferCount = m_client_out_extradata_info.getBufferCount();
8391 
8392     if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
8393         return true;
8394     }
8395 
8396     if (m_client_output_extradata_mem_ptr) {
8397         for (; j < nBufferCount; j++) {
8398             if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
8399                 break;
8400             }
8401         }
8402 
8403         if (j == nBufferCount) {
8404             bRet = true;
8405             DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
8406         }
8407     }
8408 
8409     return bRet;
8410 }
8411 /* ======================================================================
8412    FUNCTION
8413    omx_vdec::ReleaseDone
8414 
8415    DESCRIPTION
8416    Checks if IL client has released all the buffers.
8417 
8418    PARAMETERS
8419    None.
8420 
8421    RETURN VALUE
8422    true/false
8423 
8424    ========================================================================== */
8425 bool omx_vdec::release_done(void)
8426 {
8427     bool bRet = false;
8428 
8429     if (release_input_done()) {
8430         if (release_output_done()) {
8431             if (release_output_extradata_done()) {
8432                 DEBUG_PRINT_HIGH("All ports buffers are released");
8433                 bRet = true;
8434             }
8435         }
8436     }
8437     return bRet;
8438 }
8439 
8440 
8441 /* ======================================================================
8442    FUNCTION
8443    omx_vdec::ReleaseOutputDone
8444 
8445    DESCRIPTION
8446    Checks if IL client has released all the buffers.
8447 
8448    PARAMETERS
8449    None.
8450 
8451    RETURN VALUE
8452    true/false
8453 
8454    ========================================================================== */
8455 bool omx_vdec::release_output_done(void)
8456 {
8457     bool bRet = false;
8458     unsigned i=0,j=0;
8459 
8460     if (m_out_mem_ptr) {
8461         for (; j < drv_ctx.op_buf.actualcount ; j++) {
8462             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
8463                 break;
8464             }
8465         }
8466         if (j == drv_ctx.op_buf.actualcount) {
8467             m_out_bm_count = 0;
8468             bRet = true;
8469         }
8470     } else {
8471         m_out_bm_count = 0;
8472         bRet = true;
8473     }
8474     return bRet;
8475 }
8476 /* ======================================================================
8477    FUNCTION
8478    omx_vdec::ReleaseInputDone
8479 
8480    DESCRIPTION
8481    Checks if IL client has released all the buffers.
8482 
8483    PARAMETERS
8484    None.
8485 
8486    RETURN VALUE
8487    true/false
8488 
8489    ========================================================================== */
8490 bool omx_vdec::release_input_done(void)
8491 {
8492     bool bRet = false;
8493     unsigned i=0,j=0;
8494 
8495     if (m_inp_mem_ptr) {
8496         for (; j<drv_ctx.ip_buf.actualcount; j++) {
8497             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
8498                 break;
8499             }
8500         }
8501         if (j==drv_ctx.ip_buf.actualcount) {
8502             bRet = true;
8503         }
8504     } else {
8505         bRet = true;
8506     }
8507     return bRet;
8508 }
8509 
8510 bool omx_vdec::release_output_extradata_done(void) {
8511     bool bRet = false;
8512     unsigned i=0,j=0, buffer_count=0;
8513 
8514     buffer_count = m_client_out_extradata_info.getBufferCount();
8515     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
8516             m_client_output_extradata_mem_ptr, buffer_count);
8517 
8518     if (m_client_output_extradata_mem_ptr) {
8519         for (; j<buffer_count; j++) {
8520             if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
8521                 break;
8522             }
8523         }
8524         if (j == buffer_count) {
8525             bRet = true;
8526         }
8527     } else {
8528         bRet = true;
8529     }
8530     return bRet;
8531 }
8532 
8533 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
8534         OMX_BUFFERHEADERTYPE * buffer)
8535 {
8536     VIDC_TRACE_NAME_HIGH("FBD");
8537     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
8538     OMX_BUFFERHEADERTYPE  *omx_base_address =
8539         client_buffers.is_color_conversion_enabled()?
8540                               m_intermediate_out_mem_ptr:m_out_mem_ptr;
8541     vdec_bufferpayload *omx_ptr_outputbuffer =
8542         client_buffers.is_color_conversion_enabled()?
8543                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
8544 
8545     if (!buffer || (buffer - omx_base_address) >= (int)drv_ctx.op_buf.actualcount) {
8546         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
8547         return OMX_ErrorBadParameter;
8548     } else if (output_flush_progress) {
8549         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
8550         buffer->nFilledLen = 0;
8551         buffer->nTimeStamp = 0;
8552         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8553         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
8554         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
8555     }
8556 
8557     if (m_debug_extradata) {
8558         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
8559             DEBUG_PRINT_HIGH("***************************************************");
8560             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
8561             DEBUG_PRINT_HIGH("***************************************************");
8562         }
8563 
8564         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
8565             DEBUG_PRINT_HIGH("***************************************************");
8566             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8567             DEBUG_PRINT_HIGH("***************************************************");
8568         }
8569     }
8570 
8571     pending_output_buffers --;
8572     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
8573 
8574     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8575         DEBUG_PRINT_HIGH("Output EOS has been reached");
8576         if (!output_flush_progress)
8577             post_event((unsigned)NULL, (unsigned)NULL,
8578                     OMX_COMPONENT_GENERATE_EOS_DONE);
8579 
8580         if (psource_frame) {
8581             print_omx_buffer("EBD in FBD", psource_frame);
8582             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
8583             psource_frame = NULL;
8584         }
8585         if (pdest_frame) {
8586             pdest_frame->nFilledLen = 0;
8587             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
8588                     (unsigned)NULL);
8589             pdest_frame = NULL;
8590         }
8591     }
8592 
8593 #ifdef OUTPUT_EXTRADATA_LOG
8594     if (outputExtradataFile) {
8595         int buf_index = buffer - omx_base_address;
8596         OMX_U8 *pBuffer = (OMX_U8 *)(omx_ptr_outputbuffer[buf_index].bufferaddr);
8597 
8598         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
8599         p_extra = (OMX_OTHER_EXTRADATATYPE *)
8600             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
8601 
8602         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
8603             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
8604                                     p_extra->nSize, p_extra->eType);
8605             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
8606 
8607             if (p_extra->eType == OMX_ExtraDataNone) {
8608                 break;
8609             }
8610             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8611         }
8612     }
8613 #endif
8614 
8615     /* For use buffer we need to copy the data */
8616     if (!output_flush_progress) {
8617         /* This is the error check for non-recoverable errros */
8618         bool is_duplicate_ts_valid = true;
8619         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
8620 
8621         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
8622                 output_capability == V4L2_PIX_FMT_MPEG2)
8623             is_duplicate_ts_valid = false;
8624 
8625         if (buffer->nFilledLen > 0) {
8626             time_stamp_dts.get_next_timestamp(buffer,
8627                     is_interlaced && is_duplicate_ts_valid && !is_mbaff);
8628         }
8629     }
8630 
8631     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
8632 
8633     if (m_cb.FillBufferDone) {
8634         if (buffer->nFilledLen > 0) {
8635             if (arbitrary_bytes)
8636                 adjust_timestamp(buffer->nTimeStamp);
8637             else
8638                 set_frame_rate(buffer->nTimeStamp);
8639 
8640             proc_frms++;
8641             if (perf_flag) {
8642                 if (1 == proc_frms) {
8643                     dec_time.stop();
8644                     latency = dec_time.processing_time_us() - latency;
8645                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
8646                     dec_time.start();
8647                     fps_metrics.start();
8648                 }
8649                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8650                     OMX_U64 proc_time = 0;
8651                     fps_metrics.stop();
8652                     proc_time = fps_metrics.processing_time_us();
8653                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
8654                             (unsigned int)proc_frms, (float)proc_time / 1e6,
8655                             (float)(1e6 * proc_frms) / proc_time);
8656                 }
8657             }
8658         }
8659         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8660             prev_ts = LLONG_MAX;
8661             rst_prev_ts = true;
8662             proc_frms = 0;
8663         }
8664 
8665         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8666             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
8667              buffer->pPlatformPrivate)->entryList->entry;
8668         OMX_BUFFERHEADERTYPE *il_buffer;
8669         il_buffer = client_buffers.get_il_buf_hdr(buffer);
8670         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
8671 
8672         if (il_buffer && m_last_rendered_TS >= 0) {
8673             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
8674             // Convert fps into ms value. 1 sec = 1000000 ms.
8675             OMX_U64 target_ts_delta = m_dec_hfr_fps ? 1000000 / m_dec_hfr_fps : ts_delta;
8676 
8677             // Current frame can be send for rendering if
8678             // (a) current FPS is <=  60
8679             // (b) is the next frame after the frame with TS 0
8680             // (c) is the first frame after seek
8681             // (d) the delta TS b\w two consecutive frames is > 16 ms
8682             // (e) its TS is equal to previous frame TS
8683             // (f) if marked EOS
8684 
8685             if(current_framerate <= (OMX_U32)m_dec_hfr_fps || m_last_rendered_TS == 0 ||
8686                il_buffer->nTimeStamp == 0 || ts_delta >= (OMX_TICKS)target_ts_delta||
8687                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
8688                m_last_rendered_TS = il_buffer->nTimeStamp;
8689             } else {
8690                //mark for droping
8691                buffer->nFilledLen = 0;
8692             }
8693 
8694             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
8695                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
8696                               il_buffer->nTimeStamp,ts_delta);
8697 
8698             //above code makes sure that delta b\w two consecutive frames is not
8699             //greater than 16ms, slow-mo feature, so cap fps to max 60
8700             if (current_framerate > (OMX_U32)m_dec_hfr_fps ) {
8701                 current_framerate = m_dec_hfr_fps;
8702             }
8703         }
8704 
8705         // add current framerate to gralloc meta data
8706         if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && omx_base_address) {
8707             // If valid fps was received, directly send it to display for the 1st fbd.
8708             // Otherwise, calculate fps using fbd timestamps
8709             float refresh_rate = m_fps_prev;
8710             if (m_fps_received) {
8711                 if (1 == proc_frms) {
8712                     refresh_rate = m_fps_received / (float)(1<<16);
8713                 }
8714             } else {
8715                 // calculate and set refresh rate for every frame from second frame onwards
8716                 // display will assume the default refresh rate for first frame (which is 60 fps)
8717                 if (m_fps_prev) {
8718                     if (drv_ctx.frame_rate.fps_denominator) {
8719                         refresh_rate = drv_ctx.frame_rate.fps_numerator /
8720                             (float) drv_ctx.frame_rate.fps_denominator;
8721                     }
8722                 }
8723             }
8724             OMX_U32 fps_limit = m_dec_hfr_fps ? (OMX_U32)m_dec_hfr_fps : 60;
8725             if (refresh_rate > fps_limit) {
8726                 refresh_rate = fps_limit;
8727             }
8728             DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
8729             OMX_U32 buf_index = buffer - omx_base_address;
8730             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8731                          UPDATE_REFRESH_RATE, (void*)&refresh_rate);
8732             m_fps_prev = refresh_rate;
8733         }
8734 
8735         if (buffer->nFilledLen && m_enable_android_native_buffers && omx_base_address) {
8736             OMX_U32 buf_index = buffer - omx_base_address;
8737             DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
8738             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8739                                S3D_FORMAT, (void*)&stereo_output_mode);
8740         }
8741 
8742         if (il_buffer) {
8743             log_output_buffers(buffer);
8744             log_cc_output_buffers(il_buffer);
8745             if (dynamic_buf_mode) {
8746                 unsigned int nPortIndex = 0;
8747                 nPortIndex = buffer-omx_base_address;
8748 
8749                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
8750                 // to size of the handle. Do it _after_ log_output_buffers which
8751                 // requires the respective sizes to be accurate.
8752 
8753                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
8754                 buffer->nFilledLen = buffer->nFilledLen ?
8755                         sizeof(struct VideoDecoderOutputMetaData) : 0;
8756 
8757                 //Clear graphic buffer handles in dynamic mode
8758                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
8759                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
8760                     native_buffer[nPortIndex].privatehandle = NULL;
8761                     native_buffer[nPortIndex].nativehandle = NULL;
8762                 } else {
8763                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
8764                     return OMX_ErrorBadParameter;
8765                 }
8766             }
8767             print_omx_buffer("FillBufferDone", buffer);
8768             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
8769         } else {
8770             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
8771             return OMX_ErrorBadParameter;
8772         }
8773     } else {
8774         DEBUG_PRINT_ERROR("NULL m_cb.FillBufferDone");
8775         return OMX_ErrorBadParameter;
8776     }
8777 
8778 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
8779     if (m_smoothstreaming_mode && omx_base_address) {
8780         OMX_U32 buf_index = buffer - omx_base_address;
8781         BufferDim_t dim;
8782         private_handle_t *private_handle = NULL;
8783         dim.sliceWidth = framesize.nWidth;
8784         dim.sliceHeight = framesize.nHeight;
8785         if (buf_index < drv_ctx.op_buf.actualcount &&
8786             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
8787             native_buffer[buf_index].privatehandle)
8788             private_handle = native_buffer[buf_index].privatehandle;
8789         if (private_handle) {
8790             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
8791                 dim.sliceWidth, dim.sliceHeight);
8792             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
8793         }
8794     }
8795 #endif
8796 
8797     return OMX_ErrorNone;
8798 }
8799 
8800 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
8801         OMX_BUFFERHEADERTYPE* buffer)
8802 {
8803     VIDC_TRACE_NAME_HIGH("EBD");
8804     int nBufferIndex = buffer - m_inp_mem_ptr;
8805 
8806     if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
8807         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
8808         return OMX_ErrorBadParameter;
8809     }
8810 
8811     pending_input_buffers--;
8812     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
8813 
8814     if (arbitrary_bytes) {
8815         if (pdest_frame == NULL && input_flush_progress == false) {
8816             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
8817             pdest_frame = buffer;
8818             buffer->nFilledLen = 0;
8819             buffer->nTimeStamp = LLONG_MAX;
8820             push_input_buffer (hComp);
8821         } else {
8822             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
8823             buffer->nFilledLen = 0;
8824             if (!m_input_free_q.insert_entry((unsigned long)buffer,
8825                         (unsigned)NULL, (unsigned)NULL)) {
8826                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
8827             }
8828         }
8829     } else if (m_cb.EmptyBufferDone) {
8830         buffer->nFilledLen = 0;
8831         if (input_use_buffer == true) {
8832             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
8833         }
8834 
8835         /* Restore the FD that we over-wrote in ETB */
8836         if (m_input_pass_buffer_fd) {
8837             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
8838         }
8839 
8840         print_omx_buffer("EmptyBufferDone", buffer);
8841         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
8842     }
8843     return OMX_ErrorNone;
8844 }
8845 
8846 int omx_vdec::async_message_process (void *context, void* message)
8847 {
8848     omx_vdec* omx = NULL;
8849     struct vdec_msginfo *vdec_msg = NULL;
8850     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
8851     struct v4l2_buffer *v4l2_buf_ptr = NULL;
8852     struct v4l2_plane *plane = NULL;
8853     struct vdec_output_frameinfo *output_respbuf = NULL;
8854     int rc=1;
8855     bool reconfig_event_sent = false;
8856     if (context == NULL || message == NULL) {
8857         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
8858         return -1;
8859     }
8860     vdec_msg = (struct vdec_msginfo *)message;
8861 
8862     omx = reinterpret_cast<omx_vdec*>(context);
8863 
8864     switch (vdec_msg->msgcode) {
8865 
8866         case VDEC_MSG_EVT_HW_ERROR:
8867             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8868                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8869             break;
8870 
8871         case VDEC_MSG_EVT_HW_OVERLOAD:
8872             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8873                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
8874             break;
8875 
8876         case VDEC_MSG_EVT_HW_UNSUPPORTED:
8877             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8878                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
8879             break;
8880 
8881         case VDEC_MSG_RESP_START_DONE:
8882             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8883                     OMX_COMPONENT_GENERATE_START_DONE);
8884             break;
8885 
8886         case VDEC_MSG_RESP_STOP_DONE:
8887             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8888                     OMX_COMPONENT_GENERATE_STOP_DONE);
8889             break;
8890 
8891         case VDEC_MSG_RESP_RESUME_DONE:
8892             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8893                     OMX_COMPONENT_GENERATE_RESUME_DONE);
8894             break;
8895 
8896         case VDEC_MSG_RESP_PAUSE_DONE:
8897             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8898                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
8899             break;
8900 
8901         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
8902             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8903                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
8904             break;
8905         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
8906             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8907                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
8908             break;
8909         case VDEC_MSG_RESP_INPUT_FLUSHED:
8910         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
8911 
8912             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
8913                vdec_msg->msgdata.input_frame_clientdata; */
8914 
8915             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
8916             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
8917                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
8918                 omxhdr = NULL;
8919                 vdec_msg->status_code = VDEC_S_EFATAL;
8920                 break;
8921 
8922             }
8923             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
8924 
8925             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
8926                 DEBUG_PRINT_HIGH("Unsupported input");
8927                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8928                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8929             }
8930             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
8931                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8932                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
8933             }
8934             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
8935 
8936                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
8937                 android_atomic_dec(&omx->m_queued_codec_config_count);
8938                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
8939                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
8940                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
8941                     sem_post(&omx->m_safe_flush);
8942                 }
8943             }
8944             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
8945                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
8946             }
8947             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
8948                     OMX_COMPONENT_GENERATE_EBD);
8949             break;
8950         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
8951             int64_t *timestamp;
8952             timestamp = (int64_t *) malloc(sizeof(int64_t));
8953             if (timestamp) {
8954                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
8955                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
8956                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
8957                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
8958                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
8959             }
8960             break;
8961         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
8962         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: {
8963            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
8964 
8965            OMX_BUFFERHEADERTYPE  *omx_base_address = omx->m_out_mem_ptr;
8966            vdec_bufferpayload *omx_ptr_outputbuffer = omx->drv_ctx.ptr_outputbuffer;
8967            vdec_output_frameinfo *omx_ptr_respbuffer = omx->drv_ctx.ptr_respbuffer;
8968 
8969            if (omx->client_buffers.is_color_conversion_enabled()) {
8970                omx_base_address = omx->m_intermediate_out_mem_ptr;
8971                omx_ptr_outputbuffer = omx->drv_ctx.ptr_intermediate_outputbuffer;
8972                omx_ptr_respbuffer = omx->drv_ctx.ptr_intermediate_respbuffer;
8973            }
8974 
8975            if (v4l2_buf_ptr == NULL || omx_base_address == NULL ||
8976                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
8977                omxhdr = NULL;
8978                vdec_msg->status_code = VDEC_S_EFATAL;
8979                break;
8980            }
8981            plane = v4l2_buf_ptr->m.planes;
8982            omxhdr = omx_base_address + v4l2_buf_ptr->index;
8983 
8984            if (omxhdr && omxhdr->pOutputPortPrivate &&
8985                ((omxhdr - omx_base_address) < (int)omx->drv_ctx.op_buf.actualcount) &&
8986                    (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
8987                      - omx_ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
8988 
8989                omxhdr->pMarkData = (OMX_PTR)(unsigned long)plane[0].reserved[3];
8990                omxhdr->hMarkTargetComponent = (OMX_HANDLETYPE)(unsigned long)plane[0].reserved[4];
8991 
8992                if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
8993                    omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
8994                    omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
8995                    omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
8996                    omxhdr->nFlags = 0;
8997 
8998                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
8999                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
9000                         //rc = -1;
9001                    }
9002                    if (omxhdr->nFilledLen) {
9003                        omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
9004                    }
9005                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
9006                        omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
9007                    } else {
9008                        omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
9009                    }
9010 #if NEED_TO_REVISIT
9011                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
9012                        omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
9013                    }
9014 #endif
9015                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
9016                         omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
9017                         DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
9018                                         omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
9019                    }
9020 
9021                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
9022                        omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
9023                    }
9024 
9025                    output_respbuf = (struct vdec_output_frameinfo *)\
9026                             omxhdr->pOutputPortPrivate;
9027                    if (!output_respbuf) {
9028                      DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
9029                      return -1;
9030                    }
9031                    output_respbuf->len = vdec_msg->msgdata.output_frame.len;
9032                    output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
9033 
9034                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
9035                        output_respbuf->pic_type = PICTURE_TYPE_I;
9036                    }
9037                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
9038                        output_respbuf->pic_type = PICTURE_TYPE_P;
9039                    }
9040                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
9041                        output_respbuf->pic_type = PICTURE_TYPE_B;
9042                    }
9043 
9044                    if (vdec_msg->msgdata.output_frame.len) {
9045                        DEBUG_PRINT_LOW("Processing extradata");
9046                        reconfig_event_sent = omx->handle_extradata(omxhdr);
9047 
9048                        if (omx->m_extradata_info.output_crop_updated) {
9049                            DEBUG_PRINT_LOW("Read FBD crop from output extra data");
9050                            vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
9051                            vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
9052                            vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
9053                            vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
9054                            vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
9055                            vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
9056                            memcpy(vdec_msg->msgdata.output_frame.misrinfo,
9057                                 omx->m_extradata_info.misr_info, sizeof(vdec_misrinfo));
9058                        } else {
9059                            DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
9060                            vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2];
9061                            vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3];
9062                            vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4];
9063                            vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
9064                            vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
9065                            vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
9066 
9067                            /* Copy these values back to OMX internal variables to make both handlign same*/
9068 
9069                            omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
9070                            omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top;
9071                            omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
9072                            omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
9073                            omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
9074                            omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
9075                        }
9076                    }
9077 
9078                    vdec_msg->msgdata.output_frame.bufferaddr =
9079                        omx_ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
9080 
9081                    DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
9082                            " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
9083                            omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
9084                            omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
9085                            vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
9086                            (unsigned int)vdec_msg->msgdata.output_frame.len,
9087                            vdec_msg->msgdata.output_frame.framesize.left,
9088                            vdec_msg->msgdata.output_frame.framesize.top,
9089                            vdec_msg->msgdata.output_frame.framesize.right,
9090                            vdec_msg->msgdata.output_frame.framesize.bottom);
9091 
9092                    /* Post event if resolution OR crop changed */
9093                    /* filled length will be changed if resolution changed */
9094                    /* Crop parameters can be changed even without resolution change */
9095                    if (omxhdr->nFilledLen
9096                        && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
9097                        || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
9098                        || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
9099                        || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
9100                        || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
9101                        || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
9102                        || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
9103 
9104                        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",
9105                                omx->prev_n_filled_len,
9106                                omx->drv_ctx.video_resolution.frame_width,
9107                                omx->drv_ctx.video_resolution.frame_height,
9108                                omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
9109                                omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
9110                                omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
9111                                vdec_msg->msgdata.output_frame.picsize.frame_height,
9112                                vdec_msg->msgdata.output_frame.framesize.left,
9113                                vdec_msg->msgdata.output_frame.framesize.top,
9114                                vdec_msg->msgdata.output_frame.framesize.right,
9115                                vdec_msg->msgdata.output_frame.framesize.bottom);
9116 
9117                        memcpy(&omx->drv_ctx.frame_size,
9118                                &vdec_msg->msgdata.output_frame.framesize,
9119                                sizeof(struct vdec_framesize));
9120 
9121                        omx->drv_ctx.video_resolution.frame_width =
9122                                vdec_msg->msgdata.output_frame.picsize.frame_width;
9123                        omx->drv_ctx.video_resolution.frame_height =
9124                                vdec_msg->msgdata.output_frame.picsize.frame_height;
9125                        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
9126                            omx->drv_ctx.video_resolution.stride =
9127                                VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
9128                            omx->drv_ctx.video_resolution.scan_lines =
9129                                VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
9130                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
9131                            omx->drv_ctx.video_resolution.stride =
9132                                VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
9133                            omx->drv_ctx.video_resolution.scan_lines =
9134                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
9135                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
9136                            omx->drv_ctx.video_resolution.stride =
9137                                VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width);
9138                            omx->drv_ctx.video_resolution.scan_lines =
9139                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
9140                         }
9141                         else if(omx->drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
9142                            omx->drv_ctx.video_resolution.stride =
9143                                VENUS_Y_STRIDE(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_width);
9144                            omx->drv_ctx.video_resolution.scan_lines =
9145                                VENUS_Y_SCANLINES(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_height);
9146                         }
9147 
9148                        if(!reconfig_event_sent) {
9149                            omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
9150                                            OMX_IndexConfigCommonOutputCrop,
9151                                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9152                            reconfig_event_sent = true;
9153                        } else {
9154                            /* Update C2D with new resolution */
9155                            if (!omx->client_buffers.update_buffer_req()) {
9156                                DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
9157                            }
9158                        }
9159                    }
9160 
9161                    if (omxhdr->nFilledLen)
9162                        omx->prev_n_filled_len = omxhdr->nFilledLen;
9163 
9164                    if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer &&
9165                        vdec_msg->msgdata.output_frame.bufferaddr)
9166                        memcpy ( omxhdr->pBuffer, (void *)
9167                                ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
9168                                 (unsigned long)vdec_msg->msgdata.output_frame.offset),
9169                                vdec_msg->msgdata.output_frame.len);
9170                } else {
9171                    DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
9172                            (unsigned int)vdec_msg->msgdata.output_frame.len,
9173                            omxhdr->nAllocLen, omx->prev_n_filled_len);
9174                    omxhdr->nFilledLen = 0;
9175                }
9176 
9177                omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
9178                         OMX_COMPONENT_GENERATE_FBD);
9179 
9180             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
9181                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
9182                         OMX_COMPONENT_GENERATE_EOS_DONE);
9183             } else {
9184                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
9185                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
9186             }
9187             break;
9188         }
9189         case VDEC_MSG_EVT_CONFIG_CHANGED:
9190             DEBUG_PRINT_HIGH("Port settings changed");
9191             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
9192             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
9193             omx->isPortReconfigInsufficient = vdec_msg->msgdata.output_frame.flags;
9194             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
9195                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9196             break;
9197         default:
9198             break;
9199     }
9200     return rc;
9201 }
9202 
9203 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
9204         OMX_HANDLETYPE hComp,
9205         OMX_BUFFERHEADERTYPE *buffer
9206         )
9207 {
9208     unsigned address,p2,id;
9209     DEBUG_PRINT_LOW("Empty this arbitrary");
9210 
9211     if (buffer == NULL) {
9212         return OMX_ErrorBadParameter;
9213     }
9214     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
9215     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
9216             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
9217 
9218     /* return zero length and not an EOS buffer */
9219     /* return buffer if input flush in progress */
9220     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
9221                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
9222         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
9223         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
9224         return OMX_ErrorNone;
9225     }
9226 
9227     if (psource_frame == NULL) {
9228         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
9229         psource_frame = buffer;
9230         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
9231         push_input_buffer (hComp);
9232     } else {
9233         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
9234         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
9235                     (unsigned)NULL)) {
9236             return OMX_ErrorBadParameter;
9237         }
9238     }
9239 
9240     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
9241         codec_config_flag = false;
9242     }
9243     return OMX_ErrorNone;
9244 }
9245 
9246 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
9247 {
9248     unsigned long address,p2,id;
9249     OMX_ERRORTYPE ret = OMX_ErrorNone;
9250 
9251     if (pdest_frame == NULL || psource_frame == NULL) {
9252         /*Check if we have a destination buffer*/
9253         if (pdest_frame == NULL) {
9254             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
9255             if (m_input_free_q.m_size) {
9256                 m_input_free_q.pop_entry(&address,&p2,&id);
9257                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
9258                 pdest_frame->nFilledLen = 0;
9259                 pdest_frame->nTimeStamp = LLONG_MAX;
9260                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
9261             }
9262         }
9263 
9264         /*Check if we have a destination buffer*/
9265         if (psource_frame == NULL) {
9266             DEBUG_PRINT_LOW("Get a source buffer from the queue");
9267             if (m_input_pending_q.m_size) {
9268                 m_input_pending_q.pop_entry(&address,&p2,&id);
9269                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9270                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9271                         psource_frame->nTimeStamp);
9272                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9273                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9274 
9275             }
9276         }
9277 
9278     }
9279 
9280     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
9281         switch (codec_type_parse) {
9282             case CODEC_TYPE_MPEG2:
9283                 ret =  push_input_sc_codec(hComp);
9284                 break;
9285             case CODEC_TYPE_H264:
9286                 ret = push_input_h264(hComp);
9287                 break;
9288             case CODEC_TYPE_HEVC:
9289                 ret = push_input_hevc(hComp);
9290                 break;
9291             default:
9292                 break;
9293         }
9294         if (ret != OMX_ErrorNone) {
9295             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
9296             omx_report_error ();
9297             break;
9298         }
9299     }
9300 
9301     return ret;
9302 }
9303 
9304 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
9305 {
9306     OMX_U32 partial_frame = 1;
9307     OMX_BOOL generate_ebd = OMX_TRUE;
9308     unsigned long address = 0, p2 = 0, id = 0;
9309 
9310     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
9311             psource_frame,psource_frame->nTimeStamp);
9312     if (m_frame_parser.parse_sc_frame(psource_frame,
9313                 pdest_frame,&partial_frame) == -1) {
9314         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9315         return OMX_ErrorBadParameter;
9316     }
9317 
9318     if (partial_frame == 0) {
9319         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
9320                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
9321 
9322 
9323         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
9324         /*First Parsed buffer will have only header Hence skip*/
9325         if (frame_count == 0) {
9326             frame_count++;
9327         } else {
9328             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9329             if (pdest_frame->nFilledLen) {
9330                 /*Push the frame to the Decoder*/
9331                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9332                     return OMX_ErrorBadParameter;
9333                 }
9334                 frame_count++;
9335                 pdest_frame = NULL;
9336 
9337                 if (m_input_free_q.m_size) {
9338                     m_input_free_q.pop_entry(&address,&p2,&id);
9339                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9340                     pdest_frame->nFilledLen = 0;
9341                 }
9342             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
9343                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
9344                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
9345                         (unsigned)NULL);
9346                 pdest_frame = NULL;
9347             }
9348         }
9349     } else {
9350         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
9351         /*Check if Destination Buffer is full*/
9352         if (pdest_frame->nAllocLen ==
9353                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
9354             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
9355             return OMX_ErrorStreamCorrupt;
9356         }
9357     }
9358 
9359     if (psource_frame->nFilledLen == 0) {
9360         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9361             if (pdest_frame) {
9362                 pdest_frame->nFlags |= psource_frame->nFlags;
9363                 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
9364                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
9365                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9366                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9367                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
9368                 /*Push the frame to the Decoder*/
9369                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9370                     return OMX_ErrorBadParameter;
9371                 }
9372                 frame_count++;
9373                 pdest_frame = NULL;
9374             } else {
9375                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
9376                 generate_ebd = OMX_FALSE;
9377             }
9378         }
9379         if (generate_ebd) {
9380             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
9381             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9382             psource_frame = NULL;
9383 
9384             if (m_input_pending_q.m_size) {
9385                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9386                 m_input_pending_q.pop_entry(&address,&p2,&id);
9387                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9388                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9389                         psource_frame->nTimeStamp);
9390                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9391                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9392             }
9393         }
9394     }
9395     return OMX_ErrorNone;
9396 }
9397 
9398 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
9399 {
9400     OMX_U32 partial_frame = 1;
9401     unsigned long address = 0, p2 = 0, id = 0;
9402     OMX_BOOL isNewFrame = OMX_FALSE;
9403     OMX_BOOL generate_ebd = OMX_TRUE;
9404 
9405     if (h264_scratch.pBuffer == NULL) {
9406         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
9407         return OMX_ErrorBadParameter;
9408     }
9409     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
9410             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
9411     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
9412     if (h264_scratch.nFilledLen && look_ahead_nal) {
9413         look_ahead_nal = false;
9414         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9415                 h264_scratch.nFilledLen) {
9416             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9417                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
9418             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9419             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
9420             h264_scratch.nFilledLen = 0;
9421         } else {
9422             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
9423             return OMX_ErrorBadParameter;
9424         }
9425     }
9426 
9427     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
9428        in EOS flag getting associated with the destination
9429     */
9430     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
9431             pdest_frame->nFilledLen) {
9432         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
9433         generate_ebd = OMX_FALSE;
9434     }
9435 
9436     if (nal_length == 0) {
9437         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
9438         if (m_frame_parser.parse_sc_frame(psource_frame,
9439                     &h264_scratch,&partial_frame) == -1) {
9440             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9441             return OMX_ErrorBadParameter;
9442         }
9443     } else {
9444         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
9445         if (m_frame_parser.parse_h264_nallength(psource_frame,
9446                     &h264_scratch,&partial_frame) == -1) {
9447             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9448             return OMX_ErrorBadParameter;
9449         }
9450     }
9451 
9452     if (partial_frame == 0) {
9453         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9454             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9455             nal_count++;
9456             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9457             h264_scratch.nFlags = psource_frame->nFlags;
9458         } else {
9459             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
9460             if (h264_scratch.nFilledLen) {
9461                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
9462                         NALU_TYPE_SPS);
9463 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9464                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
9465                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9466                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
9467                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9468                     // If timeinfo is present frame info from SEI is already processed
9469                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9470                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
9471 #endif
9472                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9473                 nal_count++;
9474                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
9475                     pdest_frame->nTimeStamp = h264_last_au_ts;
9476                     pdest_frame->nFlags = h264_last_au_flags;
9477 #ifdef PANSCAN_HDLR
9478                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9479                         h264_parser->update_panscan_data(h264_last_au_ts);
9480 #endif
9481                 }
9482                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
9483                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
9484                     h264_last_au_ts = h264_scratch.nTimeStamp;
9485                     h264_last_au_flags = h264_scratch.nFlags;
9486 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9487                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9488                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
9489                         if (!VALID_TS(h264_last_au_ts))
9490                             h264_last_au_ts = ts_in_sei;
9491                     }
9492 #endif
9493                 } else
9494                     h264_last_au_ts = LLONG_MAX;
9495             }
9496 
9497             if (!isNewFrame) {
9498                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9499                         h264_scratch.nFilledLen) {
9500                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
9501                             (unsigned int)h264_scratch.nFilledLen);
9502                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9503                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
9504                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9505                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
9506                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
9507                     h264_scratch.nFilledLen = 0;
9508                 } else {
9509                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
9510                     return OMX_ErrorBadParameter;
9511                 }
9512             } else if(h264_scratch.nFilledLen) {
9513                 look_ahead_nal = true;
9514                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
9515                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9516                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9517                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
9518 
9519                 if (pdest_frame->nFilledLen == 0) {
9520                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
9521                     look_ahead_nal = false;
9522                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9523                             h264_scratch.nFilledLen) {
9524                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9525                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9526                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9527                         h264_scratch.nFilledLen = 0;
9528                     } else {
9529                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
9530                         return OMX_ErrorBadParameter;
9531                     }
9532                 } else {
9533                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9534                         DEBUG_PRINT_LOW("Reset the EOS Flag");
9535                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9536                     }
9537                     /*Push the frame to the Decoder*/
9538                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9539                         return OMX_ErrorBadParameter;
9540                     }
9541                     //frame_count++;
9542                     pdest_frame = NULL;
9543                     if (m_input_free_q.m_size) {
9544                         m_input_free_q.pop_entry(&address,&p2,&id);
9545                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9546                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
9547                         pdest_frame->nFilledLen = 0;
9548                         pdest_frame->nFlags = 0;
9549                         pdest_frame->nTimeStamp = LLONG_MAX;
9550                     }
9551                 }
9552             }
9553         }
9554     } else {
9555         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
9556         /*Check if Destination Buffer is full*/
9557         if (h264_scratch.nAllocLen ==
9558                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9559             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9560             return OMX_ErrorStreamCorrupt;
9561         }
9562     }
9563 
9564     if (!psource_frame->nFilledLen) {
9565         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
9566 
9567         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9568             if (pdest_frame) {
9569                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9570                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9571                         h264_scratch.nFilledLen) {
9572                     if(pdest_frame->nFilledLen == 0) {
9573                         /* No residual frame from before, send whatever
9574                          * we have left */
9575                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9576                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
9577                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9578                         h264_scratch.nFilledLen = 0;
9579                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9580                     } else {
9581                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9582                         if(!isNewFrame) {
9583                             /* Have a residual frame, but we know that the
9584                              * AU in this frame is belonging to whatever
9585                              * frame we had left over.  So append it */
9586                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9587                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
9588                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9589                              h264_scratch.nFilledLen = 0;
9590                              if (h264_last_au_ts != LLONG_MAX)
9591                                  pdest_frame->nTimeStamp = h264_last_au_ts;
9592                         } else {
9593                             /* Completely new frame, let's just push what
9594                              * we have now.  The resulting EBD would trigger
9595                              * another push */
9596                             generate_ebd = OMX_FALSE;
9597                             pdest_frame->nTimeStamp = h264_last_au_ts;
9598                             h264_last_au_ts = h264_scratch.nTimeStamp;
9599                         }
9600                     }
9601                 } else {
9602                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
9603                     return OMX_ErrorBadParameter;
9604                 }
9605 
9606                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
9607                 if(generate_ebd == OMX_TRUE) {
9608                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9609                 }
9610 
9611                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
9612                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9613                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
9614 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9615                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9616                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
9617                     if (!VALID_TS(pdest_frame->nTimeStamp))
9618                         pdest_frame->nTimeStamp = ts_in_sei;
9619                 }
9620 #endif
9621                 /*Push the frame to the Decoder*/
9622                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9623                     return OMX_ErrorBadParameter;
9624                 }
9625                 frame_count++;
9626                 pdest_frame = NULL;
9627             } else {
9628                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9629                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9630                 generate_ebd = OMX_FALSE;
9631             }
9632         }
9633     }
9634     if (generate_ebd && !psource_frame->nFilledLen) {
9635         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9636         psource_frame = NULL;
9637         if (m_input_pending_q.m_size) {
9638             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9639             m_input_pending_q.pop_entry(&address,&p2,&id);
9640             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9641             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
9642                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9643         }
9644     }
9645     return OMX_ErrorNone;
9646 }
9647 
9648 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
9649 {
9650     OMX_ERRORTYPE rc = OMX_ErrorNone;
9651     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
9652         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
9653         if (pDst->nTimeStamp == LLONG_MAX) {
9654             pDst->nTimeStamp = pSrc->nTimeStamp;
9655             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
9656         }
9657         pDst->nFilledLen += pSrc->nFilledLen;
9658         pSrc->nFilledLen = 0;
9659     } else {
9660         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
9661         rc = OMX_ErrorBadParameter;
9662     }
9663     return rc;
9664 }
9665 
9666 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
9667 {
9668     OMX_U32 partial_frame = 1;
9669     unsigned long address,p2,id;
9670     OMX_BOOL isNewFrame = OMX_FALSE;
9671     OMX_BOOL generate_ebd = OMX_TRUE;
9672     OMX_ERRORTYPE rc = OMX_ErrorNone;
9673     if (h264_scratch.pBuffer == NULL) {
9674         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
9675         return OMX_ErrorBadParameter;
9676     }
9677 
9678     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
9679             pdest_frame nFilledLen %u nTimeStamp %lld",
9680             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9681 
9682     if (h264_scratch.nFilledLen && look_ahead_nal) {
9683         look_ahead_nal = false;
9684         rc = copy_buffer(pdest_frame, &h264_scratch);
9685         if (rc != OMX_ErrorNone) {
9686             return rc;
9687         }
9688     }
9689 
9690     if (nal_length == 0) {
9691         if (m_frame_parser.parse_sc_frame(psource_frame,
9692                     &h264_scratch,&partial_frame) == -1) {
9693             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9694             return OMX_ErrorBadParameter;
9695         }
9696     } else {
9697         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
9698         if (m_frame_parser.parse_h264_nallength(psource_frame,
9699                     &h264_scratch,&partial_frame) == -1) {
9700             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9701             return OMX_ErrorBadParameter;
9702         }
9703     }
9704 
9705     if (partial_frame == 0) {
9706         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9707             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9708             nal_count++;
9709             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9710             h264_scratch.nFlags = psource_frame->nFlags;
9711         } else {
9712             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
9713             if (h264_scratch.nFilledLen) {
9714                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
9715                 nal_count++;
9716             }
9717 
9718             if (!isNewFrame) {
9719                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
9720                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
9721                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
9722                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9723                 rc = copy_buffer(pdest_frame, &h264_scratch);
9724                 if (rc != OMX_ErrorNone) {
9725                     return rc;
9726                 }
9727             } else {
9728                 look_ahead_nal = true;
9729                 if (pdest_frame->nFilledLen == 0) {
9730                     look_ahead_nal = false;
9731                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
9732                     rc = copy_buffer(pdest_frame, &h264_scratch);
9733                     if (rc != OMX_ErrorNone) {
9734                         return OMX_ErrorBadParameter;
9735                     }
9736                 } else {
9737                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9738                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9739                     }
9740                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
9741                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
9742                             nFilledLen %u nTimeStamp %lld",
9743                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
9744                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
9745                             h264_scratch.nTimeStamp);
9746                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9747                         return OMX_ErrorBadParameter;
9748                     }
9749                     pdest_frame = NULL;
9750                     if (m_input_free_q.m_size) {
9751                         m_input_free_q.pop_entry(&address, &p2, &id);
9752                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9753                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
9754                         pdest_frame->nFilledLen = 0;
9755                         pdest_frame->nFlags = 0;
9756                         pdest_frame->nTimeStamp = LLONG_MAX;
9757                     }
9758                 }
9759             }
9760         }
9761     } else {
9762         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
9763                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
9764                 nFilledLen %u nTimeStamp %lld",
9765                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
9766                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
9767                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
9768 
9769         if (h264_scratch.nAllocLen ==
9770                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9771             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9772             return OMX_ErrorStreamCorrupt;
9773         }
9774     }
9775 
9776     if (!psource_frame->nFilledLen) {
9777         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
9778         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9779             if (pdest_frame) {
9780                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9781                 rc = copy_buffer(pdest_frame, &h264_scratch);
9782                 if ( rc != OMX_ErrorNone ) {
9783                     return rc;
9784                 }
9785                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9786                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9787                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
9788                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9789                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9790                     return OMX_ErrorBadParameter;
9791                 }
9792                 frame_count++;
9793                 pdest_frame = NULL;
9794             } else {
9795                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9796                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9797                 generate_ebd = OMX_FALSE;
9798             }
9799         }
9800     }
9801 
9802     if (generate_ebd && !psource_frame->nFilledLen) {
9803         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
9804         psource_frame = NULL;
9805         if (m_input_pending_q.m_size) {
9806             m_input_pending_q.pop_entry(&address, &p2, &id);
9807             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9808             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
9809                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
9810         }
9811     }
9812     return OMX_ErrorNone;
9813 }
9814 
9815 #ifdef USE_GBM
9816 bool omx_vdec::alloc_map_gbm_memory(OMX_U32 w,OMX_U32 h,int dev_fd,
9817                  struct vdec_gbm *op_buf_gbm_info, int flag)
9818 {
9819 
9820     uint32 flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
9821     struct gbm_device *gbm = NULL;
9822     struct gbm_bo *bo = NULL;
9823     int bo_fd = -1, meta_fd = -1;
9824     if (!op_buf_gbm_info || dev_fd < 0 ) {
9825         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9826         return FALSE;
9827     }
9828 
9829     gbm = gbm_create_device(dev_fd);
9830     if (gbm == NULL) {
9831        DEBUG_PRINT_ERROR("create gbm device failed");
9832        return FALSE;
9833     } else {
9834        DEBUG_PRINT_LOW( "Successfully created gbm device");
9835     }
9836     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC)
9837        flags |= GBM_BO_USAGE_UBWC_ALIGNED_QTI;
9838 
9839     DEBUG_PRINT_LOW("create NV12 gbm_bo with width=%d, height=%d", w, h);
9840     bo = gbm_bo_create(gbm, w, h,GBM_FORMAT_NV12,
9841               flags);
9842 
9843     if (bo == NULL) {
9844       DEBUG_PRINT_ERROR("Create bo failed");
9845       gbm_device_destroy(gbm);
9846       return FALSE;
9847     }
9848 
9849     bo_fd = gbm_bo_get_fd(bo);
9850     if (bo_fd < 0) {
9851       DEBUG_PRINT_ERROR("Get bo fd failed");
9852       gbm_bo_destroy(bo);
9853       gbm_device_destroy(gbm);
9854       return FALSE;
9855     }
9856 
9857     gbm_perform(GBM_PERFORM_GET_METADATA_ION_FD, bo, &meta_fd);
9858     if (meta_fd < 0) {
9859       DEBUG_PRINT_ERROR("Get bo meta fd failed");
9860       gbm_bo_destroy(bo);
9861       gbm_device_destroy(gbm);
9862       return FALSE;
9863     }
9864     op_buf_gbm_info->gbm = gbm;
9865     op_buf_gbm_info->bo = bo;
9866     op_buf_gbm_info->bo_fd = bo_fd;
9867     op_buf_gbm_info->meta_fd = meta_fd;
9868 
9869     DEBUG_PRINT_LOW("allocate gbm bo fd meta fd  %p %d %d",bo,bo_fd,meta_fd);
9870     return TRUE;
9871 }
9872 
9873 void omx_vdec::free_gbm_memory(struct vdec_gbm *buf_gbm_info)
9874 {
9875     if(!buf_gbm_info) {
9876       DEBUG_PRINT_ERROR(" GBM: free called with invalid fd/allocdata");
9877       return;
9878     }
9879     DEBUG_PRINT_LOW("free gbm bo fd meta fd  %p %d %d",
9880            buf_gbm_info->bo,buf_gbm_info->bo_fd,buf_gbm_info->meta_fd);
9881 
9882     if (buf_gbm_info->bo)
9883        gbm_bo_destroy(buf_gbm_info->bo);
9884     buf_gbm_info->bo = NULL;
9885 
9886     if (buf_gbm_info->gbm)
9887        gbm_device_destroy(buf_gbm_info->gbm);
9888     buf_gbm_info->gbm = NULL;
9889 
9890     buf_gbm_info->bo_fd = -1;
9891     buf_gbm_info->meta_fd = -1;
9892 }
9893 #endif
9894 #ifndef USE_ION
9895 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
9896         OMX_U32 alignment)
9897 {
9898     struct pmem_allocation allocation;
9899     allocation.size = buffer_size;
9900     allocation.align = clip2(alignment);
9901     if (allocation.align < 4096) {
9902         allocation.align = 4096;
9903     }
9904     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
9905         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
9906                 allocation.align, allocation.size);
9907         return false;
9908     }
9909     return true;
9910 }
9911 #endif
9912 #ifdef USE_ION
9913 bool omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, vdec_ion *ion_info, int flag)
9914 
9915 {
9916     int rc = -EINVAL;
9917     int ion_dev_flag;
9918     struct vdec_ion ion_buf_info;
9919 
9920     if (!ion_info || buffer_size <= 0) {
9921         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9922         return false;
9923     }
9924 
9925     ion_info->dev_fd = ion_open();
9926     if (ion_info->dev_fd < 0) {
9927         DEBUG_PRINT_ERROR("opening ion device failed with ion_fd = %d", ion_info->dev_fd);
9928         return false;
9929     }
9930 
9931 #ifdef HYPERVISOR
9932     flag &= ~ION_FLAG_CACHED;
9933 #endif
9934     ion_info->alloc_data.flags = flag;
9935     ion_info->alloc_data.len = buffer_size;
9936 
9937     ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
9938     if (secure_mode && (ion_info->alloc_data.flags & ION_FLAG_SECURE)) {
9939 #ifdef HYPERVISOR
9940         ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
9941 #else
9942         ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
9943 #endif
9944     }
9945 
9946     /* Use secure display cma heap for obvious reasons. */
9947     if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
9948         ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
9949     }
9950 
9951     rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
9952                       ion_info->alloc_data.heap_id_mask, ion_info->alloc_data.flags,
9953                       &ion_info->data_fd);
9954 
9955     if (rc || ion_info->data_fd < 0) {
9956         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
9957         ion_close(ion_info->dev_fd);
9958         ion_info->data_fd = -1;
9959         ion_info->dev_fd = -1;
9960         return false;
9961     }
9962 
9963     DEBUG_PRINT_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
9964                      ion_info->dev_fd, ion_info->data_fd, (unsigned int)ion_info->alloc_data.len,
9965                      (unsigned int)ion_info->alloc_data.flags,
9966                      (unsigned int)ion_info->alloc_data.heap_id_mask);
9967 
9968     return true;
9969 }
9970 
9971 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
9972 {
9973 
9974     if (!buf_ion_info) {
9975         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
9976         return;
9977     }
9978     DEBUG_PRINT_HIGH("Free ion memory: mmap fd %d ion_dev fd %d len %d flags %#x mask %#x",
9979         buf_ion_info->data_fd, buf_ion_info->dev_fd,
9980         (unsigned int)buf_ion_info->alloc_data.len,
9981         (unsigned int)buf_ion_info->alloc_data.flags,
9982         (unsigned int)buf_ion_info->alloc_data.heap_id_mask);
9983 
9984     if (buf_ion_info->data_fd >= 0) {
9985         close(buf_ion_info->data_fd);
9986         buf_ion_info->data_fd = -1;
9987     }
9988     if (buf_ion_info->dev_fd >= 0) {
9989         ion_close(buf_ion_info->dev_fd);
9990         buf_ion_info->dev_fd = -1;
9991     }
9992 }
9993 
9994 void omx_vdec::do_cache_operations(int fd)
9995 {
9996     if (fd < 0)
9997         return;
9998 
9999     struct dma_buf_sync dma_buf_sync_data[2];
10000     dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
10001     dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
10002 
10003     for(unsigned int i=0; i<2; i++) {
10004         int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
10005         if (rc < 0) {
10006             DEBUG_PRINT_ERROR("Failed DMA_BUF_IOCTL_SYNC %s fd : %d", i==0?"start":"end", fd);
10007             return;
10008         }
10009     }
10010 }
10011 
10012 #endif
10013 void omx_vdec::free_output_buffer_header(bool intermediate)
10014 {
10015     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
10016     output_use_buffer = false;
10017     ouput_egl_buffers = false;
10018 
10019     OMX_BUFFERHEADERTYPE  **omx_base_address =
10020         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
10021     vdec_bufferpayload **omx_ptr_outputbuffer =
10022         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
10023     vdec_output_frameinfo **omx_ptr_respbuffer =
10024         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
10025     vdec_ion **omx_op_buf_ion_info =
10026         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
10027 #ifdef USE_GBM
10028     vdec_gbm **omx_op_buf_gbm_info =
10029         intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
10030 #endif
10031 
10032     if (*omx_base_address) {
10033         free (*omx_base_address);
10034         *omx_base_address = NULL;
10035     }
10036 
10037     if (m_platform_list) {
10038         free(m_platform_list);
10039         m_platform_list = NULL;
10040     }
10041 
10042     if (*omx_ptr_respbuffer) {
10043         free (*omx_ptr_respbuffer);
10044         *omx_ptr_respbuffer = NULL;
10045     }
10046     if (*omx_ptr_outputbuffer) {
10047         free (*omx_ptr_outputbuffer);
10048         *omx_ptr_outputbuffer = NULL;
10049     }
10050 #ifdef USE_GBM
10051     if (*omx_op_buf_gbm_info) {
10052         DEBUG_PRINT_LOW("Free o/p gbm context");
10053         free(*omx_op_buf_gbm_info);
10054         *omx_op_buf_gbm_info = NULL;
10055     }
10056     if (drv_ctx.gbm_device_fd >= 0) {
10057        DEBUG_PRINT_LOW("Close gbm device");
10058        close(drv_ctx.gbm_device_fd);
10059        drv_ctx.gbm_device_fd = -1;
10060     }
10061 
10062 #elif defined USE_ION
10063     if (*omx_op_buf_ion_info) {
10064         DEBUG_PRINT_LOW("Free o/p ion context");
10065         free(*omx_op_buf_ion_info);
10066         *omx_op_buf_ion_info = NULL;
10067     }
10068 #endif
10069     if (intermediate == false && client_buffers.is_color_conversion_enabled()) {
10070         free_output_buffer_header(true);
10071     }
10072 }
10073 
10074 void omx_vdec::free_input_buffer_header()
10075 {
10076     input_use_buffer = false;
10077     if (arbitrary_bytes) {
10078         if (m_inp_heap_ptr) {
10079             DEBUG_PRINT_LOW("Free input Heap Pointer");
10080             free (m_inp_heap_ptr);
10081             m_inp_heap_ptr = NULL;
10082         }
10083 
10084         if (m_phdr_pmem_ptr) {
10085             DEBUG_PRINT_LOW("Free input pmem header Pointer");
10086             free (m_phdr_pmem_ptr);
10087             m_phdr_pmem_ptr = NULL;
10088         }
10089     }
10090     if (m_inp_mem_ptr) {
10091         DEBUG_PRINT_LOW("Free input pmem Pointer area");
10092         free (m_inp_mem_ptr);
10093         m_inp_mem_ptr = NULL;
10094     }
10095     /* We just freed all the buffer headers, every thing in m_input_free_q,
10096      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
10097     while (m_input_free_q.m_size) {
10098         unsigned long address, p2, id;
10099         m_input_free_q.pop_entry(&address, &p2, &id);
10100     }
10101     while (m_input_pending_q.m_size) {
10102         unsigned long address, p2, id;
10103         m_input_pending_q.pop_entry(&address, &p2, &id);
10104     }
10105     pdest_frame = NULL;
10106     psource_frame = NULL;
10107     if (drv_ctx.ptr_inputbuffer) {
10108         DEBUG_PRINT_LOW("Free Driver Context pointer");
10109         free (drv_ctx.ptr_inputbuffer);
10110         drv_ctx.ptr_inputbuffer = NULL;
10111     }
10112 #ifdef USE_ION
10113     if (drv_ctx.ip_buf_ion_info) {
10114         DEBUG_PRINT_LOW("Free ion context");
10115         free(drv_ctx.ip_buf_ion_info);
10116         drv_ctx.ip_buf_ion_info = NULL;
10117     }
10118 #endif
10119 }
10120 
10121 void omx_vdec::free_output_extradata_buffer_header() {
10122     client_extradata = false;
10123     if (m_client_output_extradata_mem_ptr) {
10124         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
10125         free(m_client_output_extradata_mem_ptr);
10126         m_client_output_extradata_mem_ptr = NULL;
10127     }
10128 }
10129 
10130 int omx_vdec::stream_off(OMX_U32 port)
10131 {
10132     enum v4l2_buf_type btype;
10133     int rc = 0;
10134     enum v4l2_ports v4l2_port = OUTPUT_PORT;
10135     struct v4l2_requestbuffers bufreq;
10136 
10137     if (port == OMX_CORE_INPUT_PORT_INDEX) {
10138         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10139         v4l2_port = OUTPUT_PORT;
10140     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10141         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10142         v4l2_port = CAPTURE_PORT;
10143     } else if (port == OMX_ALL) {
10144         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
10145         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
10146 
10147         if (!rc_input)
10148             return rc_input;
10149         else
10150             return rc_output;
10151     }
10152 
10153     if (!streaming[v4l2_port]) {
10154         // already streamed off, warn and move on
10155         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
10156                 " which is already streamed off", v4l2_port);
10157         return 0;
10158     }
10159 
10160     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
10161 
10162     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
10163     if (rc) {
10164         /*TODO: How to handle this case */
10165         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
10166     } else {
10167         streaming[v4l2_port] = false;
10168     }
10169 
10170     if (port == OMX_CORE_INPUT_PORT_INDEX) {
10171         bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10172     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10173         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10174     }
10175 
10176     bufreq.memory = V4L2_MEMORY_USERPTR;
10177     bufreq.count = 0;
10178     rc = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10179     if (rc) {
10180         DEBUG_PRINT_ERROR("Failed to release buffers on %d Port", v4l2_port);
10181     }
10182     return rc;
10183 }
10184 
10185 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
10186 {
10187     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10188     struct v4l2_control control;
10189     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
10190     unsigned int final_extra_data_size = 0;
10191     struct v4l2_format fmt;
10192     int ret = 0;
10193     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10194             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10195 
10196     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10197         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10198         fmt.fmt.pix_mp.pixelformat = output_capability;
10199         control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
10200     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10201         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10202         fmt.fmt.pix_mp.pixelformat = capture_capability;
10203         control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
10204     } else {
10205         eRet = OMX_ErrorBadParameter;
10206     }
10207     if (eRet == OMX_ErrorNone) {
10208         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control);
10209     }
10210     if (ret) {
10211         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10212         /*TODO: How to handle this case */
10213         eRet = OMX_ErrorInsufficientResources;
10214         return eRet;
10215     }
10216     buffer_prop->actualcount = buffer_prop->mincount = control.value;
10217     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10218             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10219 
10220     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10221 
10222     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
10223         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
10224     DEBUG_PRINT_HIGH("Buffer Size = %d, type = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.type);
10225 
10226     if (ret) {
10227         /*TODO: How to handle this case */
10228         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10229         eRet = OMX_ErrorInsufficientResources;
10230     } else {
10231         int extra_idx = 0;
10232 
10233         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10234         buf_size = buffer_prop->buffer_size;
10235         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
10236         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
10237             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
10238         } else if (extra_idx >= VIDEO_MAX_PLANES) {
10239             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
10240             return OMX_ErrorBadParameter;
10241         }
10242 
10243         default_extra_data_size = VENUS_EXTRADATA_SIZE(
10244                 drv_ctx.video_resolution.frame_height,
10245                 drv_ctx.video_resolution.frame_width);
10246         final_extra_data_size = extra_data_size > default_extra_data_size ?
10247             extra_data_size : default_extra_data_size;
10248 
10249         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
10250             (~(buffer_prop->alignment - 1));
10251 
10252         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
10253         drv_ctx.extradata_info.count = buffer_prop->actualcount;
10254         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
10255         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10256         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
10257                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
10258         if (extra_data_size)
10259             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
10260                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
10261 
10262         if (in_reconfig) // BufReq will be set to driver when port is disabled
10263             buffer_prop->buffer_size = buf_size;
10264         else if (buf_size != buffer_prop->buffer_size) {
10265             buffer_prop->buffer_size = buf_size;
10266             eRet = set_buffer_req(buffer_prop);
10267         }
10268     }
10269     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
10270             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10271     return eRet;
10272 }
10273 
10274 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
10275 {
10276     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10277     unsigned buf_size = 0;
10278     struct v4l2_format fmt, c_fmt;
10279     struct v4l2_requestbuffers bufreq;
10280     int ret = 0;
10281     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
10282             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10283     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10284     if (buf_size != buffer_prop->buffer_size) {
10285         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
10286                 (unsigned int)buffer_prop->buffer_size, buf_size);
10287         eRet = OMX_ErrorBadParameter;
10288     } else {
10289         memset(&fmt, 0x0, sizeof(struct v4l2_format));
10290         memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
10291         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
10292         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
10293         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10294 
10295         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10296             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10297             fmt.fmt.pix_mp.pixelformat = output_capability;
10298             DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10299                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10300                 fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.pixelformat);
10301             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10302         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10303             c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10304             c_fmt.fmt.pix_mp.pixelformat = capture_capability;
10305             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
10306             c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10307             DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10308                 c_fmt.type, c_fmt.fmt.pix_mp.width, c_fmt.fmt.pix_mp.height,
10309                 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage, c_fmt.fmt.pix_mp.pixelformat);
10310             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
10311         } else {
10312             eRet = OMX_ErrorBadParameter;
10313         }
10314         if (ret) {
10315             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
10316             eRet = OMX_ErrorInsufficientResources;
10317         }
10318 
10319         bufreq.memory = V4L2_MEMORY_USERPTR;
10320         bufreq.count = buffer_prop->actualcount;
10321         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10322             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10323         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10324             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10325         } else {
10326             eRet = OMX_ErrorBadParameter;
10327         }
10328 
10329         if (eRet == OMX_ErrorNone) {
10330             DEBUG_PRINT_LOW("REQBUFS: type %d count %d", bufreq.type, bufreq.count);
10331             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10332         }
10333 
10334         if (ret) {
10335             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
10336             /*TODO: How to handle this case */
10337             eRet = OMX_ErrorInsufficientResources;
10338         } else if (bufreq.count < buffer_prop->actualcount) {
10339             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
10340                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
10341                     buffer_prop->actualcount, bufreq.count);
10342             eRet = OMX_ErrorInsufficientResources;
10343         } else {
10344             if (!client_buffers.update_buffer_req()) {
10345                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
10346                 eRet = OMX_ErrorInsufficientResources;
10347             }
10348         }
10349     }
10350     return eRet;
10351 }
10352 
10353 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
10354 {
10355     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10356     return eRet;
10357 }
10358 
10359 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
10360 {
10361     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10362     struct v4l2_format fmt;
10363     if (!portDefn) {
10364         DEBUG_PRINT_ERROR("update_portdef: invalid params");
10365         return OMX_ErrorBadParameter;
10366     }
10367     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
10368     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
10369     portDefn->eDomain    = OMX_PortDomainVideo;
10370     memset(&fmt, 0x0, sizeof(struct v4l2_format));
10371     if (0 == portDefn->nPortIndex) {
10372         int ret = 0;
10373         if (secure_mode) {
10374             fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10375             fmt.fmt.pix_mp.pixelformat = output_capability;
10376             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10377             if (ret) {
10378                 DEBUG_PRINT_ERROR("Get Resolution failed");
10379                 return OMX_ErrorHardware;
10380             }
10381             drv_ctx.ip_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10382         }
10383         portDefn->eDir =  OMX_DirInput;
10384         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
10385         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
10386         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
10387         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10388         portDefn->format.video.eCompressionFormat = eCompressionFormat;
10389         //for input port, always report the fps value set by client,
10390         //to distinguish whether client got valid fps from parser.
10391         portDefn->format.video.xFramerate = m_fps_received;
10392         portDefn->bEnabled   = m_inp_bEnabled;
10393         portDefn->bPopulated = m_inp_bPopulated;
10394 
10395         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10396         fmt.fmt.pix_mp.pixelformat = output_capability;
10397         ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10398     } else if (1 == portDefn->nPortIndex) {
10399         unsigned int buf_size = 0;
10400         int ret = 0;
10401        if (!is_down_scalar_enabled) {
10402            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10403            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10404            fmt.fmt.pix_mp.pixelformat = capture_capability;
10405            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10406            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10407        }
10408 
10409        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10410        fmt.fmt.pix_mp.pixelformat = capture_capability;
10411        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10412        if (ret) {
10413            DEBUG_PRINT_ERROR("Get Resolution failed");
10414            return OMX_ErrorHardware;
10415        }
10416        drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10417        if (!client_buffers.update_buffer_req()) {
10418            DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
10419            return OMX_ErrorHardware;
10420        }
10421 
10422         if (!client_buffers.get_buffer_req(buf_size)) {
10423             DEBUG_PRINT_ERROR("update buffer requirements");
10424             return OMX_ErrorHardware;
10425         }
10426         portDefn->nBufferSize = buf_size;
10427         portDefn->eDir =  OMX_DirOutput;
10428         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
10429         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
10430         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10431         if (drv_ctx.frame_rate.fps_denominator > 0)
10432             portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
10433                 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
10434         else {
10435             DEBUG_PRINT_ERROR("Error: Divide by zero");
10436             return OMX_ErrorBadParameter;
10437         }
10438         portDefn->bEnabled   = m_out_bEnabled;
10439         portDefn->bPopulated = m_out_bPopulated;
10440         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
10441             DEBUG_PRINT_ERROR("Error in getting color format");
10442             return OMX_ErrorHardware;
10443         }
10444         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10445         fmt.fmt.pix_mp.pixelformat = capture_capability;
10446     } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
10447         portDefn->nBufferSize = m_client_out_extradata_info.getSize();
10448         portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10449         portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10450         portDefn->eDir =  OMX_DirOutput;
10451         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
10452         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
10453         portDefn->format.video.nStride  = drv_ctx.video_resolution.stride;
10454         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10455         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10456         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10457         DEBUG_PRINT_LOW(" get_parameter: Port idx %d nBufSize %u nBufCnt %u",
10458                 (int)portDefn->nPortIndex,
10459                 (unsigned int)portDefn->nBufferSize,
10460                 (unsigned int)portDefn->nBufferCountActual);
10461         return eRet;
10462     } else {
10463         portDefn->eDir = OMX_DirMax;
10464         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
10465                 (int)portDefn->nPortIndex);
10466         eRet = OMX_ErrorBadPortIndex;
10467     }
10468     if (in_reconfig) {
10469         m_extradata_info.output_crop_rect.nLeft = 0;
10470         m_extradata_info.output_crop_rect.nTop = 0;
10471         m_extradata_info.output_crop_rect.nWidth = fmt.fmt.pix_mp.width;
10472         m_extradata_info.output_crop_rect.nHeight = fmt.fmt.pix_mp.height;
10473     }
10474     update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10475         fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
10476 
10477     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
10478     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
10479     portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
10480     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10481 
10482     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
10483        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
10484            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
10485            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
10486     }
10487     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
10488             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
10489             (unsigned int)portDefn->nPortIndex,
10490             (unsigned int)portDefn->format.video.nFrameWidth,
10491             (unsigned int)portDefn->format.video.nFrameHeight,
10492             (int)portDefn->format.video.nStride,
10493             (unsigned int)portDefn->format.video.nSliceHeight,
10494             (unsigned int)portDefn->format.video.eColorFormat,
10495             (unsigned int)portDefn->nBufferSize,
10496             (unsigned int)portDefn->nBufferCountActual);
10497 
10498     return eRet;
10499 }
10500 
10501 OMX_ERRORTYPE omx_vdec::allocate_output_headers(bool intermediate)
10502 {
10503     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10504     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
10505     unsigned i = 0;
10506 
10507     OMX_BUFFERHEADERTYPE  **omx_base_address =
10508                       intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
10509     vdec_bufferpayload **omx_ptr_outputbuffer =
10510         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
10511     vdec_output_frameinfo **omx_ptr_respbuffer =
10512         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
10513     vdec_ion **omx_op_buf_ion_info =
10514         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
10515 
10516     if (!*omx_base_address) {
10517         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation, Cnt %d Sz %d",
10518             drv_ctx.op_buf.actualcount, (unsigned int)drv_ctx.op_buf.buffer_size);
10519         int nBufHdrSize        = 0;
10520         int nPlatformEntrySize = 0;
10521         int nPlatformListSize  = 0;
10522         int nPMEMInfoSize = 0;
10523         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
10524         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
10525         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
10526 
10527         nBufHdrSize        = drv_ctx.op_buf.actualcount *
10528             sizeof(OMX_BUFFERHEADERTYPE);
10529         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
10530             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
10531         nPlatformListSize  = drv_ctx.op_buf.actualcount *
10532             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
10533         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
10534             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
10535 
10536         *omx_base_address = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
10537         // Alloc mem for platform specific info
10538         char *pPtr=NULL;
10539         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
10540                 nPMEMInfoSize,1);
10541         *omx_ptr_outputbuffer = (struct vdec_bufferpayload *)    \
10542                        calloc (sizeof(struct vdec_bufferpayload),
10543                                drv_ctx.op_buf.actualcount);
10544         *omx_ptr_respbuffer = (struct vdec_output_frameinfo  *)                         \
10545                      calloc (sizeof (struct vdec_output_frameinfo),
10546                              drv_ctx.op_buf.actualcount);
10547         if (!pPtr || !*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
10548             DEBUG_PRINT_ERROR("allocate_output_headers: allocation failed");
10549             free(pPtr); pPtr = NULL;
10550             free(*omx_ptr_outputbuffer); *omx_ptr_outputbuffer = NULL;
10551             free(*omx_ptr_respbuffer); *omx_ptr_respbuffer = NULL;
10552             return OMX_ErrorInsufficientResources;
10553         }
10554 
10555 #ifdef USE_ION
10556         *omx_op_buf_ion_info = (struct vdec_ion * ) \
10557                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
10558         if (!*omx_op_buf_ion_info) {
10559             DEBUG_PRINT_ERROR("Failed to alloc output buffer ion info");
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 #endif
10566 
10567         if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
10568             && *omx_ptr_respbuffer) {
10569             bufHdr          =  *omx_base_address;
10570             if (m_platform_list) {
10571                 free(m_platform_list);
10572             }
10573             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
10574             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
10575                 (((char *) m_platform_list)  + nPlatformListSize);
10576             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
10577                 (((char *) m_platform_entry) + nPlatformEntrySize);
10578             pPlatformList   = m_platform_list;
10579             pPlatformEntry  = m_platform_entry;
10580             pPMEMInfo       = m_pmem_info;
10581 
10582             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
10583 
10584             // Settting the entire storage nicely
10585             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
10586                             *omx_base_address,pPlatformEntry);
10587             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
10588             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
10589                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
10590                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
10591                 // Set the values when we determine the right HxW param
10592                 bufHdr->nAllocLen          = 0;
10593                 bufHdr->nFilledLen         = 0;
10594                 bufHdr->pAppPrivate        = NULL;
10595                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
10596                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
10597                 pPlatformEntry->entry      = pPMEMInfo;
10598                 // Initialize the Platform List
10599                 pPlatformList->nEntries    = 1;
10600                 pPlatformList->entryList   = pPlatformEntry;
10601                 // Keep pBuffer NULL till vdec is opened
10602                 bufHdr->pBuffer            = NULL;
10603                 pPMEMInfo->offset          =  0;
10604                 pPMEMInfo->pmem_fd = -1;
10605                 bufHdr->pPlatformPrivate = pPlatformList;
10606                 (*omx_ptr_outputbuffer)[i].pmem_fd = -1;
10607 #ifdef USE_ION
10608                 (*omx_op_buf_ion_info)[i].data_fd = -1;
10609                 (*omx_op_buf_ion_info)[i].dev_fd = -1;
10610 #endif
10611                 /*Create a mapping between buffers*/
10612                 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
10613                 (*omx_ptr_respbuffer)[i].client_data = (void *) \
10614                     &(*omx_ptr_outputbuffer)[i];
10615                 // Move the buffer and buffer header pointers
10616                 bufHdr++;
10617                 pPMEMInfo++;
10618                 pPlatformEntry++;
10619                 pPlatformList++;
10620             }
10621         } else {
10622             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
10623                               *omx_base_address, pPtr);
10624             if (*omx_base_address) {
10625                 free(*omx_base_address);
10626                 *omx_base_address = NULL;
10627             }
10628             if (pPtr) {
10629                 free(pPtr);
10630                 pPtr = NULL;
10631             }
10632             if (*omx_ptr_outputbuffer) {
10633                 free(*omx_ptr_outputbuffer);
10634                 *omx_ptr_outputbuffer = NULL;
10635             }
10636             if (*omx_ptr_respbuffer) {
10637                 free(*omx_ptr_respbuffer);
10638                 *omx_ptr_respbuffer = NULL;
10639             }
10640 #ifdef USE_ION
10641             if (*omx_op_buf_ion_info) {
10642                 DEBUG_PRINT_LOW("Free o/p ion context");
10643                 free(*omx_op_buf_ion_info);
10644                 *omx_op_buf_ion_info = NULL;
10645             }
10646 #endif
10647             eRet =  OMX_ErrorInsufficientResources;
10648         }
10649     } else {
10650         eRet =  OMX_ErrorInsufficientResources;
10651     }
10652 
10653     if (intermediate == false &&
10654         eRet == OMX_ErrorNone &&
10655         client_buffers.is_color_conversion_enabled()) {
10656         eRet = allocate_output_headers(true);
10657     }
10658 
10659     return eRet;
10660 }
10661 
10662 void omx_vdec::complete_pending_buffer_done_cbs()
10663 {
10664     unsigned long p1, p2, ident;
10665     omx_cmd_queue tmp_q, pending_bd_q;
10666     pthread_mutex_lock(&m_lock);
10667     // pop all pending GENERATE FDB from ftb queue
10668     while (m_ftb_q.m_size) {
10669         m_ftb_q.pop_entry(&p1,&p2,&ident);
10670         if (ident == OMX_COMPONENT_GENERATE_FBD) {
10671             pending_bd_q.insert_entry(p1,p2,ident);
10672         } else {
10673             tmp_q.insert_entry(p1,p2,ident);
10674         }
10675     }
10676     //return all non GENERATE FDB to ftb queue
10677     while (tmp_q.m_size) {
10678         tmp_q.pop_entry(&p1,&p2,&ident);
10679         m_ftb_q.insert_entry(p1,p2,ident);
10680     }
10681     // pop all pending GENERATE EDB from etb queue
10682     while (m_etb_q.m_size) {
10683         m_etb_q.pop_entry(&p1,&p2,&ident);
10684         if (ident == OMX_COMPONENT_GENERATE_EBD) {
10685             pending_bd_q.insert_entry(p1,p2,ident);
10686         } else {
10687             tmp_q.insert_entry(p1,p2,ident);
10688         }
10689     }
10690     //return all non GENERATE FDB to etb queue
10691     while (tmp_q.m_size) {
10692         tmp_q.pop_entry(&p1,&p2,&ident);
10693         m_etb_q.insert_entry(p1,p2,ident);
10694     }
10695     pthread_mutex_unlock(&m_lock);
10696     // process all pending buffer dones
10697     while (pending_bd_q.m_size) {
10698         pending_bd_q.pop_entry(&p1,&p2,&ident);
10699         switch (ident) {
10700             case OMX_COMPONENT_GENERATE_EBD:
10701                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
10702                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
10703                     omx_report_error ();
10704                 }
10705                 break;
10706 
10707             case OMX_COMPONENT_GENERATE_FBD:
10708                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
10709                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
10710                     omx_report_error ();
10711                 }
10712                 break;
10713         }
10714     }
10715 }
10716 
10717 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
10718 {
10719     OMX_U32 new_frame_interval = 0;
10720     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
10721             && llabs(act_timestamp - prev_ts) > 2000) {
10722         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
10723             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
10724         if (new_frame_interval != frm_int || frm_int == 0) {
10725             frm_int = new_frame_interval;
10726             if (frm_int) {
10727                 drv_ctx.frame_rate.fps_numerator = 1e6;
10728                 drv_ctx.frame_rate.fps_denominator = frm_int;
10729                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
10730                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
10731                         (float)drv_ctx.frame_rate.fps_denominator);
10732                 /* We need to report the difference between this FBD and the previous FBD
10733                  * back to the driver for clock scaling purposes. */
10734                 struct v4l2_outputparm oparm;
10735                 /*XXX: we're providing timing info as seconds per frame rather than frames
10736                  * per second.*/
10737                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
10738                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
10739 
10740                 struct v4l2_streamparm sparm;
10741                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10742                 sparm.parm.output = oparm;
10743                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
10744                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
10745                             performance might be affected");
10746                 }
10747 
10748             }
10749         }
10750     }
10751     prev_ts = act_timestamp;
10752 }
10753 
10754 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
10755 {
10756     if (rst_prev_ts && VALID_TS(act_timestamp)) {
10757         prev_ts = act_timestamp;
10758         prev_ts_actual = act_timestamp;
10759         rst_prev_ts = false;
10760     } else if (VALID_TS(prev_ts)) {
10761         bool codec_cond = (drv_ctx.timestamp_adjust)?
10762             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
10763             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
10764              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
10765         if (frm_int > 0 && codec_cond) {
10766             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
10767             act_timestamp = prev_ts + frm_int;
10768             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
10769             prev_ts = act_timestamp;
10770         } else {
10771             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
10772                 // ensure that timestamps can never step backwards when in display order
10773                 act_timestamp = prev_ts;
10774             }
10775             set_frame_rate(act_timestamp);
10776         }
10777     } else if (frm_int > 0)          // In this case the frame rate was set along
10778     {                               // with the port definition, start ts with 0
10779         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
10780         rst_prev_ts = true;
10781     }
10782 }
10783 
10784 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
10785     OMX_U32 transfer, OMX_U32 matrix, ColorAspects *aspects)
10786 {
10787     switch (primaries) {
10788         case MSM_VIDC_BT709_5:
10789             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
10790             break;
10791         case MSM_VIDC_BT470_6_M:
10792             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
10793             break;
10794         case MSM_VIDC_BT601_6_625:
10795             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10796             break;
10797         case MSM_VIDC_BT601_6_525:
10798             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10799             break;
10800         case MSM_VIDC_GENERIC_FILM:
10801             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
10802             break;
10803         case MSM_VIDC_BT2020:
10804             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
10805             break;
10806         case MSM_VIDC_UNSPECIFIED:
10807             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
10808         default:
10809             //aspects->mPrimaries = ColorAspects::PrimariesOther;
10810             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
10811             break;
10812     }
10813 
10814     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
10815 
10816     switch (transfer) {
10817         case MSM_VIDC_TRANSFER_BT709_5:
10818         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
10819             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10820             break;
10821         case MSM_VIDC_TRANSFER_BT_470_6_M:
10822             aspects->mTransfer = ColorAspects::TransferGamma22;
10823             break;
10824         case MSM_VIDC_TRANSFER_BT_470_6_BG:
10825             aspects->mTransfer = ColorAspects::TransferGamma28;
10826             break;
10827         case MSM_VIDC_TRANSFER_SMPTE_240M:
10828             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10829             break;
10830         case MSM_VIDC_TRANSFER_LINEAR:
10831             aspects->mTransfer = ColorAspects::TransferLinear;
10832             break;
10833         case MSM_VIDC_TRANSFER_IEC_61966:
10834             aspects->mTransfer = ColorAspects::TransferXvYCC;
10835             break;
10836         case MSM_VIDC_TRANSFER_BT_1361:
10837             aspects->mTransfer = ColorAspects::TransferBT1361;
10838             break;
10839         case MSM_VIDC_TRANSFER_SRGB:
10840             aspects->mTransfer = ColorAspects::TransferSRGB;
10841             break;
10842         case MSM_VIDC_TRANSFER_SMPTE_ST2084:
10843             aspects->mTransfer = ColorAspects::TransferST2084;
10844             break;
10845         case MSM_VIDC_TRANSFER_HLG:
10846             aspects->mTransfer = ColorAspects::TransferHLG;
10847             break;
10848         default:
10849             //aspects->mTransfer = ColorAspects::TransferOther;
10850             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
10851             break;
10852     }
10853 
10854     switch (matrix) {
10855         case MSM_VIDC_MATRIX_BT_709_5:
10856             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10857             break;
10858         case MSM_VIDC_MATRIX_FCC_47:
10859             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
10860             break;
10861         case MSM_VIDC_MATRIX_601_6_625:
10862         case MSM_VIDC_MATRIX_601_6_525:
10863             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10864             break;
10865         case MSM_VIDC_MATRIX_SMPTE_240M:
10866             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10867             break;
10868         case MSM_VIDC_MATRIX_BT_2020:
10869             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10870             break;
10871         case MSM_VIDC_MATRIX_BT_2020_CONST:
10872             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
10873             break;
10874         default:
10875             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
10876             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
10877             break;
10878     }
10879 }
10880 
10881 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) {
10882     DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)",
10883                 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange),
10884                 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs));
10885 
10886 }
10887 
10888 bool omx_vdec::handle_color_space_info(void *data)
10889 {
10890     ColorAspects tempAspects;
10891     memset(&tempAspects, 0x0, sizeof(ColorAspects));
10892     ColorAspects *aspects = &tempAspects;
10893 
10894     switch(output_capability) {
10895         case V4L2_PIX_FMT_MPEG2:
10896             {
10897                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
10898                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
10899 
10900                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
10901                  * understand this code */
10902 
10903                 if (seqdisp_payload && seqdisp_payload->color_descp) {
10904 
10905                     convert_color_space_info(seqdisp_payload->color_primaries, 0,
10906                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
10907                             aspects);
10908                     /* MPEG2 seqdisp payload doesn't give range info. Hence assing the value
10909                      * set by client */
10910                     aspects->mRange = m_client_color_space.sAspects.mRange;
10911                     m_disp_hor_size = seqdisp_payload->disp_width;
10912                     m_disp_vert_size = seqdisp_payload->disp_height;
10913                 }
10914             }
10915             break;
10916         case V4L2_PIX_FMT_H264:
10917         case V4L2_PIX_FMT_HEVC:
10918             {
10919                 struct msm_vidc_vui_display_info_payload *display_info_payload;
10920                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
10921 
10922                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
10923 
10924                 if (display_info_payload->video_signal_present_flag &&
10925                         display_info_payload->color_description_present_flag) {
10926                     convert_color_space_info(display_info_payload->color_primaries,
10927                             display_info_payload->video_full_range_flag,
10928                             display_info_payload->transfer_characteristics,
10929                             display_info_payload->matrix_coefficients,
10930                             aspects);
10931                 }
10932             }
10933             break;
10934         case V4L2_PIX_FMT_VP8:
10935             {
10936                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10937                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10938                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
10939                  * to understand this code */
10940 
10941                 if (vpx_color_space_payload->color_space == 0) {
10942                     aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10943                     aspects->mRange = ColorAspects::RangeLimited;
10944                     aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10945                     aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10946                 } else {
10947                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
10948                     break;
10949                 }
10950             }
10951             break;
10952         case V4L2_PIX_FMT_VP9:
10953             {
10954                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10955                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10956                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
10957                  * to understand this code */
10958 
10959                 switch(vpx_color_space_payload->color_space) {
10960                     case MSM_VIDC_CS_BT_601:
10961                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10962                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10963                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10964                         aspects->mRange = m_client_color_space.sAspects.mRange;
10965                         break;
10966                     case MSM_VIDC_CS_BT_709:
10967                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10968                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10969                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
10970                         aspects->mRange = m_client_color_space.sAspects.mRange;
10971                         break;
10972                     case MSM_VIDC_CS_SMPTE_170:
10973                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10974                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10975                         aspects->mPrimaries =  ColorAspects::PrimariesBT601_6_525;
10976                         aspects->mRange = m_client_color_space.sAspects.mRange;
10977                         break;
10978                     case MSM_VIDC_CS_SMPTE_240:
10979                         aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10980                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10981                         aspects->mPrimaries =  ColorAspects::PrimariesBT601_6_525;
10982                         aspects->mRange = m_client_color_space.sAspects.mRange;
10983                         break;
10984                     case MSM_VIDC_CS_BT_2020:
10985                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10986                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
10987                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
10988                         aspects->mRange = m_client_color_space.sAspects.mRange;
10989                         break;
10990                     case MSM_VIDC_CS_RESERVED:
10991                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
10992                         aspects->mTransfer = ColorAspects::TransferOther;
10993                         aspects->mPrimaries = ColorAspects::PrimariesOther;
10994                         aspects->mRange = m_client_color_space.sAspects.mRange;
10995                         break;
10996                     case MSM_VIDC_CS_RGB:
10997                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10998                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10999                         aspects->mPrimaries = ColorAspects::PrimariesOther;
11000                         aspects->mRange = m_client_color_space.sAspects.mRange;
11001                         break;
11002                     default:
11003                         break;
11004                 }
11005             }
11006             break;
11007         default:
11008             break;
11009     }
11010 
11011     print_debug_color_aspects(aspects, "Bitstream");
11012 
11013     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
11014             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
11015             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
11016             m_internal_color_space.sAspects.mRange != aspects->mRange) {
11017         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
11018 
11019         DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change");
11020         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
11021         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
11022 
11023         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
11024                 OMX_QTIIndexConfigDescribeColorAspects,
11025                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
11026         return true;
11027     }
11028     return false;
11029 }
11030 
11031 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix)
11032 {
11033     if (!hdr_info->mID) {
11034         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix,
11035                          hdr_info->sType1.mR.x, hdr_info->sType1.mR.y);
11036         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix,
11037                          hdr_info->sType1.mG.x, hdr_info->sType1.mG.y);
11038         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix,
11039                          hdr_info->sType1.mB.x, hdr_info->sType1.mB.y);
11040         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix,
11041                          hdr_info->sType1.mW.x, hdr_info->sType1.mW.y);
11042         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix,
11043                          hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance);
11044         DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix,
11045                         hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel);
11046     }
11047 
11048 }
11049 
11050 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata)
11051 {
11052     DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u",
11053                     color_mdata->colorPrimaries, color_mdata->range,
11054                     color_mdata->transfer, color_mdata->matrixCoefficients);
11055 
11056     for(uint8_t i = 0; i < 3; i++) {
11057         for(uint8_t j = 0; j < 2; j++) {
11058             DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
11059         }
11060     }
11061 
11062     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d",
11063                     color_mdata->masteringDisplayInfo.primaries.whitePoint[0],
11064                     color_mdata->masteringDisplayInfo.primaries.whitePoint[1]);
11065 
11066     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d",
11067                     color_mdata->masteringDisplayInfo.maxDisplayLuminance,
11068                     color_mdata->masteringDisplayInfo.minDisplayLuminance);
11069 
11070     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d",
11071                     color_mdata->contentLightLevel.maxContentLightLevel,
11072                     color_mdata->contentLightLevel.minPicAverageLightLevel);
11073 
11074 
11075 }
11076 
11077 bool omx_vdec::handle_content_light_level_info(void* data)
11078 {
11079     struct msm_vidc_content_light_level_sei_payload *light_level_payload =
11080         (msm_vidc_content_light_level_sei_payload*)(data);
11081 
11082     if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) ||
11083         (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) {
11084         m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight;
11085         m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight;
11086         return true;
11087     }
11088     return false;
11089 }
11090 
11091 bool omx_vdec::handle_mastering_display_color_info(void* data)
11092 {
11093     struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload =
11094         (msm_vidc_mastering_display_colour_sei_payload*)(data);
11095     HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo;
11096     bool internal_disp_changed_flag = false;
11097 
11098     internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[0]) ||
11099         (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[0]);
11100     internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[1]) ||
11101         (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[1]);
11102     internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[2]) ||
11103         (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[2]);
11104 
11105     internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) ||
11106         (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY);
11107 
11108     /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension
11109        requires it in cd/m2, so dividing by 10000 and rounding the value after division
11110     */
11111     uint16_t max_display_luminance_cd_m2 =
11112         static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5);
11113     internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) ||
11114         (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance);
11115 
11116     if (internal_disp_changed_flag) {
11117         hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[0];
11118         hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[0];
11119         hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[1];
11120         hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[1];
11121         hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[2];
11122         hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[2];
11123         hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX;
11124         hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY;
11125 
11126         hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2;
11127         hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
11128     }
11129 
11130     return internal_disp_changed_flag;
11131 }
11132 
11133 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index)
11134 {
11135     private_handle_t *private_handle = NULL;
11136     if (buf_index < drv_ctx.op_buf.actualcount &&
11137         buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
11138         native_buffer[buf_index].privatehandle) {
11139         private_handle = native_buffer[buf_index].privatehandle;
11140     }
11141     if (private_handle) {
11142         setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata);
11143     }
11144 }
11145 
11146 void omx_vdec::convert_color_aspects_to_metadata(ColorAspects& aspects, ColorMetaData &color_mdata)
11147 {
11148     PrimariesMap::const_iterator primary_it = mPrimariesMap.find(aspects.mPrimaries);
11149     TransferMap::const_iterator transfer_it = mTransferMap.find(aspects.mTransfer);
11150     MatrixCoeffMap::const_iterator matrix_it = mMatrixCoeffMap.find(aspects.mMatrixCoeffs);
11151     RangeMap::const_iterator range_it = mColorRangeMap.find(aspects.mRange);
11152 
11153     if (primary_it == mPrimariesMap.end()) {
11154         DEBUG_PRINT_LOW("No mapping for %d in PrimariesMap, defaulting to unspecified", aspects.mPrimaries);
11155         color_mdata.colorPrimaries = (ColorPrimaries)2;
11156     } else {
11157         color_mdata.colorPrimaries = primary_it->second;
11158     }
11159 
11160     if (transfer_it == mTransferMap.end()) {
11161         DEBUG_PRINT_LOW("No mapping for %d in TransferMap, defaulting to unspecified", aspects.mTransfer);
11162         color_mdata.transfer = (GammaTransfer)2;
11163     } else {
11164         color_mdata.transfer = transfer_it->second;
11165     }
11166 
11167     if (matrix_it == mMatrixCoeffMap.end()) {
11168         DEBUG_PRINT_LOW("No mapping for %d in MatrixCoeffMap, defaulting to unspecified", aspects.mMatrixCoeffs);
11169         color_mdata.matrixCoefficients = (MatrixCoEfficients)2;
11170     } else {
11171         color_mdata.matrixCoefficients = matrix_it->second;
11172     }
11173 
11174     if (range_it == mColorRangeMap.end()) {
11175         DEBUG_PRINT_LOW("No mapping for %d in ColorRangeMap, defaulting to limited range", aspects.mRange);
11176         color_mdata.range = Range_Limited;
11177     } else {
11178         color_mdata.range = range_it->second;
11179     }
11180 }
11181 
11182 void omx_vdec::convert_hdr_info_to_metadata(HDRStaticInfo& hdr_info, ColorMetaData &color_mdata)
11183 {
11184     HDRStaticInfo::Type1 zero_hdr_info;
11185     MasteringDisplay& mastering_display = color_mdata.masteringDisplayInfo;
11186     ContentLightLevel& content_light = color_mdata.contentLightLevel;
11187     bool hdr_info_enabled = false;
11188     memset(&zero_hdr_info, 0, sizeof(HDRStaticInfo::Type1));
11189     hdr_info_enabled = (memcmp(&hdr_info, &zero_hdr_info, sizeof(HDRStaticInfo::Type1))!= 0);
11190 
11191     if (hdr_info_enabled) {
11192         mastering_display.colorVolumeSEIEnabled = true;
11193         mastering_display.primaries.rgbPrimaries[0][0] = hdr_info.sType1.mR.x;
11194         mastering_display.primaries.rgbPrimaries[0][1] = hdr_info.sType1.mR.y;
11195         mastering_display.primaries.rgbPrimaries[1][0] = hdr_info.sType1.mG.x;
11196         mastering_display.primaries.rgbPrimaries[1][1] = hdr_info.sType1.mG.y;
11197         mastering_display.primaries.rgbPrimaries[2][0] = hdr_info.sType1.mB.x;
11198         mastering_display.primaries.rgbPrimaries[2][1] = hdr_info.sType1.mB.y;
11199         mastering_display.primaries.whitePoint[0] = hdr_info.sType1.mW.x;
11200         mastering_display.primaries.whitePoint[1] = hdr_info.sType1.mW.y;
11201         mastering_display.maxDisplayLuminance = hdr_info.sType1.mMaxDisplayLuminance;
11202         mastering_display.minDisplayLuminance = hdr_info.sType1.mMinDisplayLuminance;
11203         content_light.lightLevelSEIEnabled = true;
11204         content_light.maxContentLightLevel = hdr_info.sType1.mMaxContentLightLevel;
11205         content_light.minPicAverageLightLevel = hdr_info.sType1.mMaxFrameAverageLightLevel;
11206     }
11207 
11208 }
11209 
11210 void omx_vdec::get_preferred_color_aspects(ColorAspects& preferredColorAspects)
11211 {
11212     // For VPX, use client-color if specified.
11213     // For the rest, try to use the stream-color if present
11214     bool preferClientColor = (output_capability == V4L2_PIX_FMT_VP8 ||
11215          output_capability == V4L2_PIX_FMT_VP9);
11216 
11217     const ColorAspects &preferredColor = preferClientColor ?
11218         m_client_color_space.sAspects : m_internal_color_space.sAspects;
11219     const ColorAspects &defaultColor = preferClientColor ?
11220         m_internal_color_space.sAspects : m_client_color_space.sAspects;
11221 
11222     preferredColorAspects.mPrimaries = preferredColor.mPrimaries != ColorAspects::PrimariesUnspecified ?
11223         preferredColor.mPrimaries : defaultColor.mPrimaries;
11224     preferredColorAspects.mTransfer = preferredColor.mTransfer != ColorAspects::TransferUnspecified ?
11225         preferredColor.mTransfer : defaultColor.mTransfer;
11226     preferredColorAspects.mMatrixCoeffs = preferredColor.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
11227         preferredColor.mMatrixCoeffs : defaultColor.mMatrixCoeffs;
11228     preferredColorAspects.mRange = preferredColor.mRange != ColorAspects::RangeUnspecified ?
11229         preferredColor.mRange : defaultColor.mRange;
11230 
11231 }
11232 
11233 void omx_vdec::get_preferred_hdr_info(HDRStaticInfo& finalHDRInfo)
11234 {
11235     bool preferClientHDR = (output_capability == V4L2_PIX_FMT_VP9);
11236 
11237     const HDRStaticInfo &preferredHDRInfo = preferClientHDR ?
11238         m_client_hdr_info.sInfo : m_internal_hdr_info.sInfo;
11239     const HDRStaticInfo &defaultHDRInfo = preferClientHDR ?
11240         m_internal_hdr_info.sInfo : m_client_hdr_info.sInfo;
11241     finalHDRInfo.sType1.mR = ((preferredHDRInfo.sType1.mR.x != 0) && (preferredHDRInfo.sType1.mR.y != 0)) ?
11242         preferredHDRInfo.sType1.mR : defaultHDRInfo.sType1.mR;
11243     finalHDRInfo.sType1.mG = ((preferredHDRInfo.sType1.mG.x != 0) && (preferredHDRInfo.sType1.mG.y != 0)) ?
11244         preferredHDRInfo.sType1.mG : defaultHDRInfo.sType1.mG;
11245     finalHDRInfo.sType1.mB = ((preferredHDRInfo.sType1.mB.x != 0) && (preferredHDRInfo.sType1.mB.y != 0)) ?
11246         preferredHDRInfo.sType1.mB : defaultHDRInfo.sType1.mB;
11247     finalHDRInfo.sType1.mW = ((preferredHDRInfo.sType1.mW.x != 0) && (preferredHDRInfo.sType1.mW.y != 0)) ?
11248         preferredHDRInfo.sType1.mW : defaultHDRInfo.sType1.mW;
11249     finalHDRInfo.sType1.mMaxDisplayLuminance = (preferredHDRInfo.sType1.mMaxDisplayLuminance != 0) ?
11250         preferredHDRInfo.sType1.mMaxDisplayLuminance : defaultHDRInfo.sType1.mMaxDisplayLuminance;
11251     finalHDRInfo.sType1.mMinDisplayLuminance = (preferredHDRInfo.sType1.mMinDisplayLuminance != 0) ?
11252         preferredHDRInfo.sType1.mMinDisplayLuminance : defaultHDRInfo.sType1.mMinDisplayLuminance;
11253     finalHDRInfo.sType1.mMaxContentLightLevel = (preferredHDRInfo.sType1.mMaxContentLightLevel != 0) ?
11254         preferredHDRInfo.sType1.mMaxContentLightLevel : defaultHDRInfo.sType1.mMaxContentLightLevel;
11255     finalHDRInfo.sType1.mMaxFrameAverageLightLevel = (preferredHDRInfo.sType1.mMaxFrameAverageLightLevel != 0) ?
11256         preferredHDRInfo.sType1.mMaxFrameAverageLightLevel : defaultHDRInfo.sType1.mMaxFrameAverageLightLevel;
11257 }
11258 
11259 void omx_vdec::print_debug_hdr10plus_metadata(ColorMetaData& color_mdata) {
11260     DEBUG_PRINT_LOW("HDR10+ valid data length: %d", color_mdata.dynamicMetaDataLen);
11261     for (uint32_t i = 0 ; i < color_mdata.dynamicMetaDataLen && i+3 < HDR_DYNAMIC_META_DATA_SZ; i=i+4) {
11262         DEBUG_PRINT_LOW("HDR10+ mdata: %02X %02X %02X %02X", color_mdata.dynamicMetaDataPayload[i],
11263             color_mdata.dynamicMetaDataPayload[i+1],
11264             color_mdata.dynamicMetaDataPayload[i+2],
11265             color_mdata.dynamicMetaDataPayload[i+3]);
11266     }
11267 
11268 }
11269 
11270 bool omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
11271 {
11272     OMX_OTHER_EXTRADATATYPE *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
11273     OMX_U32 num_conceal_MB = 0;
11274     OMX_TICKS time_stamp = 0;
11275     OMX_U32 frame_rate = 0;
11276     unsigned long consumed_len = 0;
11277     OMX_U32 num_MB_in_frame;
11278     OMX_U32 recovery_sei_flags = 1;
11279     int enable = OMX_InterlaceFrameProgressive;
11280     bool internal_hdr_info_changed_flag = false;
11281     bool reconfig_event_sent = false;
11282     char *p_extradata = NULL;
11283     OMX_OTHER_EXTRADATATYPE *data = NULL;
11284     ColorMetaData color_mdata;
11285 
11286     OMX_BUFFERHEADERTYPE  *omx_base_address =
11287         client_buffers.is_color_conversion_enabled()?
11288                             m_intermediate_out_mem_ptr:m_out_mem_ptr;
11289     vdec_bufferpayload *omx_ptr_outputbuffer =
11290         client_buffers.is_color_conversion_enabled()?
11291                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
11292     memset(&color_mdata, 0, sizeof(color_mdata));
11293 
11294     int buf_index = p_buf_hdr - omx_base_address;
11295     if (buf_index >= drv_ctx.extradata_info.count) {
11296         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
11297                 buf_index, drv_ctx.extradata_info.count);
11298         return reconfig_event_sent;
11299     }
11300     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
11301 
11302     if (omx_ptr_outputbuffer[buf_index].bufferaddr == NULL) {
11303         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
11304         return reconfig_event_sent;
11305     }
11306 
11307     if (!drv_ctx.extradata_info.uaddr) {
11308         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
11309         return reconfig_event_sent;
11310     }
11311 
11312     if (m_client_output_extradata_mem_ptr &&
11313         m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
11314         p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer);
11315     }
11316 
11317     p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
11318 
11319     m_extradata_info.output_crop_updated = OMX_FALSE;
11320     data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
11321     if (data) {
11322         while ((((consumed_len + sizeof(struct OMX_OTHER_EXTRADATATYPE)) <
11323                 drv_ctx.extradata_info.buffer_size) && ((consumed_len + data->nSize) <
11324                 drv_ctx.extradata_info.buffer_size))
11325                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
11326             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
11327             switch ((unsigned long)data->eType) {
11328                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
11329                     struct msm_vidc_interlace_payload *payload;
11330                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
11331                     if (payload) {
11332                         DEBUG_PRINT_LOW("Interlace format %#x", payload->format);
11333                         enable = OMX_InterlaceFrameProgressive;
11334                         is_mbaff = payload->format & MSM_VIDC_INTERLACE_FRAME_MBAFF;
11335                         switch (payload->format & 0x1F) {
11336                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
11337                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11338                                 break;
11339                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
11340                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
11341                                 enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
11342                                 break;
11343                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
11344                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
11345                                 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
11346                                 break;
11347                             case MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST:
11348                                 drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
11349                                 enable = OMX_InterlaceFrameTopFieldFirst;
11350                                 break;
11351                            case MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST:
11352                                 drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
11353                                 enable = OMX_InterlaceFrameBottomFieldFirst;
11354                                 break;
11355                             default:
11356                                 DEBUG_PRINT_LOW("default case - set to progressive");
11357                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11358                         }
11359                     }
11360 
11361                     if (m_enable_android_native_buffers) {
11362                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d enable:%d",
11363                                         payload->format, enable);
11364 
11365                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
11366                                PP_PARAM_INTERLACED, (void*)&enable);
11367 
11368                     }
11369                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
11370                         if (p_client_extra) {
11371                             append_interlace_extradata(p_client_extra, (payload->format & 0x1F));
11372                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
11373                                 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11374                         }
11375                     }
11376                     break;
11377                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
11378                     struct msm_vidc_framerate_payload *frame_rate_payload;
11379                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
11380                     frame_rate = frame_rate_payload->frame_rate;
11381                     break;
11382                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
11383                     struct msm_vidc_ts_payload *time_stamp_payload;
11384                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
11385                     time_stamp = time_stamp_payload->timestamp_lo;
11386                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
11387                     p_buf_hdr->nTimeStamp = time_stamp;
11388                     break;
11389                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
11390                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
11391                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
11392                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11393                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11394                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
11395                     break;
11396                 case MSM_VIDC_EXTRADATA_INDEX:
11397                     int *etype;
11398                     etype  = (int *)(void *)data->data;
11399                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
11400                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
11401                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
11402                         if (aspect_ratio_payload) {
11403                             ((struct vdec_output_frameinfo *)
11404                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
11405                             ((struct vdec_output_frameinfo *)
11406                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
11407                         }
11408                     } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
11409                         struct msm_vidc_output_crop_payload *output_crop_payload;
11410                         output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
11411                         if (output_crop_payload) {
11412                             m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
11413                             m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
11414                             m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
11415                             m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
11416                             m_extradata_info.output_width = output_crop_payload->width;
11417                             m_extradata_info.output_height = output_crop_payload->height;
11418                             m_extradata_info.output_crop_updated = OMX_TRUE;
11419                             for(unsigned int m=0; m<output_crop_payload->misr_info[0].misr_set; m++) {
11420                             DEBUG_PRINT_HIGH("MISR0: %x %x %x %x\n",
11421                                 output_crop_payload->misr_info[0].misr_dpb_luma[m],
11422                                 output_crop_payload->misr_info[0].misr_dpb_chroma[m],
11423                                 output_crop_payload->misr_info[0].misr_opb_luma[m],
11424                                 output_crop_payload->misr_info[0].misr_opb_chroma[m]);
11425                             }
11426                             for(unsigned int m=0; m< output_crop_payload->misr_info[1].misr_set; m++) {
11427                                 DEBUG_PRINT_HIGH("MISR1: %x %x %x %x\n",
11428                                                  output_crop_payload->misr_info[1].misr_dpb_luma[m],
11429                                                  output_crop_payload->misr_info[1].misr_dpb_chroma[m],
11430                                                  output_crop_payload->misr_info[1].misr_opb_luma[m],
11431                                                  output_crop_payload->misr_info[1].misr_opb_chroma[m]);
11432                             }
11433                             memcpy(m_extradata_info.misr_info, output_crop_payload->misr_info, 2 * sizeof(msm_vidc_misr_info));
11434                             if (client_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11435                                 if (p_client_extra) {
11436                                     append_outputcrop_extradata(p_client_extra, output_crop_payload);
11437                                     p_client_extra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11438                                 }
11439                             }
11440                         }
11441                     }
11442                     break;
11443                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
11444                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
11445                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
11446                     recovery_sei_flags = recovery_sei_payload->flags;
11447                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
11448                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
11449                         DEBUG_PRINT_HIGH("***************************************************");
11450                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
11451                         DEBUG_PRINT_HIGH("***************************************************");
11452                     }
11453                     break;
11454                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
11455                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
11456                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
11457                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
11458                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
11459                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
11460                         return reconfig_event_sent;
11461                     }
11462                     break;
11463                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
11464                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
11465                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
11466                     reconfig_event_sent |= handle_color_space_info((void *)data->data);
11467                     break;
11468                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
11469                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
11470                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
11471                     switch (s3d_frame_packing_payload->fpa_type) {
11472                         case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
11473                             if (s3d_frame_packing_payload->content_interprtation_type == 1)
11474                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
11475                             else if (s3d_frame_packing_payload->content_interprtation_type == 2)
11476                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
11477                             else {
11478                                 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
11479                                 stereo_output_mode = HAL_NO_3D;
11480                             }
11481                             break;
11482                         case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
11483                             stereo_output_mode = HAL_3D_TOP_BOTTOM;
11484                             break;
11485                         default:
11486                             DEBUG_PRINT_ERROR("Unsupported framepacking type");
11487                             stereo_output_mode = HAL_NO_3D;
11488                     }
11489                     DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
11490                         s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
11491                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
11492                         if (p_client_extra) {
11493                             append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
11494                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11495                         }
11496                     }
11497                     break;
11498                 case MSM_VIDC_EXTRADATA_FRAME_QP:
11499                     struct msm_vidc_frame_qp_payload *qp_payload;
11500                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
11501                     if (client_extradata & OMX_QP_EXTRADATA) {
11502                         if (p_client_extra) {
11503                             append_qp_extradata(p_client_extra, qp_payload);
11504                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11505                         }
11506                     }
11507                     break;
11508                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
11509                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
11510                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
11511                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
11512                         if (p_client_extra) {
11513                             append_bitsinfo_extradata(p_client_extra, bits_info_payload);
11514                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11515                         }
11516                     }
11517                     break;
11518                 case MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO:
11519                     DEBUG_PRINT_LOW("MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO not used. Ignoring.");
11520                     break;
11521                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
11522                     if(output_capability == V4L2_PIX_FMT_HEVC) {
11523                         struct msm_vidc_stream_userdata_payload* userdata_payload = (struct msm_vidc_stream_userdata_payload*)data->data;
11524                         // Remove the size of type from msm_vidc_stream_userdata_payload
11525                         uint32_t payload_len = data->nDataSize - sizeof(userdata_payload->type);
11526                         if ((data->nDataSize < sizeof(userdata_payload->type)) ||
11527                             (payload_len > HDR_DYNAMIC_META_DATA_SZ)) {
11528                             DEBUG_PRINT_ERROR("Invalid User extradata size %u for HDR10+", data->nDataSize);
11529                         } else {
11530 #if HDR10_SETMETADATA_ENABLE
11531                             color_mdata.dynamicMetaDataValid = true;
11532                             color_mdata.dynamicMetaDataLen = payload_len;
11533                             memcpy(color_mdata.dynamicMetaDataPayload, userdata_payload->data, payload_len);
11534                             DEBUG_PRINT_HIGH("Copied %u bytes of HDR10+ extradata", payload_len);
11535 #else
11536                             store_hevc_hdr10plusinfo(payload_len, userdata_payload);
11537 #endif
11538                         }
11539                     }
11540                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
11541                         if (p_client_extra) {
11542                             append_user_extradata(p_client_extra, data);
11543                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11544                         }
11545                     }
11546                     break;
11547                 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
11548 
11549                     internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data);
11550                     break;
11551                 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI:
11552                     internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data);
11553                     break;
11554                 default:
11555                     DEBUG_PRINT_LOW("Unrecognized extradata");
11556                     goto unrecognized_extradata;
11557             }
11558             consumed_len += data->nSize;
11559             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
11560         }
11561         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
11562             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11563             if (p_client_extra) {
11564                 append_frame_info_extradata(p_client_extra,
11565                         num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
11566                         time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
11567                             p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
11568                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11569             }
11570         }
11571         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
11572             if (p_client_extra) {
11573                 append_frame_dimension_extradata(p_client_extra);
11574                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11575             }
11576         }
11577 
11578         if(internal_hdr_info_changed_flag) {
11579             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal");
11580             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client");
11581             if(!reconfig_event_sent) {
11582                 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change");
11583                 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
11584                            OMX_QTIIndexConfigDescribeHDRColorInfo,
11585                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
11586                 reconfig_event_sent = true;
11587             }
11588         }
11589 
11590         if (m_enable_android_native_buffers) {
11591                 ColorAspects final_color_aspects;
11592                 HDRStaticInfo final_hdr_info;
11593                 memset(&final_color_aspects, 0, sizeof(final_color_aspects));
11594                 memset(&final_hdr_info, 0, sizeof(final_hdr_info));
11595                 get_preferred_color_aspects(final_color_aspects);
11596 
11597                 /* For VP8, always set the metadata on gralloc handle to 601-LR */
11598                 if (output_capability == V4L2_PIX_FMT_VP8) {
11599                     final_color_aspects.mPrimaries = ColorAspects::PrimariesBT601_6_525;
11600                     final_color_aspects.mRange = ColorAspects::RangeLimited;
11601                     final_color_aspects.mTransfer = ColorAspects::TransferSMPTE170M;
11602                     final_color_aspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
11603                 }
11604                 get_preferred_hdr_info(final_hdr_info);
11605 #if HDR10_SETMETADATA_ENABLE
11606                 convert_hdr_info_to_metadata(final_hdr_info, color_mdata);
11607                 convert_hdr10plusinfo_to_metadata(p_buf_hdr->pMarkData, color_mdata);
11608                 remove_hdr10plusinfo_using_cookie(p_buf_hdr->pMarkData);
11609                 convert_color_aspects_to_metadata(final_color_aspects, color_mdata);
11610                 print_debug_hdr_color_info_mdata(&color_mdata);
11611                 print_debug_hdr10plus_metadata(color_mdata);
11612                 set_colormetadata_in_handle(&color_mdata, buf_index);
11613 #endif
11614         }
11615 
11616     }
11617 unrecognized_extradata:
11618     if (client_extradata) {
11619         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11620         if (p_client_extra) {
11621             append_terminator_extradata(p_client_extra);
11622         }
11623     }
11624     return reconfig_event_sent;
11625 }
11626 
11627 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata,
11628         bool is_internal, bool enable)
11629 {
11630     OMX_ERRORTYPE ret = OMX_ErrorNone;
11631     struct v4l2_control control;
11632     if (m_state != OMX_StateLoaded) {
11633         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
11634         return OMX_ErrorIncorrectStateOperation;
11635     }
11636     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
11637             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
11638 
11639     if (!is_internal) {
11640         if (enable)
11641             client_extradata |= requested_extradata;
11642         else
11643             client_extradata = client_extradata & ~requested_extradata;
11644     }
11645 
11646     if (enable) {
11647         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
11648             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11649             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
11650             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11651                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
11652                         " Quality of interlaced clips might be impacted.");
11653             }
11654         }
11655         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
11656             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11657             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
11658             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11659                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
11660             }
11661             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11662             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
11663             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11664                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
11665             }
11666             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11667             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
11668             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11669                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
11670             }
11671             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11672             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
11673             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11674                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11675             }
11676             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11677             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
11678             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11679                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11680             }
11681             if (output_capability == V4L2_PIX_FMT_MPEG2) {
11682                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11683                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11684                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11685                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11686                 }
11687             }
11688         }
11689         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
11690             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11691             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
11692             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11693                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
11694             }
11695         }
11696         if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
11697             if (output_capability == V4L2_PIX_FMT_H264) {
11698                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
11699                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11700                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
11701                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11702                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
11703                 }
11704             } else {
11705                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
11706             }
11707         }
11708         if (requested_extradata & OMX_QP_EXTRADATA) {
11709             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11710             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11711             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11712                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11713             }
11714         }
11715         if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
11716             if (!secure_mode || (secure_mode && output_capability == V4L2_PIX_FMT_HEVC)) {
11717                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11718                 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
11719                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11720                     DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
11721                 }
11722             }
11723         }
11724 #if NEED_TO_REVISIT
11725         if (requested_extradata & OMX_QP_EXTRADATA) {
11726             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11727             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11728             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11729                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11730             }
11731         }
11732 #endif
11733         if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11734             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11735             control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
11736             DEBUG_PRINT_LOW("Enable output crop extra data");
11737             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11738                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11739             }
11740         }
11741         if (requested_extradata & OMX_UBWC_CR_STATS_INFO_EXTRADATA) {
11742             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11743             control.value = V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO;
11744             DEBUG_PRINT_LOW("Enable UBWC stats extra data");
11745             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11746                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11747             }
11748         }
11749         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
11750             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11751             switch(output_capability) {
11752                 case V4L2_PIX_FMT_H264:
11753                 case V4L2_PIX_FMT_HEVC:
11754                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
11755                     break;
11756                 case V4L2_PIX_FMT_VP8:
11757                 case V4L2_PIX_FMT_VP9:
11758                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
11759                     break;
11760                 case V4L2_PIX_FMT_MPEG2:
11761                     control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11762                     break;
11763                 default:
11764                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
11765                     return ret;
11766             }
11767 
11768             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11769                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
11770             }
11771         }
11772         if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) {
11773             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11774             if (output_capability == V4L2_PIX_FMT_HEVC) {
11775                 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI;
11776                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11777                     DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata");
11778                 }
11779                 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
11780                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11781                     DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata");
11782                 }
11783             } else {
11784                 DEBUG_PRINT_HIGH("OMX_HDR_COLOR_INFO_EXTRADATA supported for HEVC only");
11785             }
11786         }
11787     }
11788     ret = get_buffer_req(&drv_ctx.op_buf);
11789     return ret;
11790 }
11791 
11792 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11793 {
11794     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
11795     OMX_U8 *data_ptr = extra->data, data = 0;
11796     while (byte_count < extra->nDataSize) {
11797         data = *data_ptr;
11798         while (data) {
11799             num_MB += (data&0x01);
11800             data >>= 1;
11801         }
11802         data_ptr++;
11803         byte_count++;
11804     }
11805     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11806             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11807     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
11808 }
11809 
11810 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11811 {
11812     if (!m_debug_extradata || !extra)
11813         return;
11814 
11815 
11816     DEBUG_PRINT_HIGH(
11817             "============== Extra Data ==============\n"
11818             "           Size: %u\n"
11819             "        Version: %u\n"
11820             "      PortIndex: %u\n"
11821             "           Type: %x\n"
11822             "       DataSize: %u",
11823             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
11824             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
11825 
11826     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
11827         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
11828         DEBUG_PRINT_HIGH(
11829                 "------ Interlace Format ------\n"
11830                 "                Size: %u\n"
11831                 "             Version: %u\n"
11832                 "           PortIndex: %u\n"
11833                 " Is Interlace Format: %d\n"
11834                 "   Interlace Formats: %u\n"
11835                 "=========== End of Interlace ===========",
11836                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
11837                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
11838     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
11839         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
11840 
11841         DEBUG_PRINT_HIGH(
11842                 "-------- Frame Format --------\n"
11843                 "             Picture Type: %d\n"
11844                 "           Interlace Type: %d\n"
11845                 " Pan Scan Total Frame Num: %u\n"
11846                 "   Concealed Macro Blocks: %u\n"
11847                 "        Recovery SEI Flag: %u\n"
11848                 "               frame rate: %u\n"
11849                 "               Time Stamp: %llu\n"
11850                 "           Aspect Ratio X: %u\n"
11851                 "           Aspect Ratio Y: %u",
11852                 fminfo->ePicType,
11853                 fminfo->interlaceType,
11854                 (unsigned int)fminfo->panScan.numWindows,
11855                 (unsigned int)fminfo->nConcealedMacroblocks,
11856                 (unsigned int)fminfo->nRecoverySeiFlag,
11857                 (unsigned int)fminfo->nFrameRate,
11858                 fminfo->nTimeStamp,
11859                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
11860                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
11861 
11862         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
11863             DEBUG_PRINT_HIGH(
11864                     "------------------------------"
11865                     "     Pan Scan Frame Num: %u\n"
11866                     "            Rectangle x: %d\n"
11867                     "            Rectangle y: %d\n"
11868                     "           Rectangle dx: %d\n"
11869                     "           Rectangle dy: %d",
11870                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
11871                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
11872         }
11873 
11874         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
11875     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
11876         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
11877         DEBUG_PRINT_HIGH(
11878                 "------------------ Framepack Format ----------\n"
11879                 "                           id: %u \n"
11880                 "                  cancel_flag: %u \n"
11881                 "                         type: %u \n"
11882                 " quincunx_sampling_flagFormat: %u \n"
11883                 "  content_interpretation_type: %u \n"
11884                 "        spatial_flipping_flag: %u \n"
11885                 "          frame0_flipped_flag: %u \n"
11886                 "             field_views_flag: %u \n"
11887                 " current_frame_is_frame0_flag: %u \n"
11888                 "   frame0_self_contained_flag: %u \n"
11889                 "   frame1_self_contained_flag: %u \n"
11890                 "       frame0_grid_position_x: %u \n"
11891                 "       frame0_grid_position_y: %u \n"
11892                 "       frame1_grid_position_x: %u \n"
11893                 "       frame1_grid_position_y: %u \n"
11894                 "                reserved_byte: %u \n"
11895                 "            repetition_period: %u \n"
11896                 "               extension_flag: %u \n"
11897                 "================== End of Framepack ===========",
11898                 (unsigned int)framepack->id,
11899                 (unsigned int)framepack->cancel_flag,
11900                 (unsigned int)framepack->type,
11901                 (unsigned int)framepack->quincunx_sampling_flag,
11902                 (unsigned int)framepack->content_interpretation_type,
11903                 (unsigned int)framepack->spatial_flipping_flag,
11904                 (unsigned int)framepack->frame0_flipped_flag,
11905                 (unsigned int)framepack->field_views_flag,
11906                 (unsigned int)framepack->current_frame_is_frame0_flag,
11907                 (unsigned int)framepack->frame0_self_contained_flag,
11908                 (unsigned int)framepack->frame1_self_contained_flag,
11909                 (unsigned int)framepack->frame0_grid_position_x,
11910                 (unsigned int)framepack->frame0_grid_position_y,
11911                 (unsigned int)framepack->frame1_grid_position_x,
11912                 (unsigned int)framepack->frame1_grid_position_y,
11913                 (unsigned int)framepack->reserved_byte,
11914                 (unsigned int)framepack->repetition_period,
11915                 (unsigned int)framepack->extension_flag);
11916     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
11917         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
11918         DEBUG_PRINT_HIGH(
11919                 "---- QP (Frame quantization parameter) ----\n"
11920                 "              Frame QP: %u \n"
11921                 "       Sum of Frame QP: %u \n"
11922                 "     Sum of Skipped QP: %u \n"
11923                 "    Num Skipped Blocks: %u \n"
11924                 "          Total Blocks: %u \n"
11925                 "================ End of QP ================\n",
11926                 (unsigned int)qp->nQP,(unsigned int)qp->nQPSum,
11927                 (unsigned int)qp->nSkipQPSum,(unsigned int)qp->nSkipNumBlocks,
11928                 (unsigned int)qp->nTotalNumBlocks);
11929     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
11930         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
11931         DEBUG_PRINT_HIGH(
11932                 "--------- Input bits information --------\n"
11933                 "    Header bits: %u \n"
11934                 "     Frame bits: %u \n"
11935                 "===== End of Input bits information =====\n",
11936                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
11937     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
11938         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
11939         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
11940         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
11941         OMX_U32 i = 0;
11942         DEBUG_PRINT_HIGH(
11943                 "--------------  Userdata  -------------\n"
11944                 "    Stream userdata type: %u\n"
11945                 "          userdata size: %u\n"
11946                 "    STREAM_USERDATA:",
11947                 (unsigned int)userdata->type, (unsigned int)userdata_size);
11948                 for (i = 0; i < userdata_size; i+=4) {
11949                     DEBUG_PRINT_HIGH("        %x %x %x %x",
11950                         data_ptr[i], data_ptr[i+1],
11951                         data_ptr[i+2], data_ptr[i+3]);
11952                 }
11953         DEBUG_PRINT_HIGH(
11954                 "=========== End of Userdata ===========");
11955     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
11956         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
11957         DEBUG_PRINT_HIGH(
11958                 "--------------  VQZip  -------------\n"
11959                 "    Size: %u\n",
11960                 (unsigned int)vq->nSize);
11961         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
11962     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo) {
11963         OMX_QCOM_OUTPUT_CROP *outputcrop_info = (OMX_QCOM_OUTPUT_CROP*)(void *)extra->data;
11964         DEBUG_PRINT_HIGH(
11965             "------------------ output crop ----------\n"
11966             "                         left: %u \n"
11967             "                          top: %u \n"
11968             "                display_width: %u \n"
11969             "               display_height: %u \n"
11970             "                        width: %u \n"
11971             "                       height: %u \n"
11972             "                    frame_num: %u \n"
11973             "                  bit_depth_y: %u \n"
11974             "                  bit_depth_c: %u \n",
11975             (unsigned int)outputcrop_info->left,
11976             (unsigned int)outputcrop_info->top,
11977             (unsigned int)outputcrop_info->display_width,
11978             (unsigned int)outputcrop_info->display_height,
11979             (unsigned int)outputcrop_info->width,
11980             (unsigned int)outputcrop_info->height,
11981             (unsigned int)outputcrop_info->frame_num,
11982             (unsigned int)outputcrop_info->bit_depth_y,
11983             (unsigned int)outputcrop_info->bit_depth_c);
11984         for(unsigned int m=0; m<outputcrop_info->misr_info[0].misr_set; m++) {
11985             DEBUG_PRINT_HIGH(
11986             "     top field: misr_dpb_luma(%d): %u \n"
11987             "   top field: misr_dpb_chroma(%d): %u \n"
11988             "     top field: misr_opb_luma(%d): %u \n"
11989             "   top field: misr_opb_chroma(%d): %u \n",
11990             m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_luma[m],
11991             m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_chroma[m],
11992             m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_luma[m],
11993             m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_chroma[m]);
11994         }
11995         for(unsigned int m=0; m<outputcrop_info->misr_info[1].misr_set; m++) {
11996             DEBUG_PRINT_HIGH(
11997             "  bottom field: misr_dpb_luma(%d): %u \n"
11998             "bottom field: misr_dpb_chroma(%d): %u \n"
11999             "  bottom field: misr_opb_luma(%d): %u \n"
12000             "bottom field: misr_opb_chroma(%d): %u \n",
12001             m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_luma[m],
12002             m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_chroma[m],
12003             m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_luma[m],
12004             m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_chroma[m]);
12005         }
12006         DEBUG_PRINT_HIGH("================== End of output crop ===========");
12007     } else if (extra->eType == OMX_ExtraDataNone) {
12008         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
12009     } else {
12010         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
12011     }
12012 }
12013 
12014 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12015         OMX_U32 interlaced_format_type)
12016 {
12017     OMX_STREAMINTERLACEFORMAT *interlace_format;
12018 
12019     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
12020         return;
12021     }
12022     if (!extra) {
12023        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
12024        return;
12025     }
12026     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
12027     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12028     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12029     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
12030     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
12031     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
12032     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
12033     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
12034     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12035 
12036     if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
12037         interlace_format->bInterlaceFormat = OMX_FALSE;
12038         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
12039         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
12040     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
12041         interlace_format->bInterlaceFormat = OMX_TRUE;
12042         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
12043         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
12044     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
12045         interlace_format->bInterlaceFormat = OMX_TRUE;
12046         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
12047         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
12048     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST) {
12049         interlace_format->bInterlaceFormat = OMX_TRUE;
12050         interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
12051         drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
12052     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST) {
12053         interlace_format->bInterlaceFormat = OMX_TRUE;
12054         interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
12055         drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
12056     } else {
12057         //default case - set to progressive
12058         interlace_format->bInterlaceFormat = OMX_FALSE;
12059         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
12060         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
12061     }
12062     print_debug_extradata(extra);
12063 }
12064 
12065 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12066 {
12067     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
12068     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
12069         return;
12070     }
12071     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
12072     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12073     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12074     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
12075     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
12076     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
12077     frame_dimension->nDecWidth = rectangle.nLeft;
12078     frame_dimension->nDecHeight = rectangle.nTop;
12079     frame_dimension->nActualWidth = rectangle.nWidth;
12080     frame_dimension->nActualHeight = rectangle.nHeight;
12081 }
12082 
12083 void omx_vdec::fill_aspect_ratio_info(
12084         struct vdec_aspectratioinfo *aspect_ratio_info,
12085         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
12086 {
12087     m_extradata = frame_info;
12088     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
12089     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
12090     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
12091             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
12092 }
12093 
12094 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12095         OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate,
12096         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
12097         struct vdec_aspectratioinfo *aspect_ratio_info)
12098 {
12099     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
12100     struct msm_vidc_panscan_window *panscan_window;
12101     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
12102         return;
12103     }
12104     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
12105     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12106     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12107     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
12108     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
12109     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
12110     switch (picture_type) {
12111         case PICTURE_TYPE_I:
12112             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
12113             break;
12114         case PICTURE_TYPE_P:
12115             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
12116             break;
12117         case PICTURE_TYPE_B:
12118             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
12119             break;
12120         default:
12121             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
12122     }
12123     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
12124         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
12125     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
12126         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
12127     else if (drv_ctx.interlace == VDEC_InterlaceFrameTopFieldFirst)
12128         frame_info->interlaceType = OMX_QCOM_InterlaceFrameTopFieldFirst;
12129     else if (drv_ctx.interlace == VDEC_InterlaceFrameBottomFieldFirst)
12130         frame_info->interlaceType = OMX_QCOM_InterlaceFrameBottomFieldFirst;
12131     else
12132         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
12133     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
12134     frame_info->nConcealedMacroblocks = num_conceal_mb;
12135     frame_info->nRecoverySeiFlag = recovery_sei_flag;
12136     frame_info->nFrameRate = frame_rate;
12137     frame_info->nTimeStamp = time_stamp;
12138     frame_info->panScan.numWindows = 0;
12139     if (output_capability == V4L2_PIX_FMT_MPEG2) {
12140         if (m_disp_hor_size && m_disp_vert_size) {
12141             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
12142             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
12143         } else {
12144             frame_info->displayAspectRatio.displayHorizontalSize = 0;
12145             frame_info->displayAspectRatio.displayVerticalSize = 0;
12146         }
12147     }
12148 
12149     if (panscan_payload) {
12150         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
12151         panscan_window = &panscan_payload->wnd[0];
12152         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
12153             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
12154             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
12155             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
12156             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
12157             panscan_window++;
12158         }
12159     }
12160     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
12161     print_debug_extradata(extra);
12162 }
12163 
12164 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12165 {
12166     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
12167     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
12168     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12169     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12170     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
12171     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
12172     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
12173     *portDefn = m_port_def;
12174     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
12175             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
12176             (unsigned int)portDefn->format.video.nFrameWidth,
12177             (unsigned int)portDefn->format.video.nStride,
12178             (unsigned int)portDefn->format.video.nSliceHeight);
12179 }
12180 
12181 void omx_vdec::append_outputcrop_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12182         struct msm_vidc_output_crop_payload *output_crop_payload) {
12183     extra->nSize = OMX_OUTPUTCROP_EXTRADATA_SIZE;
12184     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12185     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12186     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo;
12187     extra->nDataSize = sizeof(OMX_QCOM_OUTPUT_CROP);
12188     memcpy(extra->data, output_crop_payload, extra->nDataSize);
12189 
12190     print_debug_extradata(extra);
12191 }
12192 
12193 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12194         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
12195 {
12196     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
12197     if (18 * sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
12198         DEBUG_PRINT_ERROR("frame packing size mismatch");
12199         return;
12200     }
12201     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
12202     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12203     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12204     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
12205     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12206     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
12207     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12208     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
12209     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12210     memcpy(&framepack->id, s3d_frame_packing_payload,
12211         sizeof(struct msm_vidc_s3d_frame_packing_payload));
12212     memcpy(&m_frame_pack_arrangement, framepack,
12213         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
12214     print_debug_extradata(extra);
12215 }
12216 
12217 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12218             struct msm_vidc_frame_qp_payload *qp_payload)
12219 {
12220     OMX_QCOM_EXTRADATA_QP * qp = NULL;
12221     if (!qp_payload) {
12222         DEBUG_PRINT_ERROR("QP payload is NULL");
12223         return;
12224     }
12225     extra->nSize = OMX_QP_EXTRADATA_SIZE;
12226     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12227     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12228     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
12229     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
12230     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
12231     qp->nQP = qp_payload->frame_qp;
12232     qp->nQPSum = qp_payload->qp_sum;
12233     qp->nSkipQPSum = qp_payload->skip_qp_sum;
12234     qp->nSkipNumBlocks = qp_payload->skip_num_blocks;
12235     qp->nTotalNumBlocks = qp_payload->total_num_blocks;
12236     print_debug_extradata(extra);
12237 }
12238 
12239 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12240             struct msm_vidc_frame_bits_info_payload *bits_payload)
12241 {
12242     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
12243     if (!bits_payload) {
12244         DEBUG_PRINT_ERROR("bits info payload is NULL");
12245         return;
12246     }
12247     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
12248     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12249     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12250     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
12251     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
12252     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
12253     bits->frame_bits = bits_payload->frame_bits;
12254     bits->header_bits = bits_payload->header_bits;
12255     print_debug_extradata(extra);
12256 }
12257 
12258 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12259             OMX_OTHER_EXTRADATATYPE *p_user)
12260 {
12261     int userdata_size = 0;
12262     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
12263     userdata_payload =
12264         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
12265     userdata_size = p_user->nDataSize;
12266     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
12267     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12268     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12269     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
12270     extra->nDataSize = userdata_size;
12271     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
12272         memcpy(extra->data, p_user->data, extra->nDataSize);
12273     print_debug_extradata(extra);
12274 }
12275 
12276 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12277 {
12278     if (!client_extradata) {
12279         return;
12280     }
12281     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
12282     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12283     extra->eType = OMX_ExtraDataNone;
12284     extra->nDataSize = 0;
12285     extra->data[0] = 0;
12286 
12287     print_debug_extradata(extra);
12288 }
12289 
12290 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
12291 {
12292     OMX_ERRORTYPE eRet = OMX_ErrorNone;
12293     if (index >= drv_ctx.ip_buf.actualcount) {
12294         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
12295         return OMX_ErrorInsufficientResources;
12296     }
12297     if (m_desc_buffer_ptr == NULL) {
12298         m_desc_buffer_ptr = (desc_buffer_hdr*) \
12299                     calloc( (sizeof(desc_buffer_hdr)),
12300                             drv_ctx.ip_buf.actualcount);
12301         if (m_desc_buffer_ptr == NULL) {
12302             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
12303             return OMX_ErrorInsufficientResources;
12304         }
12305     }
12306 
12307     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
12308     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
12309         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
12310         return OMX_ErrorInsufficientResources;
12311     }
12312 
12313     return eRet;
12314 }
12315 
12316 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
12317 {
12318     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
12319     if (m_demux_entries < 8192) {
12320         m_demux_offsets[m_demux_entries++] = address_offset;
12321     }
12322     return;
12323 }
12324 
12325 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
12326 {
12327     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
12328     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
12329     OMX_U32 index = 0;
12330 
12331     m_demux_entries = 0;
12332 
12333     while (index < bytes_to_parse) {
12334         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12335                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
12336                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12337                  (buf[index+2] == 0x01)) ) {
12338             //Found start code, insert address offset
12339             insert_demux_addr_offset(index);
12340             if (buf[index+2] == 0x01) // 3 byte start code
12341                 index += 3;
12342             else                      //4 byte start code
12343                 index += 4;
12344         } else
12345             index++;
12346     }
12347     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
12348     return;
12349 }
12350 
12351 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
12352 {
12353     //fix this, handle 3 byte start code, vc1 terminator entry
12354     OMX_U8 *p_demux_data = NULL;
12355     OMX_U32 desc_data = 0;
12356     OMX_U32 start_addr = 0;
12357     OMX_U32 nal_size = 0;
12358     OMX_U32 suffix_byte = 0;
12359     OMX_U32 demux_index = 0;
12360     OMX_U32 buffer_index = 0;
12361 
12362     if (m_desc_buffer_ptr == NULL) {
12363         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
12364         return OMX_ErrorBadParameter;
12365     }
12366 
12367     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
12368     if (buffer_index > drv_ctx.ip_buf.actualcount) {
12369         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
12370         return OMX_ErrorBadParameter;
12371     }
12372 
12373     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
12374 
12375     if ( ((OMX_U8*)p_demux_data == NULL) ||
12376             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
12377         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
12378         return OMX_ErrorBadParameter;
12379     } else {
12380         for (; demux_index < m_demux_entries; demux_index++) {
12381             desc_data = 0;
12382             start_addr = m_demux_offsets[demux_index];
12383             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
12384                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
12385             } else {
12386                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
12387             }
12388             if (demux_index < (m_demux_entries - 1)) {
12389                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
12390             } else {
12391                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
12392             }
12393             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
12394                     (unsigned int)start_addr,
12395                     (unsigned int)suffix_byte,
12396                     (unsigned int)nal_size,
12397                     (unsigned int)demux_index);
12398             desc_data = (start_addr >> 3) << 1;
12399             desc_data |= (start_addr & 7) << 21;
12400             desc_data |= suffix_byte << 24;
12401 
12402             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
12403             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
12404             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
12405             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
12406 
12407             p_demux_data += 16;
12408         }
12409         //Add zero word to indicate end of descriptors
12410         memset(p_demux_data, 0, sizeof(OMX_U32));
12411 
12412         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
12413         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
12414     }
12415     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
12416     m_demux_entries = 0;
12417     DEBUG_PRINT_LOW("Demux table complete!");
12418     return OMX_ErrorNone;
12419 }
12420 
12421 void omx_vdec::allocate_color_convert_buf::enable_color_conversion(bool enable) {
12422     if (!omx) {
12423         DEBUG_PRINT_HIGH("Invalid omx_vdec");
12424         return;
12425     }
12426 
12427     if (!omx->in_reconfig)
12428         enabled = enable;
12429 
12430     omx->c2d_enable_pending = enable;
12431 }
12432 
12433 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
12434 {
12435     enabled = false;
12436     client_buffers_disabled = false;
12437     omx = NULL;
12438     init_members();
12439     ColorFormat = OMX_COLOR_FormatMax;
12440     dest_format = YCbCr420P;
12441     m_c2d_width = 0;
12442     m_c2d_height = 0;
12443 
12444     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][-1] =
12445                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
12446     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][VDEC_CODECTYPE_MVC] =
12447                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
12448     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_UBWC][-1] =
12449                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
12450     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_TP10_UBWC][-1] =
12451                      QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
12452     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_P010_VENUS][-1] =
12453                      QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus;
12454 
12455     mMapOutput2Convert.insert( {
12456             {VDEC_YUV_FORMAT_NV12, NV12_128m},
12457             {VDEC_YUV_FORMAT_NV12_UBWC, NV12_UBWC},
12458             {VDEC_YUV_FORMAT_NV12_TP10_UBWC, TP10_UBWC},
12459             {VDEC_YUV_FORMAT_P010_VENUS, YCbCr420_VENUS_P010},
12460         });
12461 }
12462 
12463 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
12464 {
12465     omx = reinterpret_cast<omx_vdec*>(client);
12466 }
12467 
12468 void omx_vdec::allocate_color_convert_buf::init_members()
12469 {
12470     allocated_count = 0;
12471     buffer_size_req = 0;
12472     buffer_alignment_req = 0;
12473     m_c2d_width = m_c2d_height = 0;
12474     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
12475     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
12476     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
12477     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
12478 #ifdef USE_ION
12479     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
12480 #endif
12481     for (int i = 0; i < MAX_COUNT; i++)
12482         pmem_fd[i] = -1;
12483 }
12484 
12485 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
12486 {
12487     bool status = true;
12488     unsigned int src_size = 0, destination_size = 0;
12489     unsigned int height, width;
12490     struct v4l2_format fmt;
12491     OMX_COLOR_FORMATTYPE drv_color_format;
12492 
12493     if (!omx) {
12494         DEBUG_PRINT_ERROR("Invalid client in color convert");
12495         return false;
12496     }
12497     if (!enabled) {
12498         DEBUG_PRINT_HIGH("No color conversion required");
12499         return true;
12500     }
12501     pthread_mutex_lock(&omx->c_lock);
12502 
12503     ColorSubMapping::const_iterator
12504         found =  mMapOutput2Convert.find(omx->drv_ctx.output_format);
12505     if (found == mMapOutput2Convert.end()) {
12506         DEBUG_PRINT_HIGH("%s: Could not find the color conversion "
12507                          "mapping for %#X. Setting to default NV12",
12508                          __func__, omx->drv_ctx.output_format);
12509         src_format = NV12_128m;
12510     } else {
12511         src_format = (ColorConvertFormat) found->second;;
12512     }
12513 
12514     memset(&fmt, 0x0, sizeof(struct v4l2_format));
12515     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
12516     fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
12517     ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
12518     width = fmt.fmt.pix_mp.width;
12519     height =  fmt.fmt.pix_mp.height;
12520 
12521     bool resolution_upgrade = (height > m_c2d_height ||
12522             width > m_c2d_width);
12523     bool is_interlaced = omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
12524     if (resolution_upgrade) {
12525         // resolution upgraded ? ensure we are yet to allocate;
12526         // failing which, c2d buffers will never be reallocated and bad things will happen
12527         if (allocated_count > 0) {
12528             DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
12529                     allocated_count);
12530             status = false;
12531         }
12532     }
12533 
12534     if (status != false) {
12535         if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
12536             (ColorFormat != OMX_COLOR_FormatYUV420Planar &&
12537              ColorFormat != OMX_COLOR_FormatYUV420SemiPlanar &&
12538              ColorFormat != (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12539             DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
12540             status = false;
12541         } else {
12542             ColorSubMapping::const_iterator
12543                 found =  mMapOutput2Convert.find(
12544                                                  omx->drv_ctx.output_format);
12545             if (found == mMapOutput2Convert.end()) {
12546                 src_format = NV12_128m;
12547             } else {
12548                 src_format = (ColorConvertFormat) found->second;;
12549             }
12550 
12551             DEBUG_PRINT_INFO("C2D: Set Resolution, Interlace(%s) Conversion(%#X -> %#X)"
12552                              " src(%dX%d) dest(%dX%d)",
12553                              (omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) ? "true": "false",
12554                              src_format, dest_format, width,
12555                              omx->m_progressive !=
12556                                   MSM_VIDC_PIC_STRUCT_PROGRESSIVE?(height+1)/2 : height,
12557                              width, height);
12558             status = c2dcc.setResolution(width,
12559                                          omx->m_progressive !=
12560                                          MSM_VIDC_PIC_STRUCT_PROGRESSIVE?
12561                                          (height+1)/2 : height,
12562                                          width, height,
12563                                          src_format, dest_format,
12564                                          0,0);
12565             if (status) {
12566                 src_size = c2dcc.getBuffSize(C2D_INPUT);
12567                 destination_size = c2dcc.getBuffSize(C2D_OUTPUT);
12568 
12569                 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
12570                     !destination_size) {
12571                     DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
12572                                       "driver size %u destination size %d",
12573                                       src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
12574                                       destination_size);
12575                     buffer_size_req = 0;
12576                     // TODO: make this fatal. Driver is not supposed to quote size
12577                     //  smaller than what C2D needs !!
12578                 } else {
12579                     buffer_size_req = destination_size;
12580                     m_c2d_height = height;
12581                     m_c2d_width = width;
12582                 }
12583             }
12584         }
12585     }
12586     pthread_mutex_unlock(&omx->c_lock);
12587     return status;
12588 }
12589 
12590 bool omx_vdec::allocate_color_convert_buf::set_color_format(
12591         OMX_COLOR_FORMATTYPE dest_color_format)
12592 {
12593     bool status = true, drv_colorformat_c2d_enable = false;
12594     bool dest_color_format_c2d_enable = false;
12595     OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused;
12596     if (!omx) {
12597         DEBUG_PRINT_ERROR("Invalid client in color convert");
12598         return false;
12599     }
12600     pthread_mutex_lock(&omx->c_lock);
12601     status = get_color_format (drv_color_format);
12602 
12603     drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) &&
12604         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12605                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
12606         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12607                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed) &&
12608         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12609                 QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus);
12610 
12611     dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
12612             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
12613             (dest_color_format != (OMX_COLOR_FORMATTYPE)
12614                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
12615 
12616     if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) {
12617         DEBUG_PRINT_LOW("Enabling C2D");
12618         if (dest_color_format == OMX_COLOR_FormatYUV420Planar ||
12619             dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar ||
12620             (omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE &&
12621             dest_color_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12622             ColorFormat = dest_color_format;
12623             if (dest_color_format == OMX_COLOR_FormatYUV420Planar) {
12624                    dest_format = YCbCr420P;
12625             } else if( dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar) {
12626                     dest_format = YCbCr420SP;
12627             } else {
12628                    dest_format = NV12_128m;
12629             }
12630             enable_color_conversion(true);
12631         } else {
12632             DEBUG_PRINT_ERROR("Unsupported output color format for c2d (%d)",
12633                               dest_color_format);
12634             status = false;
12635             enable_color_conversion(false);
12636         }
12637     } else {
12638         enable_color_conversion(false);
12639     }
12640     pthread_mutex_unlock(&omx->c_lock);
12641     return status;
12642 }
12643 
12644 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
12645 (OMX_BUFFERHEADERTYPE *bufadd)
12646 {
12647     if (!omx) {
12648         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
12649         return NULL;
12650     }
12651     if (!is_color_conversion_enabled())
12652         return bufadd;
12653 
12654     OMX_BUFFERHEADERTYPE  *omx_base_address =
12655               is_color_conversion_enabled()?
12656                     omx->m_intermediate_out_mem_ptr:omx->m_out_mem_ptr;
12657 
12658     unsigned index = 0;
12659     index = bufadd - omx_base_address;
12660     if (index < omx->drv_ctx.op_buf.actualcount) {
12661         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12662         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
12663 
12664         omx->m_out_mem_ptr[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12665         omx->m_out_mem_ptr[index].nTimeStamp = bufadd->nTimeStamp;
12666         bool status = false;
12667         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
12668             pthread_mutex_lock(&omx->c_lock);
12669             omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12670 
12671             DEBUG_PRINT_INFO("C2D: Start color convertion");
12672             status = c2dcc.convertC2D(
12673                              omx->drv_ctx.ptr_intermediate_outputbuffer[index].pmem_fd,
12674                              bufadd->pBuffer, bufadd->pBuffer,
12675                              omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
12676                              omx->m_out_mem_ptr[index].pBuffer,
12677                              omx->m_out_mem_ptr[index].pBuffer);
12678             omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12679             if (!status) {
12680                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
12681                 m_out_mem_ptr_client[index].nFilledLen = 0;
12682                 omx->m_out_mem_ptr[index].nFilledLen = 0;
12683                 pthread_mutex_unlock(&omx->c_lock);
12684                 return &omx->m_out_mem_ptr[index];
12685             } else {
12686                 unsigned int filledLen = 0;
12687                 c2dcc.getBuffFilledLen(C2D_OUTPUT, filledLen);
12688                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
12689                 omx->m_out_mem_ptr[index].nFilledLen = filledLen;
12690             }
12691             pthread_mutex_unlock(&omx->c_lock);
12692         } else {
12693             m_out_mem_ptr_client[index].nFilledLen = 0;
12694             omx->m_out_mem_ptr[index].nFilledLen = 0;
12695         }
12696         return &omx->m_out_mem_ptr[index];
12697     }
12698     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
12699     return NULL;
12700 }
12701 
12702     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
12703 (unsigned int &buffer_size)
12704 {
12705     bool status = true;
12706     pthread_mutex_lock(&omx->c_lock);
12707      /* Whenever port mode is set to kPortModeDynamicANWBuffer, Video Frameworks
12708         always uses VideoNativeMetadata and OMX receives buffer type as
12709         grallocsource via storeMetaDataInBuffers_l API. The buffer_size
12710         will be communicated to frameworks via IndexParamPortdefinition. */
12711     if (!enabled)
12712         buffer_size = omx->dynamic_buf_mode ? sizeof(struct VideoNativeMetadata) :
12713                       omx->drv_ctx.op_buf.buffer_size;
12714     else {
12715         buffer_size = c2dcc.getBuffSize(C2D_OUTPUT);
12716     }
12717     pthread_mutex_unlock(&omx->c_lock);
12718     return status;
12719 }
12720 
12721 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
12722         OMX_U32 buffer_size, OMX_U32 actual_count)
12723 {
12724     OMX_U32 expectedSize = is_color_conversion_enabled() ? buffer_size_req : omx->dynamic_buf_mode ?
12725             sizeof(struct VideoDecoderOutputMetaData) : omx->drv_ctx.op_buf.buffer_size;
12726     if (buffer_size < expectedSize) {
12727         DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
12728                 buffer_size, expectedSize);
12729         return OMX_ErrorBadParameter;
12730     }
12731     if (actual_count < omx->drv_ctx.op_buf.mincount) {
12732         DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
12733                 actual_count, omx->drv_ctx.op_buf.mincount);
12734         return OMX_ErrorBadParameter;
12735     }
12736 
12737     if (enabled) {
12738         // disallow changing buffer size/count while we have active allocated buffers
12739         if (allocated_count > 0) {
12740             DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
12741                     buffer_size_req, buffer_size, allocated_count);
12742             return OMX_ErrorInvalidState;
12743         }
12744 
12745         buffer_size_req = buffer_size;
12746     } else {
12747         if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
12748             omx->drv_ctx.op_buf.buffer_size = buffer_size;
12749         }
12750     }
12751 
12752     omx->drv_ctx.op_buf.actualcount = actual_count;
12753     omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
12754     omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
12755             omx->drv_ctx.extradata_info.buffer_size;
12756     return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
12757 }
12758 
12759 bool omx_vdec::is_component_secure()
12760 {
12761     return secure_mode;
12762 }
12763 
12764 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
12765 {
12766     bool status = true;
12767     if (!enabled) {
12768         for (auto& x: mMapOutput2DriverColorFormat) {
12769             DecColorMapping::const_iterator
12770                 found = mMapOutput2DriverColorFormat.find(omx->drv_ctx.output_format);
12771             if (found == mMapOutput2DriverColorFormat.end()) {
12772                 status = false;
12773             } else {
12774                 ColorSubMapping::const_iterator
12775                     subFound = found->second.find(omx->drv_ctx.decoder_format);
12776                 if (subFound == found->second.end()) {
12777                     dest_color_format = (OMX_COLOR_FORMATTYPE)
12778                                              found->second.find(-1)->second;
12779                 } else {
12780                     dest_color_format = (OMX_COLOR_FORMATTYPE) subFound->second;
12781                 }
12782             }
12783         }
12784     } else {
12785         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
12786             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
12787             ColorFormat == (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
12788             dest_color_format = ColorFormat;
12789         } else {
12790             status = false;
12791         }
12792     }
12793     return status;
12794 }
12795 
12796 void omx_vdec::send_codec_config() {
12797     if (codec_config_flag) {
12798         unsigned long p1 = 0; // Parameter - 1
12799         unsigned long p2 = 0; // Parameter - 2
12800         unsigned long ident = 0;
12801         pthread_mutex_lock(&m_lock);
12802         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
12803         while (m_etb_q.m_size) {
12804             m_etb_q.pop_entry(&p1,&p2,&ident);
12805             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
12806                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12807                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
12808                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12809                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
12810                         omx_report_error();
12811                     }
12812                 } else {
12813                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
12814                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
12815                 }
12816             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
12817                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12818                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
12819                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12820                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
12821                         omx_report_error ();
12822                     }
12823                 } else {
12824                     pending_input_buffers++;
12825                     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
12826                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
12827                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
12828                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
12829                 }
12830             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
12831                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
12832                         (OMX_BUFFERHEADERTYPE *)p1);
12833                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
12834             }
12835         }
12836         pthread_mutex_unlock(&m_lock);
12837     }
12838 }
12839 
12840 omx_vdec::perf_control::perf_control()
12841 {
12842     m_perf_control_enable = 0;
12843     m_perf_lib = NULL;
12844     m_perf_handle = 0;
12845     m_perf_lock_acquire = NULL;
12846     m_perf_lock_release = NULL;
12847 }
12848 
12849 omx_vdec::perf_control::~perf_control()
12850 {
12851     if (!m_perf_control_enable)
12852         return;
12853 
12854     if (m_perf_handle && m_perf_lock_release) {
12855         m_perf_lock_release(m_perf_handle);
12856         DEBUG_PRINT_LOW("perflock released");
12857     }
12858     if (m_perf_lib) {
12859         dlclose(m_perf_lib);
12860     }
12861 }
12862 
12863 int omx_vdec::perf_control::perf_lock_acquire()
12864 {
12865     int arg[2];
12866     if (!m_perf_control_enable)
12867         return 0;
12868 
12869     if (!m_perf_lib) {
12870         DEBUG_PRINT_ERROR("no perf control library");
12871         return -1;
12872     }
12873     if (!m_perf_lock_acquire) {
12874         DEBUG_PRINT_ERROR("NULL perflock acquire");
12875         return -1;
12876     }
12877     if (m_perf_handle) {
12878         DEBUG_PRINT_LOW("perflock already acquired");
12879         return 0;
12880     }
12881     DEBUG_PRINT_HIGH("perflock acquire");
12882     arg[0] = MPCTLV3_VIDEO_DECODE_PB_HINT;
12883     arg[1] = 1;
12884     m_perf_handle = m_perf_lock_acquire(0, 0, arg, sizeof(arg) / sizeof(int));
12885     if (m_perf_handle < 0) {
12886         DEBUG_PRINT_ERROR("perflock acquire failed with error %d", m_perf_handle);
12887         m_perf_handle = 0;
12888         return -1;
12889     }
12890     return 0;
12891 }
12892 
12893 void omx_vdec::perf_control::perf_lock_release()
12894 {
12895     if (!m_perf_control_enable)
12896         return;
12897 
12898     if (!m_perf_lib) {
12899         DEBUG_PRINT_ERROR("no perf control library");
12900         return;
12901     }
12902     if (!m_perf_lock_release) {
12903         DEBUG_PRINT_ERROR("NULL perflock release");
12904         return;
12905     }
12906     if (!m_perf_handle) {
12907         DEBUG_PRINT_LOW("perflock already released");
12908         return;
12909     }
12910     DEBUG_PRINT_HIGH("perflock release");
12911     m_perf_lock_release(m_perf_handle);
12912     m_perf_handle = 0;
12913 }
12914 
12915 bool omx_vdec::perf_control::load_perf_library()
12916 {
12917     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
12918 
12919     if (!m_perf_control_enable) {
12920         DEBUG_PRINT_HIGH("perf control is not enabled");
12921         return false;
12922     }
12923     if (m_perf_lib) {
12924         DEBUG_PRINT_HIGH("perf lib already opened");
12925         return true;
12926     }
12927 
12928     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
12929         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
12930         goto handle_err;
12931     }
12932 
12933     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
12934         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
12935         goto handle_err;
12936     } else {
12937         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
12938         if (m_perf_lock_acquire == NULL) {
12939             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
12940             goto handle_err;
12941         }
12942         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
12943         if (m_perf_lock_release == NULL) {
12944             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
12945             goto handle_err;
12946         }
12947     }
12948     return true;
12949 
12950 handle_err:
12951     if (m_perf_lib) {
12952         dlclose(m_perf_lib);
12953     }
12954     m_perf_lib = NULL;
12955     m_perf_lock_acquire = NULL;
12956     m_perf_lock_release = NULL;
12957     return false;
12958 }
12959 
12960 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
12961                             unsigned long nMaxFrameHeight)
12962 {
12963 
12964     OMX_ERRORTYPE eRet = OMX_ErrorNone;
12965     int ret = 0;
12966     unsigned long min_res_buf_count = 0;
12967 
12968     eRet = enable_smoothstreaming();
12969     if (eRet != OMX_ErrorNone) {
12970          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
12971          return eRet;
12972      }
12973 
12974      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
12975              nMaxFrameWidth,
12976              nMaxFrameHeight);
12977      m_smoothstreaming_mode = true;
12978      m_smoothstreaming_width = nMaxFrameWidth;
12979      m_smoothstreaming_height = nMaxFrameHeight;
12980 
12981      //Get upper limit buffer count for min supported resolution
12982      struct v4l2_format fmt;
12983      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
12984      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
12985      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
12986      fmt.fmt.pix_mp.pixelformat = output_capability;
12987 
12988      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
12989      if (ret) {
12990          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
12991                            m_decoder_capability.min_height,
12992                            m_decoder_capability.min_width);
12993          return OMX_ErrorUnsupportedSetting;
12994      }
12995 
12996      eRet = get_buffer_req(&drv_ctx.op_buf);
12997      if (eRet != OMX_ErrorNone) {
12998          DEBUG_PRINT_ERROR("failed to get_buffer_req");
12999          return eRet;
13000      }
13001 
13002      min_res_buf_count = drv_ctx.op_buf.mincount;
13003      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
13004                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
13005 
13006      m_extradata_info.output_crop_rect.nLeft = 0;
13007      m_extradata_info.output_crop_rect.nTop = 0;
13008      m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width;
13009      m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height;
13010 
13011      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
13012                        m_smoothstreaming_width, m_smoothstreaming_height);
13013 
13014      //Get upper limit buffer size for max smooth streaming resolution set
13015      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
13016      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
13017      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
13018      fmt.fmt.pix_mp.pixelformat = output_capability;
13019      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
13020      if (ret) {
13021          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
13022          return OMX_ErrorUnsupportedSetting;
13023      }
13024 
13025      eRet = get_buffer_req(&drv_ctx.op_buf);
13026      if (eRet != OMX_ErrorNone) {
13027          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
13028          return eRet;
13029      }
13030      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
13031                      (unsigned int)drv_ctx.op_buf.buffer_size);
13032 
13033      drv_ctx.op_buf.mincount = min_res_buf_count;
13034      drv_ctx.op_buf.actualcount = min_res_buf_count;
13035      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
13036      eRet = set_buffer_req(&drv_ctx.op_buf);
13037      if (eRet != OMX_ErrorNone) {
13038          DEBUG_PRINT_ERROR("failed to set_buffer_req");
13039          return eRet;
13040      }
13041 
13042      eRet = get_buffer_req(&drv_ctx.op_buf);
13043      if (eRet != OMX_ErrorNone) {
13044          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
13045          return eRet;
13046      }
13047      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
13048                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
13049      return eRet;
13050 }
13051 
13052 //static
13053 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
13054 
13055 #ifndef FLEXYUV_SUPPORTED
13056     return OMX_ErrorUndefined;
13057 #else
13058 
13059     if (pParam == NULL) {
13060         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
13061         return OMX_ErrorBadParameter;
13062     }
13063 
13064     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
13065 
13066     MediaImage *img = &(params->sMediaImage);
13067     switch(params->eColorFormat) {
13068         case static_cast <OMX_COLOR_FORMATTYPE> (QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m):
13069         {
13070             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
13071             img->mNumPlanes = 3;
13072             // mWidth and mHeight represent the W x H of the largest plane
13073             // In our case, this happens to be the Stride x Scanlines of Y plane
13074             img->mWidth = params->nFrameWidth;
13075             img->mHeight = params->nFrameHeight;
13076             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13077             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
13078             img->mBitDepth = 8;
13079             //Plane 0 (Y)
13080             img->mPlane[MediaImage::Y].mOffset = 0;
13081             img->mPlane[MediaImage::Y].mColInc = 1;
13082             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
13083             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
13084             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
13085             //Plane 1 (U)
13086             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
13087             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
13088             img->mPlane[MediaImage::U].mRowInc =
13089                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13090             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
13091             img->mPlane[MediaImage::U].mVertSubsampling = 2;
13092             //Plane 2 (V)
13093             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
13094             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
13095             img->mPlane[MediaImage::V].mRowInc =
13096                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13097             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
13098             img->mPlane[MediaImage::V].mVertSubsampling = 2;
13099             break;
13100         }
13101 
13102         case OMX_COLOR_FormatYUV420Planar:
13103         case OMX_COLOR_FormatYUV420SemiPlanar:
13104             // We need not describe the standard OMX linear formats as these are
13105             // understood by client. Fail this deliberately to let client fill-in
13106             return OMX_ErrorUnsupportedSetting;
13107 
13108         default:
13109             // Rest all formats which are non-linear cannot be described
13110             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
13111             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
13112             return OMX_ErrorNone;
13113     };
13114 
13115     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
13116     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
13117     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
13118     for (size_t i = 0; i < img->mNumPlanes; ++i) {
13119         DEBUG_PRINT_LOW("  Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
13120                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
13121     }
13122     return OMX_ErrorNone;
13123 #endif //FLEXYUV_SUPPORTED
13124 }
13125 
13126 bool omx_vdec::prefetch_buffers(unsigned long prefetch_count,
13127         unsigned long prefetch_size, unsigned ioctl_code, unsigned ion_flag)
13128 {
13129     struct ion_prefetch_data prefetch_data;
13130     struct ion_prefetch_regions regions;
13131     __u64 sizes[prefetch_count];
13132     int rc, ion_fd = ion_open();
13133     if (ion_fd < 0) {
13134         DEBUG_PRINT_ERROR("%s: Ion fd open failed : %d", __func__, ion_fd);
13135         return false;
13136     }
13137 
13138     DEBUG_PRINT_HIGH("%s: prefetch_count : %lu, prefetch_size : %lu, ioctl : %u",
13139             __func__, prefetch_count, prefetch_size, ioctl_code);
13140     for (uint32_t i = 0; i < prefetch_count; i++) {
13141         sizes[i] = prefetch_size;
13142     }
13143 
13144     regions.nr_sizes = prefetch_count;
13145 #if TARGET_ION_ABI_VERSION >= 2
13146     regions.sizes = (__u64)sizes;
13147 #else
13148     regions.sizes = sizes;
13149 #endif
13150     regions.vmid = ion_flag;
13151 
13152     prefetch_data.nr_regions = 1;
13153 #if TARGET_ION_ABI_VERSION >= 2
13154     prefetch_data.regions = (__u64)&regions;
13155 #else
13156     prefetch_data.regions = &regions;
13157 #endif
13158     prefetch_data.heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
13159 
13160     rc = ioctl(ion_fd, ioctl_code, &prefetch_data);
13161     if (rc) {
13162         DEBUG_PRINT_ERROR("%s: Prefetch ioctl failed ioctl : %u, rc : %d, errno : %d",
13163                 __func__, ioctl_code, rc, errno);
13164         rc = false;
13165     } else {
13166         rc = true;
13167     }
13168 
13169     close(ion_fd);
13170     return rc;
13171 }
13172 
13173 bool omx_vdec::store_vp9_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13174 {
13175     struct hdr10plusInfo metadata;
13176 
13177     if (!hdr10plusdata) {
13178         DEBUG_PRINT_ERROR("hdr10plus info not present");
13179         return false;
13180     }
13181 
13182     if (hdr10plusdata->nParamSize > MAX_HDR10PLUSINFO_SIZE ||
13183             hdr10plusdata->nParamSize < 1) {
13184         DEBUG_PRINT_ERROR("Invalid hdr10plus metadata size %u", hdr10plusdata->nParamSize);
13185         return false;
13186     }
13187 
13188     if (output_capability != V4L2_PIX_FMT_VP9) {
13189         DEBUG_PRINT_ERROR("DescribeHDR10PlusInfoParams is not supported for %d codec",
13190             output_capability);
13191         return false;
13192     }
13193 
13194     memset(&metadata, 0, sizeof(struct hdr10plusInfo));
13195     metadata.nSize = hdr10plusdata->nSize;
13196     metadata.nVersion = hdr10plusdata->nVersion;
13197     metadata.nPortIndex = hdr10plusdata->nPortIndex;
13198     metadata.nParamSize = hdr10plusdata->nParamSize;
13199     metadata.nParamSizeUsed = hdr10plusdata->nParamSizeUsed;
13200     memcpy(metadata.payload, hdr10plusdata->nValue , hdr10plusdata->nParamSizeUsed);
13201     metadata.is_new = true;
13202 
13203     /*
13204      * For the first setconfig, set the timestamp as zero. For
13205      * the remaining, set the timestamp equal to previous
13206      * etb timestamp + 1 to know this hdr10plus data arrived
13207      * after previous etb.
13208      */
13209     if (m_etb_count) {
13210         metadata.timestamp = m_etb_timestamp + 1;
13211     }
13212 
13213     pthread_mutex_lock(&m_hdr10pluslock);
13214     DEBUG_PRINT_LOW("add hdr10plus info to the list with timestamp %lld and size %u",
13215         metadata.timestamp, metadata.nParamSizeUsed);
13216     m_hdr10pluslist.push_back(metadata);
13217     pthread_mutex_unlock(&m_hdr10pluslock);
13218 
13219     return true;
13220 }
13221 
13222 bool omx_vdec::store_hevc_hdr10plusinfo(uint32_t payload_size,
13223     msm_vidc_stream_userdata_payload *hdr10plusdata)
13224 {
13225     struct hdr10plusInfo metadata;
13226 
13227     if (!hdr10plusdata) {
13228         DEBUG_PRINT_ERROR("hdr10plus info not present");
13229         return false;
13230     }
13231 
13232     if (payload_size > MAX_HDR10PLUSINFO_SIZE ||
13233             payload_size < 1) {
13234         DEBUG_PRINT_ERROR("Invalid hdr10plus metadata size %u", payload_size);
13235         return false;
13236     }
13237 
13238     if (output_capability != V4L2_PIX_FMT_HEVC) {
13239         DEBUG_PRINT_ERROR("msm_vidc_stream_userdata_payload is not supported for %d codec",
13240             output_capability);
13241         return false;
13242     }
13243 
13244     memset(&metadata, 0, sizeof(struct hdr10plusInfo));
13245     metadata.nParamSizeUsed = payload_size;
13246     memcpy(metadata.payload, hdr10plusdata->data , payload_size);
13247     metadata.is_new = true;
13248     if (m_etb_count) {
13249         metadata.timestamp = m_etb_timestamp + 1;
13250     }
13251 
13252     pthread_mutex_lock(&m_hdr10pluslock);
13253     DEBUG_PRINT_LOW("add hevc hdr10plus info to the list with size %u", payload_size);
13254     m_hdr10pluslist.push_back(metadata);
13255     pthread_mutex_unlock(&m_hdr10pluslock);
13256 
13257     return true;
13258 }
13259 
13260 void omx_vdec::update_hdr10plusinfo_cookie_using_timestamp(OMX_PTR markdata, OMX_TICKS timestamp)
13261 {
13262     std::list<hdr10plusInfo>::reverse_iterator iter;
13263     unsigned int found = 0;
13264     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13265     bool is_list_empty = false;
13266 
13267     if (output_capability != V4L2_PIX_FMT_VP9 &&
13268         output_capability != V4L2_PIX_FMT_HEVC)
13269         return;
13270 
13271     pthread_mutex_lock(&m_hdr10pluslock);
13272     is_list_empty = m_hdr10pluslist.empty();
13273     pthread_mutex_unlock(&m_hdr10pluslock);
13274 
13275     if (is_list_empty) {
13276         DEBUG_PRINT_HIGH("update_hdr10plusinfo_cookie_using_timestamp: hdr10plusinfo list is empty!");
13277         return;
13278     }
13279     /*
13280      * look for the hdr10plus data which has timestamp nearest and
13281      * lower than the etb timestamp, we should not take the
13282      * hdr10plus data which has the timestamp greater than etb timestamp.
13283      */
13284     pthread_mutex_lock(&m_hdr10pluslock);
13285     iter = m_hdr10pluslist.rbegin();
13286     while (iter != m_hdr10pluslist.rend()) {
13287         if (iter->timestamp <= timestamp && iter->is_new) {
13288             found++;
13289             if (found == 1) {
13290                 iter->cookie = cookie;
13291                 iter->is_new = false;
13292                 DEBUG_PRINT_LOW("Cookie value %u stored in hdr10plus list with timestamp %lld, size %u",
13293                     iter->cookie, iter->timestamp, iter->nParamSizeUsed);
13294             }
13295         }
13296         iter++;
13297     }
13298     pthread_mutex_unlock(&m_hdr10pluslock);
13299 
13300     if(found > 1)
13301         DEBUG_PRINT_HIGH("Multiple hdr10plus data not expected. Continue with the latest");
13302 }
13303 
13304 void omx_vdec::convert_hdr10plusinfo_to_metadata(OMX_PTR markdata, ColorMetaData &colorData)
13305 {
13306     std::list<hdr10plusInfo>::iterator iter;
13307     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13308     bool is_list_empty = false;
13309 
13310     if (output_capability != V4L2_PIX_FMT_VP9 &&
13311         output_capability != V4L2_PIX_FMT_HEVC)
13312         return;
13313 
13314     pthread_mutex_lock(&m_hdr10pluslock);
13315     is_list_empty = m_hdr10pluslist.empty();
13316     pthread_mutex_unlock(&m_hdr10pluslock);
13317 
13318     if (is_list_empty) {
13319         DEBUG_PRINT_HIGH("convert_hdr10plusinfo_to_metadata: hdr10plusinfo list is empty!");
13320         return;
13321     }
13322 
13323     pthread_mutex_lock(&m_hdr10pluslock);
13324     iter = m_hdr10pluslist.begin();
13325     while (iter != m_hdr10pluslist.end()) {
13326         if (iter->cookie == cookie && !iter->is_new) {
13327             colorData.dynamicMetaDataValid = true;
13328             colorData.dynamicMetaDataLen = iter->nParamSizeUsed;
13329             memcpy(colorData.dynamicMetaDataPayload, iter->payload,
13330                 iter->nParamSizeUsed);
13331             DEBUG_PRINT_LOW("found hdr10plus metadata for cookie %u with timestamp %lld, size %u",
13332                 cookie, iter->timestamp, colorData.dynamicMetaDataLen);
13333             break;
13334         }
13335         iter++;
13336     }
13337     pthread_mutex_unlock(&m_hdr10pluslock);
13338 }
13339 
13340 void omx_vdec::remove_hdr10plusinfo_using_cookie(OMX_PTR markdata)
13341 {
13342     std::list<hdr10plusInfo>::iterator iter;
13343     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13344     bool is_list_empty = false;
13345 
13346     if (output_capability != V4L2_PIX_FMT_VP9 &&
13347         output_capability != V4L2_PIX_FMT_HEVC)
13348         return;
13349 
13350     pthread_mutex_lock(&m_hdr10pluslock);
13351     is_list_empty = m_hdr10pluslist.empty();
13352     pthread_mutex_unlock(&m_hdr10pluslock);
13353 
13354     if (is_list_empty) {
13355         DEBUG_PRINT_HIGH("remove_hdr10plusinfo_using_cookie: hdr10plusinfo list is empty!");
13356         return;
13357     }
13358 
13359     pthread_mutex_lock(&m_hdr10pluslock);
13360     iter = m_hdr10pluslist.begin();
13361     while (iter != m_hdr10pluslist.end()) {
13362         if (iter->cookie == cookie && !iter->is_new) {
13363             iter = m_hdr10pluslist.erase(iter);
13364             DEBUG_PRINT_LOW("removed hdr10plusinfo from the list for the cookie %u", cookie);
13365             break;
13366         }
13367         iter++;
13368     }
13369     pthread_mutex_unlock(&m_hdr10pluslock);
13370 }
13371 
13372 void omx_vdec::clear_hdr10plusinfo()
13373 {
13374     bool is_list_empty = false;
13375 
13376     if (output_capability != V4L2_PIX_FMT_VP9 &&
13377         output_capability != V4L2_PIX_FMT_HEVC)
13378         return;
13379 
13380     pthread_mutex_lock(&m_hdr10pluslock);
13381     is_list_empty = m_hdr10pluslist.empty();
13382     pthread_mutex_unlock(&m_hdr10pluslock);
13383 
13384     if (is_list_empty) {
13385         DEBUG_PRINT_HIGH("clear_hdr10plusinfo: hdr10plusinfo list is empty!");
13386         return;
13387     }
13388 
13389     pthread_mutex_lock(&m_hdr10pluslock);
13390     m_hdr10pluslist.clear();
13391     pthread_mutex_unlock(&m_hdr10pluslock);
13392 }
13393 
13394 void omx_vdec::get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13395 {
13396     std::list<hdr10plusInfo>::iterator iter;
13397     bool is_list_empty = false;
13398 
13399     if (output_capability != V4L2_PIX_FMT_VP9 &&
13400         output_capability != V4L2_PIX_FMT_HEVC)
13401         return;
13402 
13403     pthread_mutex_lock(&m_hdr10pluslock);
13404     is_list_empty = m_hdr10pluslist.empty();
13405     pthread_mutex_unlock(&m_hdr10pluslock);
13406 
13407     if (is_list_empty) {
13408         DEBUG_PRINT_HIGH("get_hdr10plusinfo: hdr10plusinfo list is empty!");
13409         return;
13410     }
13411 
13412     pthread_mutex_lock(&m_hdr10pluslock);
13413     iter = m_hdr10pluslist.begin();
13414     while (iter != m_hdr10pluslist.end()) {
13415         if (!iter->is_new) {
13416             hdr10plusdata->nParamSizeUsed = iter->nParamSizeUsed;
13417             memcpy(hdr10plusdata->nValue, iter->payload,
13418                 iter->nParamSizeUsed);
13419             DEBUG_PRINT_LOW("found hdr10plus metadata with timestamp %lld, size %u",
13420                 iter->timestamp, iter->nParamSizeUsed);
13421             iter = m_hdr10pluslist.erase(iter);
13422             break;
13423         }
13424         iter++;
13425     }
13426     pthread_mutex_unlock(&m_hdr10pluslock);
13427 }
13428 
13429 void omx_vdec::print_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13430 {
13431          DEBUG_PRINT_LOW("HDR10+ frameworks path valid data length: %d", hdr10plusdata->nParamSizeUsed);
13432         for (uint32_t i = 0 ; i < hdr10plusdata->nParamSizeUsed && i+3 < 1024; i=i+4) {
13433             DEBUG_PRINT_LOW("HDR10+ mdata: %02X %02X %02X %02X", hdr10plusdata->nValue[i],
13434             hdr10plusdata->nValue[i+1],
13435             hdr10plusdata->nValue[i+2],
13436             hdr10plusdata->nValue[i+3]);
13437     }
13438 }
13439 
13440 // No code beyond this !
13441 
13442 // inline import of vendor-extensions implementation
13443 #include "omx_vdec_extensions.hpp"
13444