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)®ions; 13155 #else 13156 prefetch_data.regions = ®ions; 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