1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010 - 2017, 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 <fcntl.h> 52 #include <limits.h> 53 #include <stdlib.h> 54 #include <media/hardware/HardwareAPI.h> 55 #include <sys/eventfd.h> 56 #include <nativebase/nativebase.h> 57 58 #if !defined(_ANDROID_) || defined(SYS_IOCTL) 59 #include <sys/ioctl.h> 60 #include <sys/mman.h> 61 #endif 62 63 #ifdef _ANDROID_ 64 #include <cutils/properties.h> 65 #undef USE_EGL_IMAGE_GPU 66 67 #ifdef _QUERY_DISP_RES_ 68 #include "display_config.h" 69 #endif 70 #endif 71 72 #ifdef _USE_GLIB_ 73 #include <glib.h> 74 #define strlcpy g_strlcpy 75 #endif 76 77 #include <qdMetaData.h> 78 #include <gralloc_priv.h> 79 80 #ifdef ANDROID_JELLYBEAN_MR2 81 #include "QComOMXMetadata.h" 82 #endif 83 84 #ifdef USE_EGL_IMAGE_GPU 85 #include <EGL/egl.h> 86 #include <EGL/eglQCOM.h> 87 #define EGL_BUFFER_HANDLE 0x4F00 88 #define EGL_BUFFER_OFFSET 0x4F01 89 #endif 90 91 #define BUFFER_LOG_LOC "/data/vendor/media" 92 93 #ifdef OUTPUT_EXTRADATA_LOG 94 FILE *outputExtradataFile; 95 char output_extradata_filename [] = "/data/vendor/media/extradata"; 96 #endif 97 98 #define DEFAULT_FPS 30 99 #define MAX_SUPPORTED_FPS 240 100 #define DEFAULT_WIDTH_ALIGNMENT 128 101 #define DEFAULT_HEIGHT_ALIGNMENT 32 102 103 #define VC1_SP_MP_START_CODE 0xC5000000 104 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 105 #define VC1_AP_SEQ_START_CODE 0x0F010000 106 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 107 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 108 #define VC1_SIMPLE_PROFILE 0 109 #define VC1_MAIN_PROFILE 1 110 #define VC1_ADVANCE_PROFILE 3 111 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 112 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 113 #define VC1_STRUCT_C_LEN 4 114 #define VC1_STRUCT_C_POS 8 115 #define VC1_STRUCT_A_POS 12 116 #define VC1_STRUCT_B_POS 24 117 #define VC1_SEQ_LAYER_SIZE 36 118 #define POLL_TIMEOUT 0x7fffffff 119 120 #define MEM_DEVICE "/dev/ion" 121 122 #ifdef _ANDROID_ 123 extern "C" { 124 #include<utils/Log.h> 125 } 126 #endif//_ANDROID_ 127 128 #define SZ_4K 0x1000 129 #define SZ_1M 0x100000 130 131 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 132 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 133 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0) 134 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1)) 135 136 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_FRAMEPACK_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA \ 137 | OMX_DISPLAY_INFO_EXTRADATA | OMX_HDR_COLOR_INFO_EXTRADATA) 138 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default 139 140 #ifndef ION_FLAG_CP_BITSTREAM 141 #define ION_FLAG_CP_BITSTREAM 0 142 #endif 143 144 #ifndef ION_FLAG_CP_PIXEL 145 #define ION_FLAG_CP_PIXEL 0 146 #endif 147 148 #ifdef MASTER_SIDE_CP 149 #define MEM_HEAP_ID ION_SECURE_HEAP_ID 150 #define SECURE_ALIGN SZ_4K 151 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM) 152 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL) 153 #else //SLAVE_SIDE_CP 154 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID 155 #define SECURE_ALIGN SZ_1M 156 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE 157 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE 158 #endif 159 160 #define LUMINANCE_DIV_FACTOR 10000.0 161 162 #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 163 #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 164 165 static OMX_U32 maxSmoothStreamingWidth = 1920; 166 static OMX_U32 maxSmoothStreamingHeight = 1088; 167 168 void* async_message_thread (void *input) 169 { 170 OMX_BUFFERHEADERTYPE *buffer; 171 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 172 struct pollfd pfds[2]; 173 struct v4l2_buffer v4l2_buf; 174 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 175 struct v4l2_event dqevent; 176 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 177 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 178 pfds[1].events = POLLIN | POLLERR; 179 pfds[0].fd = omx->drv_ctx.video_driver_fd; 180 pfds[1].fd = omx->m_poll_efd; 181 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; 182 DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); 183 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); 184 while (!omx->async_thread_force_stop) { 185 rc = poll(pfds, 2, POLL_TIMEOUT); 186 if (!rc) { 187 DEBUG_PRINT_ERROR("Poll timedout"); 188 break; 189 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) { 190 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno); 191 break; 192 } 193 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) { 194 DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited"); 195 break; 196 } 197 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) { 198 struct vdec_msginfo vdec_msg; 199 memset(&vdec_msg, 0, sizeof(vdec_msg)); 200 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 201 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 202 v4l2_buf.length = omx->drv_ctx.num_planes; 203 v4l2_buf.m.planes = plane; 204 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 205 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 206 vdec_msg.status_code=VDEC_S_SUCCESS; 207 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; 208 vdec_msg.msgdata.output_frame.len=plane[0].bytesused; 209 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; 210 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + 211 (uint64_t)v4l2_buf.timestamp.tv_usec; 212 213 if (omx->async_message_process(input,&vdec_msg) < 0) { 214 DEBUG_PRINT_HIGH("async_message_thread Exited"); 215 break; 216 } 217 } 218 } 219 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) { 220 struct vdec_msginfo vdec_msg; 221 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 222 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 223 v4l2_buf.length = 1; 224 v4l2_buf.m.planes = plane; 225 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 226 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; 227 vdec_msg.status_code=VDEC_S_SUCCESS; 228 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; 229 if (omx->async_message_process(input,&vdec_msg) < 0) { 230 DEBUG_PRINT_HIGH("async_message_thread Exited"); 231 break; 232 } 233 } 234 } 235 if (pfds[0].revents & POLLPRI) { 236 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent); 237 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { 238 struct vdec_msginfo vdec_msg; 239 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 240 241 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; 242 vdec_msg.status_code=VDEC_S_SUCCESS; 243 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0]; 244 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1]; 245 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient"); 246 if(ptr[2] & V4L2_EVENT_BITDEPTH_FLAG) { 247 omx->dpb_bit_depth = ptr[3]; 248 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", ptr[3]); 249 } 250 if(ptr[2] & V4L2_EVENT_PICSTRUCT_FLAG) { 251 omx->m_progressive = ptr[4]; 252 DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct change - %d", ptr[4]); 253 } 254 if(ptr[2] & V4L2_EVENT_COLOUR_SPACE_FLAG) { 255 if (ptr[5] == MSM_VIDC_BT2020) { 256 omx->m_color_space = omx_vdec::BT2020; 257 } else { 258 omx->m_color_space = omx_vdec::EXCEPT_BT2020; 259 } 260 DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace change - %d", omx->m_color_space); 261 } 262 if (omx->async_message_process(input,&vdec_msg) < 0) { 263 DEBUG_PRINT_HIGH("async_message_thread Exited"); 264 break; 265 } 266 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 267 struct vdec_msginfo vdec_msg; 268 uint32_t flush_type = *(uint32_t *)dqevent.u.data; 269 // Old driver doesn't send flushType information. 270 // To make this backward compatible fallback to old approach 271 // if the flush_type is not present. 272 vdec_msg.status_code=VDEC_S_SUCCESS; 273 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) { 274 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; 275 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved"); 276 if (omx->async_message_process(input,&vdec_msg) < 0) { 277 DEBUG_PRINT_HIGH("async_message_thread Exited"); 278 break; 279 } 280 } 281 282 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) { 283 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; 284 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved"); 285 if (omx->async_message_process(input,&vdec_msg) < 0) { 286 DEBUG_PRINT_HIGH("async_message_thread Exited"); 287 break; 288 } 289 } 290 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) { 291 struct vdec_msginfo vdec_msg; 292 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD; 293 vdec_msg.status_code=VDEC_S_SUCCESS; 294 DEBUG_PRINT_ERROR("HW Overload received"); 295 if (omx->async_message_process(input,&vdec_msg) < 0) { 296 DEBUG_PRINT_HIGH("async_message_thread Exited"); 297 break; 298 } 299 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) { 300 struct vdec_msginfo vdec_msg; 301 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED; 302 vdec_msg.status_code=VDEC_S_SUCCESS; 303 DEBUG_PRINT_ERROR("HW Unsupported received"); 304 if (omx->async_message_process(input,&vdec_msg) < 0) { 305 DEBUG_PRINT_HIGH("async_message_thread Exited"); 306 break; 307 } 308 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 309 struct vdec_msginfo vdec_msg; 310 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR; 311 vdec_msg.status_code = VDEC_S_SUCCESS; 312 DEBUG_PRINT_HIGH("SYS Error Recieved"); 313 if (omx->async_message_process(input,&vdec_msg) < 0) { 314 DEBUG_PRINT_HIGH("async_message_thread Exited"); 315 break; 316 } 317 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) { 318 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 319 320 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]); 321 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) { 322 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 323 struct vdec_msginfo vdec_msg; 324 325 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]); 326 327 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 328 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 329 v4l2_buf.length = omx->drv_ctx.num_planes; 330 v4l2_buf.m.planes = plane; 331 v4l2_buf.index = ptr[5]; 332 v4l2_buf.flags = 0; 333 334 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 335 vdec_msg.status_code = VDEC_S_SUCCESS; 336 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf; 337 vdec_msg.msgdata.output_frame.len = 0; 338 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2]; 339 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) + 340 (uint64_t)ptr[4]; 341 if (omx->async_message_process(input,&vdec_msg) < 0) { 342 DEBUG_PRINT_HIGH("async_message_thread Exitedn"); 343 break; 344 } 345 } else { 346 DEBUG_PRINT_HIGH("VIDC Some Event recieved"); 347 continue; 348 } 349 } 350 } 351 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); 352 return NULL; 353 } 354 355 void* message_thread_dec(void *input) 356 { 357 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 358 unsigned char id; 359 int n; 360 361 fd_set readFds; 362 int res = 0; 363 struct timeval tv; 364 365 DEBUG_PRINT_HIGH("omx_vdec: message thread start"); 366 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); 367 while (!omx->message_thread_stop) { 368 369 tv.tv_sec = 2; 370 tv.tv_usec = 0; 371 372 FD_ZERO(&readFds); 373 FD_SET(omx->m_pipe_in, &readFds); 374 375 res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv); 376 if (res < 0) { 377 DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno)); 378 continue; 379 } else if (res == 0 /*timeout*/ || omx->message_thread_stop) { 380 continue; 381 } 382 383 n = read(omx->m_pipe_in, &id, 1); 384 385 if (0 == n) { 386 break; 387 } 388 389 if (1 == n) { 390 omx->process_event_cb(omx, id); 391 } 392 393 if ((n < 0) && (errno != EINTR)) { 394 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno); 395 break; 396 } 397 } 398 DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); 399 return 0; 400 } 401 402 void post_message(omx_vdec *omx, unsigned char id) 403 { 404 int ret_value; 405 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); 406 ret_value = write(omx->m_pipe_out, &id, 1); 407 if (ret_value <= 0) { 408 DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno)); 409 } else { 410 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); 411 } 412 } 413 414 // omx_cmd_queue destructor 415 omx_vdec::omx_cmd_queue::~omx_cmd_queue() 416 { 417 // Nothing to do 418 } 419 420 // omx cmd queue constructor 421 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 422 { 423 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 424 } 425 426 // omx cmd queue insert 427 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id) 428 { 429 bool ret = true; 430 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) { 431 m_q[m_write].id = id; 432 m_q[m_write].param1 = p1; 433 m_q[m_write].param2 = p2; 434 m_write++; 435 m_size ++; 436 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) { 437 m_write = 0; 438 } 439 } else { 440 ret = false; 441 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__); 442 } 443 return ret; 444 } 445 446 // omx cmd queue pop 447 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id) 448 { 449 bool ret = true; 450 if (m_size > 0) { 451 *id = m_q[m_read].id; 452 *p1 = m_q[m_read].param1; 453 *p2 = m_q[m_read].param2; 454 // Move the read pointer ahead 455 ++m_read; 456 --m_size; 457 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) { 458 m_read = 0; 459 } 460 } else { 461 ret = false; 462 } 463 return ret; 464 } 465 466 // Retrieve the first mesg type in the queue 467 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 468 { 469 return m_q[m_read].id; 470 } 471 472 #ifdef _ANDROID_ 473 omx_vdec::ts_arr_list::ts_arr_list() 474 { 475 //initialize timestamps array 476 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); 477 } 478 omx_vdec::ts_arr_list::~ts_arr_list() 479 { 480 //free m_ts_arr_list? 481 } 482 483 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) 484 { 485 bool ret = true; 486 bool duplicate_ts = false; 487 int idx = 0; 488 489 //insert at the first available empty location 490 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 491 if (!m_ts_arr_list[idx].valid) { 492 //found invalid or empty entry, save timestamp 493 m_ts_arr_list[idx].valid = true; 494 m_ts_arr_list[idx].timestamp = ts; 495 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", 496 ts, idx); 497 break; 498 } 499 } 500 501 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) { 502 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); 503 ret = false; 504 } 505 return ret; 506 } 507 508 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) 509 { 510 bool ret = true; 511 int min_idx = -1; 512 OMX_TICKS min_ts = 0; 513 int idx = 0; 514 515 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 516 517 if (m_ts_arr_list[idx].valid) { 518 //found valid entry, save index 519 if (min_idx < 0) { 520 //first valid entry 521 min_ts = m_ts_arr_list[idx].timestamp; 522 min_idx = idx; 523 } else if (m_ts_arr_list[idx].timestamp < min_ts) { 524 min_ts = m_ts_arr_list[idx].timestamp; 525 min_idx = idx; 526 } 527 } 528 529 } 530 531 if (min_idx < 0) { 532 //no valid entries found 533 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); 534 ts = 0; 535 ret = false; 536 } else { 537 ts = m_ts_arr_list[min_idx].timestamp; 538 m_ts_arr_list[min_idx].valid = false; 539 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", 540 ts, min_idx); 541 } 542 543 return ret; 544 545 } 546 547 548 bool omx_vdec::ts_arr_list::reset_ts_list() 549 { 550 bool ret = true; 551 int idx = 0; 552 553 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); 554 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 555 m_ts_arr_list[idx].valid = false; 556 } 557 return ret; 558 } 559 #endif 560 561 // factory function executed by the core to create instances 562 void *get_omx_component_factory_fn(void) 563 { 564 return (new omx_vdec); 565 } 566 567 bool is_platform_tp10capture_supported() 568 { 569 char platform_name[PROPERTY_VALUE_MAX] = {0}; 570 property_get("ro.board.platform", platform_name, "0"); 571 if (!strncmp(platform_name, "msm8998", 7)) { 572 DEBUG_PRINT_HIGH("TP10 on capture port is supported"); 573 return true; 574 } 575 DEBUG_PRINT_HIGH("TP10 on capture port is not supported"); 576 return false; 577 } 578 579 /* ====================================================================== 580 FUNCTION 581 omx_vdec::omx_vdec 582 583 DESCRIPTION 584 Constructor 585 586 PARAMETERS 587 None 588 589 RETURN VALUE 590 None. 591 ========================================================================== */ 592 omx_vdec::omx_vdec(): m_error_propogated(false), 593 m_state(OMX_StateInvalid), 594 m_app_data(NULL), 595 m_inp_mem_ptr(NULL), 596 m_out_mem_ptr(NULL), 597 m_client_output_extradata_mem_ptr(NULL), 598 input_flush_progress (false), 599 output_flush_progress (false), 600 input_use_buffer (false), 601 output_use_buffer (false), 602 ouput_egl_buffers(false), 603 m_use_output_pmem(OMX_FALSE), 604 m_out_mem_region_smi(OMX_FALSE), 605 m_out_pvt_entry_pmem(OMX_FALSE), 606 pending_input_buffers(0), 607 pending_output_buffers(0), 608 m_out_bm_count(0), 609 m_inp_bm_count(0), 610 m_out_extradata_bm_count(0), 611 m_inp_bPopulated(OMX_FALSE), 612 m_out_bPopulated(OMX_FALSE), 613 m_flags(0), 614 m_inp_bEnabled(OMX_TRUE), 615 m_out_bEnabled(OMX_TRUE), 616 m_in_alloc_cnt(0), 617 m_platform_list(NULL), 618 m_platform_entry(NULL), 619 m_pmem_info(NULL), 620 h264_parser(NULL), 621 arbitrary_bytes (true), 622 psource_frame (NULL), 623 pdest_frame (NULL), 624 m_inp_heap_ptr (NULL), 625 m_phdr_pmem_ptr(NULL), 626 m_heap_inp_bm_count (0), 627 codec_type_parse ((codec_type)0), 628 first_frame_meta (true), 629 frame_count (0), 630 nal_count (0), 631 nal_length(0), 632 look_ahead_nal (false), 633 first_frame(0), 634 first_buffer(NULL), 635 first_frame_size (0), 636 m_device_file_ptr(NULL), 637 m_vc1_profile((vc1_profile_type)0), 638 h264_last_au_ts(LLONG_MAX), 639 h264_last_au_flags(0), 640 m_disp_hor_size(0), 641 m_disp_vert_size(0), 642 prev_ts(LLONG_MAX), 643 prev_ts_actual(LLONG_MAX), 644 rst_prev_ts(true), 645 frm_int(0), 646 m_fps_received(0), 647 m_fps_prev(0), 648 m_drc_enable(0), 649 in_reconfig(false), 650 m_display_id(NULL), 651 client_extradata(0), 652 m_reject_avc_1080p_mp (0), 653 #ifdef _ANDROID_ 654 m_enable_android_native_buffers(OMX_FALSE), 655 m_use_android_native_buffers(OMX_FALSE), 656 #endif 657 m_desc_buffer_ptr(NULL), 658 secure_mode(false), 659 allocate_native_handle(false), 660 m_other_extradata(NULL), 661 m_profile(0), 662 m_need_turbo(0), 663 client_set_fps(false), 664 stereo_output_mode(HAL_NO_3D), 665 m_last_rendered_TS(-1), 666 m_queued_codec_config_count(0), 667 current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL), 668 secure_scaling_to_non_secure_opb(false), 669 m_force_compressed_for_dpb(true), 670 m_is_display_session(false) 671 { 672 m_pipe_in = -1; 673 m_pipe_out = -1; 674 m_poll_efd = -1; 675 drv_ctx.video_driver_fd = -1; 676 drv_ctx.extradata_info.ion.fd_ion_data.fd = -1; 677 /* Assumption is that , to begin with , we have all the frames with decoder */ 678 DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8); 679 memset(&m_debug,0,sizeof(m_debug)); 680 #ifdef _ANDROID_ 681 char property_value[PROPERTY_VALUE_MAX] = {0}; 682 property_get("vendor.vidc.debug.level", property_value, "1"); 683 debug_level = strtoul(property_value, NULL, 16); 684 property_value[0] = '\0'; 685 686 DEBUG_PRINT_HIGH("In OMX vdec Constructor"); 687 688 property_get("vendor.vidc.dec.debug.perf", property_value, "0"); 689 perf_flag = atoi(property_value); 690 if (perf_flag) { 691 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); 692 dec_time.start(); 693 } 694 proc_frms = latency = 0; 695 prev_n_filled_len = 0; 696 property_value[0] = '\0'; 697 property_get("vendor.vidc.dec.debug.ts", property_value, "0"); 698 m_debug_timestamp = atoi(property_value); 699 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); 700 if (m_debug_timestamp) { 701 time_stamp_dts.set_timestamp_reorder_mode(true); 702 time_stamp_dts.enable_debug_print(true); 703 } 704 705 property_value[0] = '\0'; 706 property_get("vendor.vidc.dec.debug.concealedmb", property_value, "0"); 707 m_debug_concealedmb = atoi(property_value); 708 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); 709 710 property_value[0] = '\0'; 711 property_get("vendor.vidc.dec.profile.check", property_value, "0"); 712 m_reject_avc_1080p_mp = atoi(property_value); 713 DEBUG_PRINT_HIGH("vendor.vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp); 714 715 property_value[0] = '\0'; 716 property_get("vendor.vidc.dec.log.in", property_value, "0"); 717 m_debug.in_buffer_log = atoi(property_value); 718 719 property_value[0] = '\0'; 720 property_get("vendor.vidc.dec.log.out", property_value, "0"); 721 m_debug.out_buffer_log = atoi(property_value); 722 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 723 724 property_value[0] = '\0'; 725 property_get("vendor.vidc.dec.meta.log.out", property_value, "0"); 726 m_debug.out_meta_buffer_log = atoi(property_value); 727 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 728 729 property_value[0] = '\0'; 730 property_get("vendor.vidc.log.loc", property_value, ""); 731 if (*property_value) 732 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX); 733 734 property_value[0] = '\0'; 735 property_get("vendor.vidc.dec.120fps.enabled", property_value, "0"); 736 737 //if this feature is not enabled then reset this value -ve 738 if(atoi(property_value)) { 739 DEBUG_PRINT_LOW("feature 120 FPS decode enabled"); 740 m_last_rendered_TS = 0; 741 } 742 743 property_value[0] = '\0'; 744 property_get("vendor.vidc.dec.debug.dyn.disabled", property_value, "0"); 745 m_disable_dynamic_buf_mode = atoi(property_value); 746 DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode); 747 748 property_value[0] = '\0'; 749 property_get("vendor.vidc.dec.drc.enable", property_value, "0"); 750 if (atoi(property_value)) { 751 m_drc_enable = true; 752 DEBUG_PRINT_HIGH("DRC enabled"); 753 } 754 755 #ifdef _UBWC_ 756 property_value[0] = '\0'; 757 property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0"); 758 m_disable_ubwc_mode = atoi(property_value); 759 DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled"); 760 #else 761 m_disable_ubwc_mode = true; 762 #endif 763 #endif 764 memset(&m_cmp,0,sizeof(m_cmp)); 765 memset(&m_cb,0,sizeof(m_cb)); 766 memset (&drv_ctx,0,sizeof(drv_ctx)); 767 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 768 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 769 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 770 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize)); 771 memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams)); 772 memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams)); 773 memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams)); 774 memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams)); 775 memset(&m_color_mdata, 0, sizeof(ColorMetaData)); 776 m_demux_entries = 0; 777 msg_thread_id = 0; 778 async_thread_id = 0; 779 msg_thread_created = false; 780 async_thread_created = false; 781 async_thread_force_stop = false; 782 message_thread_stop = false; 783 #ifdef _ANDROID_ICS_ 784 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 785 #endif 786 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 787 788 /* invalidate m_frame_pack_arrangement */ 789 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 790 m_frame_pack_arrangement.cancel_flag = 1; 791 792 drv_ctx.timestamp_adjust = false; 793 m_vendor_config.pData = NULL; 794 pthread_mutex_init(&m_lock, NULL); 795 pthread_mutex_init(&c_lock, NULL); 796 pthread_mutex_init(&buf_lock, NULL); 797 sem_init(&m_cmd_lock,0,0); 798 sem_init(&m_safe_flush, 0, 0); 799 streaming[CAPTURE_PORT] = 800 streaming[OUTPUT_PORT] = false; 801 #ifdef _ANDROID_ 802 char extradata_value[PROPERTY_VALUE_MAX] = {0}; 803 property_get("vendor.vidc.dec.debug.extradata", extradata_value, "0"); 804 m_debug_extradata = atoi(extradata_value); 805 DEBUG_PRINT_HIGH("vendor.vidc.dec.debug.extradata value is %d",m_debug_extradata); 806 #endif 807 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; 808 client_buffers.set_vdec_client(this); 809 dynamic_buf_mode = false; 810 out_dynamic_list = NULL; 811 is_down_scalar_enabled = false; 812 m_enable_downscalar = 0; 813 m_downscalar_width = 0; 814 m_downscalar_height = 0; 815 m_force_down_scalar = 0; 816 m_reconfig_height = 0; 817 m_reconfig_width = 0; 818 m_smoothstreaming_mode = false; 819 m_smoothstreaming_width = 0; 820 m_smoothstreaming_height = 0; 821 m_decode_order_mode = false; 822 is_q6_platform = false; 823 m_perf_control.send_hint_to_mpctl(true); 824 m_input_pass_buffer_fd = false; 825 memset(&m_extradata_info, 0, sizeof(m_extradata_info)); 826 m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX; 827 m_client_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 828 m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 829 m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 830 m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 831 832 m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 833 m_internal_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 834 m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 835 m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 836 m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 837 m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams); 838 839 m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX; 840 m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 841 m_change_client_hdr_info = false; 842 pthread_mutex_init(&m_hdr_info_client_lock, NULL); 843 844 char dither_value[PROPERTY_VALUE_MAX] = {0}; 845 property_get("vendor.vidc.dec.dither", dither_value, "0"); 846 if ((atoi(dither_value) > DITHER_ALL_COLORSPACE) || 847 (atoi(dither_value) < DITHER_DISABLE)) { 848 m_dither_config = DITHER_ALL_COLORSPACE; 849 } else { 850 m_dither_config = is_platform_tp10capture_supported() ? (dither_type)atoi(dither_value) : DITHER_ALL_COLORSPACE; 851 } 852 853 DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config); 854 m_color_space = EXCEPT_BT2020; 855 } 856 857 static const int event_type[] = { 858 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 859 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, 860 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, 861 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT, 862 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE, 863 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER, 864 V4L2_EVENT_MSM_VIDC_SYS_ERROR, 865 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD, 866 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED 867 }; 868 869 static OMX_ERRORTYPE subscribe_to_events(int fd) 870 { 871 OMX_ERRORTYPE eRet = OMX_ErrorNone; 872 struct v4l2_event_subscription sub; 873 int array_sz = sizeof(event_type)/sizeof(int); 874 int i,rc; 875 if (fd < 0) { 876 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 877 return OMX_ErrorBadParameter; 878 } 879 880 for (i = 0; i < array_sz; ++i) { 881 memset(&sub, 0, sizeof(sub)); 882 sub.type = event_type[i]; 883 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 884 if (rc) { 885 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 886 break; 887 } 888 } 889 if (i < array_sz) { 890 for (--i; i >=0 ; i--) { 891 memset(&sub, 0, sizeof(sub)); 892 sub.type = event_type[i]; 893 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 894 if (rc) 895 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 896 } 897 eRet = OMX_ErrorNotImplemented; 898 } 899 return eRet; 900 } 901 902 903 static OMX_ERRORTYPE unsubscribe_to_events(int fd) 904 { 905 OMX_ERRORTYPE eRet = OMX_ErrorNone; 906 struct v4l2_event_subscription sub; 907 int array_sz = sizeof(event_type)/sizeof(int); 908 int i,rc; 909 if (fd < 0) { 910 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 911 return OMX_ErrorBadParameter; 912 } 913 914 for (i = 0; i < array_sz; ++i) { 915 memset(&sub, 0, sizeof(sub)); 916 sub.type = event_type[i]; 917 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 918 if (rc) { 919 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 920 break; 921 } 922 } 923 return eRet; 924 } 925 926 /* ====================================================================== 927 FUNCTION 928 omx_vdec::~omx_vdec 929 930 DESCRIPTION 931 Destructor 932 933 PARAMETERS 934 None 935 936 RETURN VALUE 937 None. 938 ========================================================================== */ 939 omx_vdec::~omx_vdec() 940 { 941 m_pmem_info = NULL; 942 DEBUG_PRINT_HIGH("In OMX vdec Destructor"); 943 if (msg_thread_created) { 944 DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread"); 945 message_thread_stop = true; 946 post_message(this, OMX_COMPONENT_CLOSE_MSG); 947 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); 948 pthread_join(msg_thread_id,NULL); 949 } 950 close(m_pipe_in); 951 close(m_pipe_out); 952 m_pipe_in = -1; 953 m_pipe_out = -1; 954 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); 955 if(eventfd_write(m_poll_efd, 1)) { 956 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno); 957 async_thread_force_stop = true; 958 } 959 960 if (async_thread_created) 961 pthread_join(async_thread_id,NULL); 962 unsubscribe_to_events(drv_ctx.video_driver_fd); 963 close(m_poll_efd); 964 close(drv_ctx.video_driver_fd); 965 pthread_mutex_destroy(&m_lock); 966 pthread_mutex_destroy(&c_lock); 967 pthread_mutex_destroy(&buf_lock); 968 sem_destroy(&m_cmd_lock); 969 pthread_mutex_destroy(&m_hdr_info_client_lock); 970 if (perf_flag) { 971 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); 972 dec_time.end(); 973 } 974 DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd); 975 m_perf_control.send_hint_to_mpctl(false); 976 } 977 978 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) 979 { 980 struct v4l2_requestbuffers bufreq; 981 int rc = 0; 982 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 983 bufreq.memory = V4L2_MEMORY_USERPTR; 984 bufreq.count = 0; 985 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 986 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 987 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) { 988 bufreq.memory = V4L2_MEMORY_USERPTR; 989 bufreq.count = 0; 990 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 991 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 992 } 993 return rc; 994 } 995 996 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format) 997 { 998 int rc = 0; 999 struct v4l2_ext_control ctrl[2]; 1000 struct v4l2_ext_controls controls; 1001 1002 DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s", 1003 is_split_mode ? "split" : "combined", 1004 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc": 1005 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc": 1006 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb": 1007 "unknown", 1008 capture_capability == V4L2_PIX_FMT_NV12 ? "nv12": 1009 capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc": 1010 capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC ? "nv12_10bit_ubwc": 1011 "unknown"); 1012 1013 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE; 1014 if (is_split_mode) { 1015 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY; 1016 } else { 1017 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY; 1018 } 1019 1020 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT; 1021 ctrl[1].value = dpb_color_format; 1022 1023 controls.count = 2; 1024 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 1025 controls.controls = ctrl; 1026 1027 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls); 1028 if (rc) { 1029 DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc); 1030 return OMX_ErrorUnsupportedSetting; 1031 } 1032 return OMX_ErrorNone; 1033 } 1034 1035 1036 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool split_opb_dpb_with_same_color_fmt) 1037 { 1038 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1039 struct v4l2_format fmt; 1040 int rc = 0; 1041 bool cpu_access = (capture_capability != V4L2_PIX_FMT_NV12_UBWC) && 1042 capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC; 1043 bool tp10_enable = !drv_ctx.idr_only_decoding && 1044 !client_buffers.is_color_conversion_enabled() && 1045 dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10; 1046 bool dither_enable = true; 1047 1048 switch (m_dither_config) { 1049 case DITHER_DISABLE: 1050 dither_enable = false; 1051 break; 1052 case DITHER_COLORSPACE_EXCEPTBT2020: 1053 dither_enable = (m_color_space == EXCEPT_BT2020); 1054 break; 1055 case DITHER_ALL_COLORSPACE: 1056 dither_enable = true; 1057 break; 1058 default: 1059 DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config); 1060 } 1061 1062 if (tp10_enable && !dither_enable) { 1063 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC; 1064 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC; 1065 cpu_access = false; 1066 1067 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1068 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1069 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1070 if (rc) { 1071 DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__); 1072 return OMX_ErrorUnsupportedSetting; 1073 } 1074 fmt.fmt.pix_mp.pixelformat = capture_capability; 1075 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1076 if (rc) { 1077 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__); 1078 return OMX_ErrorUnsupportedSetting; 1079 } 1080 } 1081 1082 1083 if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) && 1084 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 1085 DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split"); 1086 return eRet; 1087 } 1088 1089 1090 if (cpu_access) { 1091 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 1092 /* Disabled split mode for VP9. In split mode the DPB buffers are part of the internal 1093 * scratch buffers and the driver does not does the reference buffer management for 1094 * scratch buffers. In case of VP9 with spatial scalability, when a sequence changed 1095 * event is received with the new resolution, and when a flush is sent by the driver, it 1096 * releases all the references of internal scratch buffers. However as per the VP9 1097 * spatial scalability, even after the flush, the buffers which have not yet received 1098 * release reference event should not be unmapped and freed. Currently in driver, 1099 * reference buffer management of the internal scratch buffer is not implemented 1100 * and hence the DPB buffers get unmapped. For other codecs it does not matter 1101 * as with the new SPS/PPS, the DPB is flushed. 1102 */ 1103 bool is_not_vp9 = eCompressionFormat != OMX_VIDEO_CodingVP9; 1104 bool eligible_for_split_dpb_ubwc = 1105 m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE && //@ Due to Venus limitation for Interlaced, Split mode enabled only for Progressive. 1106 is_not_vp9 && //@ Split mode disabled for VP9. 1107 !drv_ctx.idr_only_decoding && //@ Split mode disabled for Thumbnail usecase. 1108 !m_disable_split_mode; //@ Set prop to disable split mode 1109 1110 //Since opb is linear, dpb should also be linear. 1111 if (split_opb_dpb_with_same_color_fmt) { 1112 eligible_for_split_dpb_ubwc = false; 1113 } 1114 1115 if (eligible_for_split_dpb_ubwc) { 1116 //split DPB-OPB 1117 //DPB -> UBWC , OPB -> Linear 1118 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1119 } else if (split_opb_dpb_with_same_color_fmt) { 1120 //DPB -> Linear, OPB -> Linear 1121 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1122 } else { 1123 //DPB-OPB combined linear 1124 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1125 } 1126 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1127 //split DPB-OPB 1128 //DPB -> UBWC, OPB -> Linear 1129 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1130 } 1131 } else { //no cpu access 1132 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 1133 if (split_opb_dpb_with_same_color_fmt) { 1134 //split DPB-OPB 1135 //DPB -> UBWC, OPB -> UBWC 1136 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1137 } else { 1138 //DPB-OPB combined UBWC 1139 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1140 } 1141 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1142 if (dither_enable) { 1143 //split DPB-OPB 1144 //DPB -> TP10UBWC, OPB -> UBWC 1145 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1146 } else { 1147 //combined DPB-OPB 1148 //DPB -> TP10UBWC, OPB -> TP10UBWC 1149 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1150 } 1151 } 1152 } 1153 if (eRet) { 1154 DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet); 1155 } 1156 1157 1158 1159 return eRet; 1160 } 1161 1162 int omx_vdec::enable_downscalar() 1163 { 1164 int rc = 0; 1165 struct v4l2_control control; 1166 struct v4l2_format fmt; 1167 1168 if (is_down_scalar_enabled) { 1169 DEBUG_PRINT_LOW("%s: already enabled", __func__); 1170 return 0; 1171 } 1172 1173 DEBUG_PRINT_LOW("omx_vdec::enable_downscalar"); 1174 rc = decide_dpb_buffer_mode(true); 1175 if (rc) { 1176 DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__); 1177 return rc; 1178 } 1179 is_down_scalar_enabled = true; 1180 1181 memset(&control, 0x0, sizeof(struct v4l2_control)); 1182 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO; 1183 control.value = 1; 1184 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 1185 if (rc) { 1186 DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__); 1187 return rc; 1188 } 1189 1190 return 0; 1191 } 1192 1193 int omx_vdec::disable_downscalar() 1194 { 1195 int rc = 0; 1196 struct v4l2_control control; 1197 1198 if (!is_down_scalar_enabled) { 1199 DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled"); 1200 return 0; 1201 } 1202 1203 rc = decide_dpb_buffer_mode(false); 1204 if (rc < 0) { 1205 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__); 1206 return rc; 1207 } 1208 is_down_scalar_enabled = false; 1209 1210 return rc; 1211 } 1212 1213 int omx_vdec::decide_downscalar() 1214 { 1215 int rc = 0; 1216 struct v4l2_format fmt; 1217 enum color_fmts color_format; 1218 OMX_U32 width, height; 1219 OMX_BOOL isPortraitVideo = OMX_FALSE; 1220 1221 if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) { 1222 rc = disable_downscalar(); 1223 if (rc) { 1224 DEBUG_PRINT_ERROR("Disable downscalar failed!"); 1225 return rc; 1226 } 1227 return 0; 1228 } 1229 1230 if (!m_enable_downscalar) { 1231 DEBUG_PRINT_LOW("%s: downscalar not supported", __func__); 1232 return 0; 1233 } 1234 1235 #ifdef _QUERY_DISP_RES_ 1236 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1237 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1238 fmt.fmt.pix_mp.pixelformat = capture_capability; 1239 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1240 if (rc < 0) { 1241 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 1242 return rc; 1243 } 1244 isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE; 1245 if (!m_downscalar_width || !m_downscalar_height) { 1246 qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {}; 1247 int prim_config, ext_config, virt_config; 1248 1249 prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY); 1250 dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY); 1251 DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d dpa.yres=%d dpa.xdpi = %f dpa.ydpi = %f ", 1252 __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi); 1253 1254 ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL); 1255 dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL); 1256 DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d dsa.yres = %d dsa.xdpi = %f dsa.ydpi = %f ", 1257 __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi); 1258 1259 virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL); 1260 dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL); 1261 DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d dva.yres = %d dva.xdpi = %f dva.ydpi = %f ", 1262 __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi); 1263 1264 /* Below logic takes care of following conditions: 1265 * 1. Choose display resolution as maximum resolution of all the connected 1266 * displays (secondary, primary, virtual), so that we do not downscale 1267 * unnecessarily which might be supported on one of the display losing quality. 1268 * 2. Displays connected might be in landscape or portrait mode, so the xres might 1269 * be smaller or greater than the yres. So we first take the max of the two 1270 * in width and min of two in height and then rotate it if below point is true. 1271 * 3. Video might also be in portrait mode, so invert the downscalar width and 1272 * height for such cases. 1273 */ 1274 if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) { 1275 m_downscalar_width = MAX(dsa.xres, dsa.yres); 1276 m_downscalar_height = MIN(dsa.xres, dsa.yres); 1277 } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) { 1278 m_downscalar_width = MAX(dva.xres, dva.yres); 1279 m_downscalar_height = MIN(dva.xres, dva.yres); 1280 1281 } else { 1282 m_downscalar_width = MAX(dpa.xres, dpa.yres); 1283 m_downscalar_height = MIN(dpa.xres, dpa.yres); 1284 } 1285 if (isPortraitVideo) { 1286 // Swap width and height 1287 m_downscalar_width = m_downscalar_width ^ m_downscalar_height; 1288 m_downscalar_height = m_downscalar_width ^ m_downscalar_height; 1289 m_downscalar_width = m_downscalar_width ^ m_downscalar_height; 1290 } 1291 } 1292 m_downscalar_width = ALIGN(m_downscalar_width, 128); 1293 m_downscalar_height = ALIGN(m_downscalar_height, 32); 1294 #endif 1295 1296 if (!m_downscalar_width || !m_downscalar_height) { 1297 DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__); 1298 return 0; 1299 } 1300 1301 if (m_force_down_scalar) { 1302 DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar); 1303 return 0; 1304 } 1305 1306 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1307 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1308 fmt.fmt.pix_mp.pixelformat = capture_capability; 1309 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1310 if (rc < 0) { 1311 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 1312 return rc; 1313 } 1314 1315 height = fmt.fmt.pix_mp.height; 1316 width = fmt.fmt.pix_mp.width; 1317 1318 DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__, 1319 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session); 1320 1321 if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) && 1322 m_is_display_session) { 1323 rc = enable_downscalar(); 1324 if (rc < 0) { 1325 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 1326 return rc; 1327 } 1328 1329 width = m_downscalar_width > fmt.fmt.pix_mp.width ? 1330 fmt.fmt.pix_mp.width : m_downscalar_width; 1331 height = m_downscalar_height > fmt.fmt.pix_mp.height ? 1332 fmt.fmt.pix_mp.height : m_downscalar_height; 1333 switch (capture_capability) { 1334 case V4L2_PIX_FMT_NV12: 1335 color_format = COLOR_FMT_NV12; 1336 break; 1337 case V4L2_PIX_FMT_NV12_UBWC: 1338 color_format = COLOR_FMT_NV12_UBWC; 1339 break; 1340 case V4L2_PIX_FMT_NV12_TP10_UBWC: 1341 color_format = COLOR_FMT_NV12_BPP10_UBWC; 1342 break; 1343 default: 1344 DEBUG_PRINT_ERROR("Color format not recognized\n"); 1345 rc = OMX_ErrorUndefined; 1346 return rc; 1347 } 1348 } else { 1349 1350 rc = disable_downscalar(); 1351 if (rc < 0) { 1352 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 1353 return rc; 1354 } 1355 } 1356 1357 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1358 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1359 fmt.fmt.pix_mp.height = height; 1360 fmt.fmt.pix_mp.width = width; 1361 fmt.fmt.pix_mp.pixelformat = capture_capability; 1362 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1363 if (rc) { 1364 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__); 1365 return rc; 1366 } 1367 1368 rc = get_buffer_req(&drv_ctx.op_buf); 1369 if (rc) { 1370 DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__); 1371 return rc; 1372 } 1373 1374 return rc; 1375 } 1376 1377 /* ====================================================================== 1378 FUNCTION 1379 omx_vdec::OMXCntrlProcessMsgCb 1380 1381 DESCRIPTION 1382 IL Client callbacks are generated through this routine. The decoder 1383 provides the thread context for this routine. 1384 1385 PARAMETERS 1386 ctxt -- Context information related to the self. 1387 id -- Event identifier. This could be any of the following: 1388 1. Command completion event 1389 2. Buffer done callback event 1390 3. Frame done callback event 1391 1392 RETURN VALUE 1393 None. 1394 1395 ========================================================================== */ 1396 void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 1397 { 1398 unsigned long p1; // Parameter - 1 1399 unsigned long p2; // Parameter - 2 1400 unsigned long ident; 1401 unsigned qsize=0; // qsize 1402 omx_vdec *pThis = (omx_vdec *) ctxt; 1403 1404 if (!pThis) { 1405 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out", 1406 __func__); 1407 return; 1408 } 1409 1410 // Protect the shared queue data structure 1411 do { 1412 /*Read the message id's from the queue*/ 1413 pthread_mutex_lock(&pThis->m_lock); 1414 qsize = pThis->m_cmd_q.m_size; 1415 if (qsize) { 1416 pThis->m_cmd_q.pop_entry(&p1, &p2, &ident); 1417 } 1418 1419 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1420 qsize = pThis->m_ftb_q.m_size; 1421 if (qsize) { 1422 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident); 1423 } 1424 } 1425 1426 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1427 qsize = pThis->m_etb_q.m_size; 1428 if (qsize) { 1429 pThis->m_etb_q.pop_entry(&p1, &p2, &ident); 1430 } 1431 } 1432 pthread_mutex_unlock(&pThis->m_lock); 1433 1434 /*process message if we have one*/ 1435 if (qsize > 0) { 1436 id = ident; 1437 switch (id) { 1438 case OMX_COMPONENT_GENERATE_EVENT: 1439 if (pThis->m_cb.EventHandler) { 1440 switch (p1) { 1441 case OMX_CommandStateSet: 1442 pThis->m_state = (OMX_STATETYPE) p2; 1443 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", 1444 pThis->m_state); 1445 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1446 OMX_EventCmdComplete, p1, p2, NULL); 1447 break; 1448 1449 case OMX_EventError: 1450 if (p2 == OMX_StateInvalid) { 1451 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid"); 1452 pThis->m_state = (OMX_STATETYPE) p2; 1453 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1454 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 1455 } else if (p2 == (unsigned long)OMX_ErrorHardware) { 1456 pThis->omx_report_error(); 1457 } else { 1458 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1459 OMX_EventError, p2, (OMX_U32)NULL, NULL ); 1460 } 1461 break; 1462 1463 case OMX_CommandPortDisable: 1464 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2); 1465 if (BITMASK_PRESENT(&pThis->m_flags, 1466 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1467 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1468 break; 1469 } 1470 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) { 1471 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1472 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 1473 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) 1474 DEBUG_PRINT_HIGH("Failed to release output buffers"); 1475 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); 1476 if (eRet != OMX_ErrorNone) { 1477 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); 1478 pThis->omx_report_error(); 1479 break; 1480 } 1481 } 1482 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1483 OMX_EventCmdComplete, p1, p2, NULL ); 1484 break; 1485 case OMX_CommandPortEnable: 1486 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2); 1487 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 1488 OMX_EventCmdComplete, p1, p2, NULL ); 1489 pThis->in_reconfig = false; 1490 break; 1491 1492 default: 1493 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1494 OMX_EventCmdComplete, p1, p2, NULL ); 1495 break; 1496 1497 } 1498 } else { 1499 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1500 } 1501 break; 1502 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 1503 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 1504 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1505 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure"); 1506 pThis->omx_report_error (); 1507 } 1508 break; 1509 case OMX_COMPONENT_GENERATE_ETB: { 1510 OMX_ERRORTYPE iret; 1511 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2); 1512 if (iret == OMX_ErrorInsufficientResources) { 1513 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload"); 1514 pThis->omx_report_hw_overload (); 1515 } else if (iret != OMX_ErrorNone) { 1516 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); 1517 pThis->omx_report_error (); 1518 } 1519 } 1520 break; 1521 1522 case OMX_COMPONENT_GENERATE_FTB: 1523 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\ 1524 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1525 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure"); 1526 pThis->omx_report_error (); 1527 } 1528 break; 1529 1530 case OMX_COMPONENT_GENERATE_COMMAND: 1531 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 1532 (OMX_U32)p2,(OMX_PTR)NULL); 1533 break; 1534 1535 case OMX_COMPONENT_GENERATE_EBD: 1536 1537 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) { 1538 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure"); 1539 pThis->omx_report_error (); 1540 } else { 1541 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) { 1542 pThis->time_stamp_dts.remove_time_stamp( 1543 ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp, 1544 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1545 ?true:false); 1546 } 1547 1548 if ( pThis->empty_buffer_done(&pThis->m_cmp, 1549 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) { 1550 DEBUG_PRINT_ERROR("empty_buffer_done failure"); 1551 pThis->omx_report_error (); 1552 } 1553 } 1554 break; 1555 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: { 1556 int64_t *timestamp = (int64_t *)(intptr_t)p1; 1557 if (p1) { 1558 pThis->time_stamp_dts.remove_time_stamp(*timestamp, 1559 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1560 ?true:false); 1561 free(timestamp); 1562 } 1563 } 1564 break; 1565 case OMX_COMPONENT_GENERATE_FBD: 1566 if (p2 != VDEC_S_SUCCESS) { 1567 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure"); 1568 pThis->omx_report_error (); 1569 } else if ( pThis->fill_buffer_done(&pThis->m_cmp, 1570 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) { 1571 DEBUG_PRINT_ERROR("fill_buffer_done failure"); 1572 pThis->omx_report_error (); 1573 } 1574 break; 1575 1576 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 1577 DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); 1578 if (!pThis->input_flush_progress) { 1579 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1580 } else { 1581 pThis->execute_input_flush(); 1582 if (pThis->m_cb.EventHandler) { 1583 if (p2 != VDEC_S_SUCCESS) { 1584 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 1585 pThis->omx_report_error (); 1586 } else { 1587 /*Check if we need generate event for Flush done*/ 1588 pThis->notify_flush_done(ctxt); 1589 1590 if (BITMASK_PRESENT(&pThis->m_flags, 1591 OMX_COMPONENT_IDLE_PENDING)) { 1592 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { 1593 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port"); 1594 pThis->omx_report_error (); 1595 } else { 1596 pThis->streaming[OUTPUT_PORT] = false; 1597 } 1598 if (!pThis->output_flush_progress) { 1599 DEBUG_PRINT_LOW("Input flush done hence issue stop"); 1600 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1601 OMX_COMPONENT_GENERATE_STOP_DONE); 1602 } 1603 } 1604 } 1605 } else { 1606 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1607 } 1608 } 1609 break; 1610 1611 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 1612 DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); 1613 if (!pThis->output_flush_progress) { 1614 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1615 } else { 1616 pThis->execute_output_flush(); 1617 if (pThis->m_cb.EventHandler) { 1618 if (p2 != VDEC_S_SUCCESS) { 1619 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 1620 pThis->omx_report_error (); 1621 } else { 1622 /*Check if we need generate event for Flush done*/ 1623 pThis->notify_flush_done(ctxt); 1624 1625 if (BITMASK_PRESENT(&pThis->m_flags, 1626 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1627 DEBUG_PRINT_LOW("Internal flush complete"); 1628 BITMASK_CLEAR (&pThis->m_flags, 1629 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 1630 if (BITMASK_PRESENT(&pThis->m_flags, 1631 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) { 1632 pThis->post_event(OMX_CommandPortDisable, 1633 OMX_CORE_OUTPUT_PORT_INDEX, 1634 OMX_COMPONENT_GENERATE_EVENT); 1635 BITMASK_CLEAR (&pThis->m_flags, 1636 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1637 BITMASK_CLEAR (&pThis->m_flags, 1638 OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1639 1640 } 1641 } 1642 1643 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) { 1644 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 1645 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port"); 1646 pThis->omx_report_error (); 1647 break; 1648 } 1649 pThis->streaming[CAPTURE_PORT] = false; 1650 if (!pThis->input_flush_progress) { 1651 DEBUG_PRINT_LOW("Output flush done hence issue stop"); 1652 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1653 OMX_COMPONENT_GENERATE_STOP_DONE); 1654 } 1655 } 1656 } 1657 } else { 1658 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1659 } 1660 } 1661 break; 1662 1663 case OMX_COMPONENT_GENERATE_START_DONE: 1664 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); 1665 1666 if (pThis->m_cb.EventHandler) { 1667 if (p2 != VDEC_S_SUCCESS) { 1668 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure"); 1669 pThis->omx_report_error (); 1670 } else { 1671 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); 1672 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1673 DEBUG_PRINT_LOW("Move to executing"); 1674 // Send the callback now 1675 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1676 pThis->m_state = OMX_StateExecuting; 1677 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1678 OMX_EventCmdComplete,OMX_CommandStateSet, 1679 OMX_StateExecuting, NULL); 1680 } else if (BITMASK_PRESENT(&pThis->m_flags, 1681 OMX_COMPONENT_PAUSE_PENDING)) { 1682 if (/*ioctl (pThis->drv_ctx.video_driver_fd, 1683 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) { 1684 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed"); 1685 pThis->omx_report_error (); 1686 } 1687 } 1688 } 1689 } else { 1690 DEBUG_PRINT_LOW("Event Handler callback is NULL"); 1691 } 1692 break; 1693 1694 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 1695 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 1696 if (pThis->m_cb.EventHandler) { 1697 if (p2 != VDEC_S_SUCCESS) { 1698 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 1699 pThis->omx_report_error (); 1700 } else { 1701 pThis->complete_pending_buffer_done_cbs(); 1702 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) { 1703 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 1704 //Send the callback now 1705 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 1706 pThis->m_state = OMX_StatePause; 1707 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1708 OMX_EventCmdComplete,OMX_CommandStateSet, 1709 OMX_StatePause, NULL); 1710 } 1711 } 1712 } else { 1713 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1714 } 1715 1716 break; 1717 1718 case OMX_COMPONENT_GENERATE_RESUME_DONE: 1719 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 1720 if (pThis->m_cb.EventHandler) { 1721 if (p2 != VDEC_S_SUCCESS) { 1722 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 1723 pThis->omx_report_error (); 1724 } else { 1725 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1726 DEBUG_PRINT_LOW("Moving the decoder to execute state"); 1727 // Send the callback now 1728 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1729 pThis->m_state = OMX_StateExecuting; 1730 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1731 OMX_EventCmdComplete,OMX_CommandStateSet, 1732 OMX_StateExecuting,NULL); 1733 } 1734 } 1735 } else { 1736 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1737 } 1738 1739 break; 1740 1741 case OMX_COMPONENT_GENERATE_STOP_DONE: 1742 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 1743 if (pThis->m_cb.EventHandler) { 1744 if (p2 != VDEC_S_SUCCESS) { 1745 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 1746 pThis->omx_report_error (); 1747 } else { 1748 pThis->complete_pending_buffer_done_cbs(); 1749 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) { 1750 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); 1751 // Send the callback now 1752 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 1753 pThis->m_state = OMX_StateIdle; 1754 DEBUG_PRINT_LOW("Move to Idle State"); 1755 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 1756 OMX_EventCmdComplete,OMX_CommandStateSet, 1757 OMX_StateIdle,NULL); 1758 } 1759 } 1760 } else { 1761 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1762 } 1763 1764 break; 1765 1766 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 1767 if (p2 == OMX_IndexParamPortDefinition) { 1768 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition"); 1769 pThis->in_reconfig = true; 1770 pThis->m_need_turbo &= ~TURBO_MODE_HIGH_FPS; 1771 } else if (p2 == OMX_IndexConfigCommonOutputCrop) { 1772 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop"); 1773 1774 /* Check if resolution is changed in smooth streaming mode */ 1775 if (pThis->m_smoothstreaming_mode && 1776 (pThis->framesize.nWidth != 1777 pThis->drv_ctx.video_resolution.frame_width) || 1778 (pThis->framesize.nHeight != 1779 pThis->drv_ctx.video_resolution.frame_height)) { 1780 1781 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d", 1782 pThis->framesize.nWidth, 1783 pThis->framesize.nHeight, 1784 pThis->drv_ctx.video_resolution.frame_width, 1785 pThis->drv_ctx.video_resolution.frame_height); 1786 1787 /* Update new resolution */ 1788 pThis->framesize.nWidth = 1789 pThis->drv_ctx.video_resolution.frame_width; 1790 pThis->framesize.nHeight = 1791 pThis->drv_ctx.video_resolution.frame_height; 1792 1793 /* Update C2D with new resolution */ 1794 if (!pThis->client_buffers.update_buffer_req()) { 1795 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed"); 1796 } 1797 } 1798 1799 /* Update new crop information */ 1800 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left; 1801 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top; 1802 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right; 1803 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom; 1804 1805 /* Validate the new crop information */ 1806 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth > 1807 pThis->drv_ctx.video_resolution.frame_width) { 1808 1809 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]", 1810 pThis->rectangle.nLeft, pThis->rectangle.nWidth, 1811 pThis->drv_ctx.video_resolution.frame_width); 1812 pThis->rectangle.nLeft = 0; 1813 1814 if (pThis->rectangle.nWidth > 1815 pThis->drv_ctx.video_resolution.frame_width) { 1816 1817 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]", 1818 pThis->rectangle.nWidth, 1819 pThis->drv_ctx.video_resolution.frame_width); 1820 pThis->rectangle.nWidth = 1821 pThis->drv_ctx.video_resolution.frame_width; 1822 } 1823 } 1824 if (pThis->rectangle.nTop + pThis->rectangle.nHeight > 1825 pThis->drv_ctx.video_resolution.frame_height) { 1826 1827 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]", 1828 pThis->rectangle.nTop, pThis->rectangle.nHeight, 1829 pThis->drv_ctx.video_resolution.frame_height); 1830 pThis->rectangle.nTop = 0; 1831 1832 if (pThis->rectangle.nHeight > 1833 pThis->drv_ctx.video_resolution.frame_height) { 1834 1835 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]", 1836 pThis->rectangle.nHeight, 1837 pThis->drv_ctx.video_resolution.frame_height); 1838 pThis->rectangle.nHeight = 1839 pThis->drv_ctx.video_resolution.frame_height; 1840 } 1841 } 1842 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u", 1843 pThis->rectangle.nLeft, pThis->rectangle.nTop, 1844 pThis->rectangle.nWidth, pThis->rectangle.nHeight); 1845 } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) { 1846 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects"); 1847 } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) { 1848 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo"); 1849 } else { 1850 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2); 1851 break; 1852 } 1853 if (pThis->m_debug.outfile) { 1854 fclose(pThis->m_debug.outfile); 1855 pThis->m_debug.outfile = NULL; 1856 } 1857 if (pThis->m_debug.out_ymeta_file) { 1858 fclose(pThis->m_debug.out_ymeta_file); 1859 pThis->m_debug.out_ymeta_file = NULL; 1860 } 1861 if (pThis->m_debug.out_uvmeta_file) { 1862 fclose(pThis->m_debug.out_uvmeta_file); 1863 pThis->m_debug.out_uvmeta_file = NULL; 1864 } 1865 1866 if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) { 1867 pThis->prefetchNewBuffers(); 1868 } 1869 1870 if (pThis->m_cb.EventHandler) { 1871 uint32_t frame_data[7]; 1872 frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ? 1873 pThis->m_reconfig_height : pThis->rectangle.nHeight; 1874 frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ? 1875 pThis->m_reconfig_width : pThis->rectangle.nWidth; 1876 1877 frame_data[2] = (p2 == OMX_IndexParamPortDefinition) ? 1878 frame_data[0] : pThis->drv_ctx.video_resolution.frame_height; 1879 1880 frame_data[3] = (p2 == OMX_IndexParamPortDefinition) ? 1881 frame_data[1] : pThis->drv_ctx.video_resolution.frame_width; 1882 frame_data[4] = pThis->dpb_bit_depth; 1883 frame_data[5] = pThis->m_color_space; 1884 frame_data[6] = pThis->m_dither_config; 1885 1886 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1887 OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data ); 1888 } else { 1889 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1890 } 1891 break; 1892 1893 case OMX_COMPONENT_GENERATE_EOS_DONE: 1894 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); 1895 if (pThis->m_cb.EventHandler) { 1896 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, 1897 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); 1898 } else { 1899 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1900 } 1901 pThis->prev_ts = LLONG_MAX; 1902 pThis->rst_prev_ts = true; 1903 break; 1904 1905 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 1906 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 1907 pThis->omx_report_error(); 1908 break; 1909 1910 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: 1911 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING"); 1912 pThis->omx_report_unsupported_setting(); 1913 break; 1914 1915 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD: 1916 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD"); 1917 pThis->omx_report_hw_overload(); 1918 break; 1919 1920 default: 1921 break; 1922 } 1923 } 1924 pthread_mutex_lock(&pThis->m_lock); 1925 qsize = pThis->m_cmd_q.m_size; 1926 if (pThis->m_state != OMX_StatePause) 1927 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); 1928 pthread_mutex_unlock(&pThis->m_lock); 1929 } while (qsize>0); 1930 1931 } 1932 1933 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) 1934 { 1935 int format_changed = 0; 1936 if ((height != (int)drv_ctx.video_resolution.frame_height) || 1937 (width != (int)drv_ctx.video_resolution.frame_width)) { 1938 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)", 1939 width, drv_ctx.video_resolution.frame_width, 1940 height,drv_ctx.video_resolution.frame_height); 1941 format_changed = 1; 1942 } 1943 drv_ctx.video_resolution.frame_height = height; 1944 drv_ctx.video_resolution.frame_width = width; 1945 drv_ctx.video_resolution.scan_lines = scan_lines; 1946 drv_ctx.video_resolution.stride = stride; 1947 1948 if (!is_down_scalar_enabled) { 1949 rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft; 1950 rectangle.nTop = m_extradata_info.output_crop_rect.nTop; 1951 rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth; 1952 rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight; 1953 } 1954 return format_changed; 1955 } 1956 1957 OMX_ERRORTYPE omx_vdec::is_video_session_supported() 1958 { 1959 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 1960 OMX_MAX_STRINGNAME_SIZE) && 1961 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) { 1962 m_decoder_capability.max_width = 1280; 1963 m_decoder_capability.max_height = 720; 1964 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP"); 1965 } 1966 1967 if ((drv_ctx.video_resolution.frame_width * 1968 drv_ctx.video_resolution.frame_height > 1969 m_decoder_capability.max_width * 1970 m_decoder_capability.max_height) || 1971 (drv_ctx.video_resolution.frame_width* 1972 drv_ctx.video_resolution.frame_height < 1973 m_decoder_capability.min_width * 1974 m_decoder_capability.min_height)) { 1975 DEBUG_PRINT_ERROR( 1976 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", 1977 drv_ctx.video_resolution.frame_width, 1978 drv_ctx.video_resolution.frame_height, 1979 m_decoder_capability.min_width, 1980 m_decoder_capability.min_height, 1981 m_decoder_capability.max_width, 1982 m_decoder_capability.max_height); 1983 return OMX_ErrorUnsupportedSetting; 1984 } 1985 DEBUG_PRINT_HIGH("video session supported"); 1986 return OMX_ErrorNone; 1987 } 1988 1989 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len) 1990 { 1991 if (m_debug.in_buffer_log && !m_debug.infile) { 1992 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 1993 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v", 1994 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1995 } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 1996 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, 1997 drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1998 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 1999 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263", 2000 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2001 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) || 2002 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 2003 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264", 2004 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2005 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 2006 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265", 2007 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2008 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 2009 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 2010 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2011 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) { 2012 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 2013 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2014 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 2015 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 2016 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2017 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2018 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 2019 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2020 } else { 2021 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx", 2022 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2023 } 2024 m_debug.infile = fopen (m_debug.infile_name, "ab"); 2025 if (!m_debug.infile) { 2026 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); 2027 m_debug.infile_name[0] = '\0'; 2028 return -1; 2029 } 2030 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 2031 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2032 struct ivf_file_header { 2033 OMX_U8 signature[4]; //='DKIF'; 2034 OMX_U8 version ; //= 0; 2035 OMX_U8 headersize ; //= 32; 2036 OMX_U32 FourCC; 2037 OMX_U8 width; 2038 OMX_U8 height; 2039 OMX_U32 rate; 2040 OMX_U32 scale; 2041 OMX_U32 length; 2042 OMX_U8 unused[4]; 2043 } file_header; 2044 2045 memset((void *)&file_header,0,sizeof(file_header)); 2046 file_header.signature[0] = 'D'; 2047 file_header.signature[1] = 'K'; 2048 file_header.signature[2] = 'I'; 2049 file_header.signature[3] = 'F'; 2050 file_header.version = 0; 2051 file_header.headersize = 32; 2052 switch (drv_ctx.decoder_format) { 2053 case VDEC_CODECTYPE_VP8: 2054 file_header.FourCC = 0x30385056; 2055 break; 2056 case VDEC_CODECTYPE_VP9: 2057 file_header.FourCC = 0x30395056; 2058 break; 2059 default: 2060 DEBUG_PRINT_ERROR("unsupported format for VP8/VP9"); 2061 break; 2062 } 2063 fwrite((const char *)&file_header, 2064 sizeof(file_header),1,m_debug.infile); 2065 } 2066 } 2067 if (m_debug.infile && buffer_addr && buffer_len) { 2068 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 2069 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2070 struct vpx_ivf_frame_header { 2071 OMX_U32 framesize; 2072 OMX_U32 timestamp_lo; 2073 OMX_U32 timestamp_hi; 2074 } vpx_frame_header; 2075 vpx_frame_header.framesize = buffer_len; 2076 /* Currently FW doesn't use timestamp values */ 2077 vpx_frame_header.timestamp_lo = 0; 2078 vpx_frame_header.timestamp_hi = 0; 2079 fwrite((const char *)&vpx_frame_header, 2080 sizeof(vpx_frame_header),1,m_debug.infile); 2081 } 2082 fwrite(buffer_addr, buffer_len, 1, m_debug.infile); 2083 } 2084 return 0; 2085 } 2086 2087 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) { 2088 int buf_index = 0; 2089 char *temp = NULL; 2090 2091 if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen) 2092 return 0; 2093 2094 if (m_debug.out_buffer_log && !m_debug.outfile) { 2095 snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv", 2096 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2097 m_debug.outfile = fopen (m_debug.outfile_name, "ab"); 2098 if (!m_debug.outfile) { 2099 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc); 2100 m_debug.outfile_name[0] = '\0'; 2101 return -1; 2102 } 2103 } 2104 2105 if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) { 2106 snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta", 2107 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2108 snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta", 2109 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2110 m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab"); 2111 m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab"); 2112 if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) { 2113 DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc); 2114 m_debug.out_ymetafile_name[0] = '\0'; 2115 m_debug.out_uvmetafile_name[0] = '\0'; 2116 return -1; 2117 } 2118 } 2119 2120 buf_index = buffer - m_out_mem_ptr; 2121 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 2122 2123 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC || 2124 drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 2125 DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)", 2126 drv_ctx.video_resolution.frame_width, 2127 drv_ctx.video_resolution.frame_height); 2128 2129 if (m_debug.outfile) 2130 fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile); 2131 2132 if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) { 2133 unsigned int width = 0, height = 0; 2134 unsigned int y_plane, y_meta_plane; 2135 int y_stride = 0, y_sclines = 0; 2136 int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0; 2137 int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC; 2138 int i; 2139 int bytes_written = 0; 2140 2141 width = drv_ctx.video_resolution.frame_width; 2142 height = drv_ctx.video_resolution.frame_height; 2143 y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); 2144 y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); 2145 y_stride = VENUS_Y_STRIDE(color_fmt, width); 2146 y_sclines = VENUS_Y_SCANLINES(color_fmt, height); 2147 uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); 2148 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); 2149 2150 y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096); 2151 y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); 2152 2153 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 2154 for (i = 0; i < y_meta_scanlines; i++) { 2155 bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file); 2156 temp += y_meta_stride; 2157 } 2158 2159 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane; 2160 for(i = 0; i < uv_meta_scanlines; i++) { 2161 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file); 2162 temp += uv_meta_stride; 2163 } 2164 } 2165 } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 2166 int stride = drv_ctx.video_resolution.stride; 2167 int scanlines = drv_ctx.video_resolution.scan_lines; 2168 if (m_smoothstreaming_mode) { 2169 stride = drv_ctx.video_resolution.frame_width; 2170 scanlines = drv_ctx.video_resolution.frame_height; 2171 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1)); 2172 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1)); 2173 } 2174 unsigned i; 2175 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)", 2176 drv_ctx.video_resolution.frame_width, 2177 drv_ctx.video_resolution.frame_height, stride, scanlines); 2178 int bytes_written = 0; 2179 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { 2180 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 2181 temp += stride; 2182 } 2183 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; 2184 int stride_c = stride; 2185 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { 2186 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 2187 temp += stride_c; 2188 } 2189 } 2190 return 0; 2191 } 2192 2193 /* ====================================================================== 2194 FUNCTION 2195 omx_vdec::ComponentInit 2196 2197 DESCRIPTION 2198 Initialize the component. 2199 2200 PARAMETERS 2201 ctxt -- Context information related to the self. 2202 id -- Event identifier. This could be any of the following: 2203 1. Command completion event 2204 2. Buffer done callback event 2205 3. Frame done callback event 2206 2207 RETURN VALUE 2208 None. 2209 2210 ========================================================================== */ 2211 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 2212 { 2213 2214 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2215 struct v4l2_fmtdesc fdesc; 2216 struct v4l2_format fmt; 2217 struct v4l2_requestbuffers bufreq; 2218 struct v4l2_control control; 2219 struct v4l2_frmsizeenum frmsize; 2220 unsigned int alignment = 0,buffer_size = 0; 2221 int fds[2]; 2222 int r,ret=0; 2223 bool codec_ambiguous = false; 2224 OMX_STRING device_name = (OMX_STRING)"/dev/video32"; 2225 char property_value[PROPERTY_VALUE_MAX] = {0}; 2226 FILE *soc_file = NULL; 2227 char buffer[10]; 2228 2229 #ifdef _ANDROID_ 2230 char platform_name[PROPERTY_VALUE_MAX]; 2231 property_get("ro.board.platform", platform_name, "0"); 2232 if (!strncmp(platform_name, "msm8610", 7)) { 2233 device_name = (OMX_STRING)"/dev/video/q6_dec"; 2234 is_q6_platform = true; 2235 maxSmoothStreamingWidth = 1280; 2236 maxSmoothStreamingHeight = 720; 2237 } 2238 #endif 2239 2240 is_thulium_v1 = false; 2241 soc_file = fopen("/sys/devices/soc0/soc_id", "r"); 2242 if (soc_file) { 2243 fread(buffer, 1, 4, soc_file); 2244 fclose(soc_file); 2245 if (atoi(buffer) == 246) { 2246 soc_file = fopen("/sys/devices/soc0/revision", "r"); 2247 if (soc_file) { 2248 fread(buffer, 1, 4, soc_file); 2249 fclose(soc_file); 2250 if (atoi(buffer) == 1) { 2251 is_thulium_v1 = true; 2252 DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE"); 2253 } 2254 } 2255 } 2256 } 2257 2258 #ifdef _ANDROID_ 2259 /* 2260 * turn off frame parsing for Android by default. 2261 * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode 2262 */ 2263 arbitrary_bytes = false; 2264 property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 2265 if (atoi(property_value)) { 2266 DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command"); 2267 arbitrary_bytes = true; 2268 } 2269 #endif 2270 2271 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure", 2272 OMX_MAX_STRINGNAME_SIZE)) { 2273 secure_mode = true; 2274 arbitrary_bytes = false; 2275 role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; 2276 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure", 2277 OMX_MAX_STRINGNAME_SIZE)) { 2278 secure_mode = true; 2279 arbitrary_bytes = false; 2280 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2"; 2281 } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure", 2282 OMX_MAX_STRINGNAME_SIZE)) { 2283 secure_mode = true; 2284 arbitrary_bytes = false; 2285 role = (OMX_STRING)"OMX.qcom.video.decoder.hevc"; 2286 } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure", 2287 OMX_MAX_STRINGNAME_SIZE)) { 2288 secure_mode = true; 2289 arbitrary_bytes = false; 2290 role = (OMX_STRING)"OMX.qcom.video.decoder.vc1"; 2291 } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure", 2292 OMX_MAX_STRINGNAME_SIZE)) { 2293 secure_mode = true; 2294 arbitrary_bytes = false; 2295 role = (OMX_STRING)"OMX.qcom.video.decoder.wmv"; 2296 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure", 2297 OMX_MAX_STRINGNAME_SIZE)) { 2298 secure_mode = true; 2299 arbitrary_bytes = false; 2300 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4"; 2301 } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure", 2302 OMX_MAX_STRINGNAME_SIZE)) { 2303 secure_mode = true; 2304 arbitrary_bytes = false; 2305 role = (OMX_STRING)"OMX.qcom.video.decoder.vp9"; 2306 } 2307 else if (!strncmp(role, "OMX.qcom.video.decoder.vp8.secure", 2308 OMX_MAX_STRINGNAME_SIZE)) { 2309 secure_mode = true; 2310 arbitrary_bytes = false; 2311 role = (OMX_STRING)"OMX.qcom.video.decoder.vp8"; 2312 } 2313 2314 drv_ctx.video_driver_fd = open(device_name, O_RDWR); 2315 2316 DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd); 2317 2318 if (drv_ctx.video_driver_fd < 0) { 2319 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno); 2320 return OMX_ErrorInsufficientResources; 2321 } 2322 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; 2323 drv_ctx.frame_rate.fps_denominator = 1; 2324 operating_frame_rate = DEFAULT_FPS; 2325 m_poll_efd = eventfd(0, 0); 2326 if (m_poll_efd < 0) { 2327 DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno)); 2328 return OMX_ErrorInsufficientResources; 2329 } 2330 ret = subscribe_to_events(drv_ctx.video_driver_fd); 2331 if (!ret) { 2332 async_thread_created = true; 2333 ret = pthread_create(&async_thread_id,0,async_message_thread,this); 2334 } 2335 if (ret) { 2336 DEBUG_PRINT_ERROR("Failed to create async_message_thread"); 2337 async_thread_created = false; 2338 return OMX_ErrorInsufficientResources; 2339 } 2340 2341 #ifdef OUTPUT_EXTRADATA_LOG 2342 outputExtradataFile = fopen (output_extradata_filename, "ab"); 2343 #endif 2344 2345 // Copy the role information which provides the decoder kind 2346 strlcpy(drv_ctx.kind,role,128); 2347 2348 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ 2349 OMX_MAX_STRINGNAME_SIZE)) { 2350 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ 2351 OMX_MAX_STRINGNAME_SIZE); 2352 drv_ctx.timestamp_adjust = true; 2353 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; 2354 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 2355 output_capability=V4L2_PIX_FMT_MPEG4; 2356 /*Initialize Start Code for MPEG4*/ 2357 codec_type_parse = CODEC_TYPE_MPEG4; 2358 m_frame_parser.init_start_codes(codec_type_parse); 2359 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ 2360 OMX_MAX_STRINGNAME_SIZE)) { 2361 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ 2362 OMX_MAX_STRINGNAME_SIZE); 2363 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; 2364 output_capability = V4L2_PIX_FMT_MPEG2; 2365 eCompressionFormat = OMX_VIDEO_CodingMPEG2; 2366 /*Initialize Start Code for MPEG2*/ 2367 codec_type_parse = CODEC_TYPE_MPEG2; 2368 m_frame_parser.init_start_codes(codec_type_parse); 2369 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ 2370 OMX_MAX_STRINGNAME_SIZE)) { 2371 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 2372 DEBUG_PRINT_LOW("H263 Decoder selected"); 2373 drv_ctx.decoder_format = VDEC_CODECTYPE_H263; 2374 eCompressionFormat = OMX_VIDEO_CodingH263; 2375 output_capability = V4L2_PIX_FMT_H263; 2376 codec_type_parse = CODEC_TYPE_H263; 2377 m_frame_parser.init_start_codes(codec_type_parse); 2378 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ 2379 OMX_MAX_STRINGNAME_SIZE)) { 2380 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2381 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); 2382 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; 2383 output_capability = V4L2_PIX_FMT_DIVX_311; 2384 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2385 codec_type_parse = CODEC_TYPE_DIVX; 2386 m_frame_parser.init_start_codes(codec_type_parse); 2387 2388 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 2389 OMX_MAX_STRINGNAME_SIZE)) { 2390 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2391 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); 2392 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; 2393 output_capability = V4L2_PIX_FMT_DIVX; 2394 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2395 codec_type_parse = CODEC_TYPE_DIVX; 2396 codec_ambiguous = true; 2397 m_frame_parser.init_start_codes(codec_type_parse); 2398 2399 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ 2400 OMX_MAX_STRINGNAME_SIZE)) { 2401 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2402 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); 2403 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; 2404 output_capability = V4L2_PIX_FMT_DIVX; 2405 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2406 codec_type_parse = CODEC_TYPE_DIVX; 2407 codec_ambiguous = true; 2408 m_frame_parser.init_start_codes(codec_type_parse); 2409 2410 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ 2411 OMX_MAX_STRINGNAME_SIZE)) { 2412 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 2413 drv_ctx.decoder_format = VDEC_CODECTYPE_H264; 2414 output_capability=V4L2_PIX_FMT_H264; 2415 eCompressionFormat = OMX_VIDEO_CodingAVC; 2416 codec_type_parse = CODEC_TYPE_H264; 2417 m_frame_parser.init_start_codes(codec_type_parse); 2418 m_frame_parser.init_nal_length(nal_length); 2419 if (is_thulium_v1) { 2420 arbitrary_bytes = true; 2421 DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264"); 2422 } 2423 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\ 2424 OMX_MAX_STRINGNAME_SIZE)) { 2425 strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 2426 drv_ctx.decoder_format = VDEC_CODECTYPE_MVC; 2427 output_capability = V4L2_PIX_FMT_H264_MVC; 2428 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC; 2429 codec_type_parse = CODEC_TYPE_H264; 2430 m_frame_parser.init_start_codes(codec_type_parse); 2431 m_frame_parser.init_nal_length(nal_length); 2432 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ 2433 OMX_MAX_STRINGNAME_SIZE)) { 2434 strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 2435 drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; 2436 output_capability = V4L2_PIX_FMT_HEVC; 2437 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; 2438 codec_type_parse = CODEC_TYPE_HEVC; 2439 m_frame_parser.init_start_codes(codec_type_parse); 2440 m_frame_parser.init_nal_length(nal_length); 2441 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ 2442 OMX_MAX_STRINGNAME_SIZE)) { 2443 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2444 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; 2445 eCompressionFormat = OMX_VIDEO_CodingWMV; 2446 codec_type_parse = CODEC_TYPE_VC1; 2447 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; 2448 m_frame_parser.init_start_codes(codec_type_parse); 2449 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ 2450 OMX_MAX_STRINGNAME_SIZE)) { 2451 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2452 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; 2453 eCompressionFormat = OMX_VIDEO_CodingWMV; 2454 codec_type_parse = CODEC_TYPE_VC1; 2455 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; 2456 m_frame_parser.init_start_codes(codec_type_parse); 2457 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ 2458 OMX_MAX_STRINGNAME_SIZE)) { 2459 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 2460 drv_ctx.decoder_format = VDEC_CODECTYPE_VP8; 2461 output_capability = V4L2_PIX_FMT_VP8; 2462 eCompressionFormat = OMX_VIDEO_CodingVP8; 2463 codec_type_parse = CODEC_TYPE_VP8; 2464 arbitrary_bytes = false; 2465 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", \ 2466 OMX_MAX_STRINGNAME_SIZE)) { 2467 strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 2468 drv_ctx.decoder_format = VDEC_CODECTYPE_VP9; 2469 output_capability = V4L2_PIX_FMT_VP9; 2470 eCompressionFormat = OMX_VIDEO_CodingVP9; 2471 codec_type_parse = CODEC_TYPE_VP9; 2472 arbitrary_bytes = false; 2473 } else { 2474 DEBUG_PRINT_ERROR("ERROR:Unknown Component"); 2475 eRet = OMX_ErrorInvalidComponentName; 2476 } 2477 2478 if (eRet == OMX_ErrorNone) { 2479 OMX_COLOR_FORMATTYPE dest_color_format; 2480 if (m_disable_ubwc_mode) { 2481 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 2482 } else { 2483 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC; 2484 } 2485 if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC) 2486 dest_color_format = (OMX_COLOR_FORMATTYPE) 2487 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 2488 else 2489 dest_color_format = (OMX_COLOR_FORMATTYPE) 2490 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 2491 if (!client_buffers.set_color_format(dest_color_format)) { 2492 DEBUG_PRINT_ERROR("Setting color format failed"); 2493 eRet = OMX_ErrorInsufficientResources; 2494 } 2495 2496 dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8; 2497 m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; 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 if (codec_ambiguous) { 2549 if (output_capability == V4L2_PIX_FMT_DIVX) { 2550 struct v4l2_control divx_ctrl; 2551 2552 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { 2553 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; 2554 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { 2555 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; 2556 } else { 2557 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; 2558 } 2559 2560 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; 2561 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); 2562 if (ret) { 2563 DEBUG_PRINT_ERROR("Failed to set divx version"); 2564 } 2565 } else { 2566 DEBUG_PRINT_ERROR("Codec should not be ambiguous"); 2567 } 2568 } 2569 2570 property_get("persist.vendor.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR); 2571 m_conceal_color= atoi(property_value); 2572 DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color); 2573 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR; 2574 control.value = m_conceal_color; 2575 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2576 if (ret) { 2577 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret); 2578 } 2579 2580 //Get the hardware capabilities 2581 memset((void *)&frmsize,0,sizeof(frmsize)); 2582 frmsize.index = 0; 2583 frmsize.pixel_format = output_capability; 2584 ret = ioctl(drv_ctx.video_driver_fd, 2585 VIDIOC_ENUM_FRAMESIZES, &frmsize); 2586 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 2587 DEBUG_PRINT_ERROR("Failed to get framesizes"); 2588 return OMX_ErrorHardware; 2589 } 2590 2591 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 2592 m_decoder_capability.min_width = frmsize.stepwise.min_width; 2593 m_decoder_capability.max_width = frmsize.stepwise.max_width; 2594 m_decoder_capability.min_height = frmsize.stepwise.min_height; 2595 m_decoder_capability.max_height = frmsize.stepwise.max_height; 2596 } 2597 2598 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 2599 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2600 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2601 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2602 fmt.fmt.pix_mp.pixelformat = capture_capability; 2603 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2604 if (ret) { 2605 /*TODO: How to handle this case */ 2606 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 2607 } 2608 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE)); 2609 framesize.nWidth = drv_ctx.video_resolution.frame_width; 2610 framesize.nHeight = drv_ctx.video_resolution.frame_height; 2611 2612 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE)); 2613 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 2614 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 2615 2616 DEBUG_PRINT_HIGH("Set Format was successful"); 2617 if (secure_mode) { 2618 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 2619 control.value = 1; 2620 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret); 2621 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 2622 if (ret) { 2623 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret); 2624 return OMX_ErrorInsufficientResources; 2625 } 2626 } 2627 if (output_capability == V4L2_PIX_FMT_H264_MVC) { 2628 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT; 2629 control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM; 2630 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2631 if (ret) { 2632 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout"); 2633 return OMX_ErrorInsufficientResources; 2634 } 2635 } 2636 2637 if (is_thulium_v1) { 2638 eRet = enable_smoothstreaming(); 2639 if (eRet != OMX_ErrorNone) { 2640 DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver"); 2641 return eRet; 2642 } 2643 } 2644 2645 /*Get the Buffer requirements for input and output ports*/ 2646 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; 2647 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 2648 2649 if (secure_mode) { 2650 drv_ctx.op_buf.alignment = SECURE_ALIGN; 2651 drv_ctx.ip_buf.alignment = SECURE_ALIGN; 2652 } else { 2653 drv_ctx.op_buf.alignment = SZ_4K; 2654 drv_ctx.ip_buf.alignment = SZ_4K; 2655 } 2656 2657 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 2658 drv_ctx.extradata = 0; 2659 drv_ctx.picture_order = VDEC_ORDER_DISPLAY; 2660 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 2661 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 2662 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2663 drv_ctx.idr_only_decoding = 0; 2664 2665 #ifdef _ANDROID_ 2666 property_get("vendor.vidc.dec.enable.downscalar",property_value,"0"); 2667 if (atoi(property_value)) { 2668 m_enable_downscalar = atoi(property_value); 2669 property_get("vendor.vidc.dec.downscalar_width",property_value,"0"); 2670 if (atoi(property_value)) { 2671 m_downscalar_width = atoi(property_value); 2672 } 2673 property_get("vendor.vidc.dec.downscalar_height",property_value,"0"); 2674 if (atoi(property_value)) { 2675 m_downscalar_height = atoi(property_value); 2676 } 2677 2678 if (m_downscalar_width < m_decoder_capability.min_width || 2679 m_downscalar_height < m_decoder_capability.min_height) { 2680 m_downscalar_width = 0; 2681 m_downscalar_height = 0; 2682 } 2683 2684 DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n", 2685 m_downscalar_width, m_downscalar_height); 2686 } 2687 property_get("vendor.vidc.disable.split.mode",property_value,"0"); 2688 m_disable_split_mode = atoi(property_value); 2689 DEBUG_PRINT_HIGH("split mode is %s", m_disable_split_mode ? "disabled" : "enabled"); 2690 #endif 2691 m_state = OMX_StateLoaded; 2692 #ifdef DEFAULT_EXTRADATA 2693 enable_extradata(DEFAULT_EXTRADATA, true, true); 2694 #endif 2695 eRet = get_buffer_req(&drv_ctx.ip_buf); 2696 DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size); 2697 get_buffer_req(&drv_ctx.op_buf); 2698 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2699 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC || 2700 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2701 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; 2702 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); 2703 h264_scratch.nFilledLen = 0; 2704 h264_scratch.nOffset = 0; 2705 2706 if (h264_scratch.pBuffer == NULL) { 2707 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed "); 2708 return OMX_ErrorInsufficientResources; 2709 } 2710 } 2711 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2712 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2713 if (m_frame_parser.mutils == NULL) { 2714 m_frame_parser.mutils = new H264_Utils(); 2715 if (m_frame_parser.mutils == NULL) { 2716 DEBUG_PRINT_ERROR("parser utils Allocation failed "); 2717 eRet = OMX_ErrorInsufficientResources; 2718 } else { 2719 m_frame_parser.mutils->initialize_frame_checking_environment(); 2720 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); 2721 } 2722 } 2723 2724 h264_parser = new h264_stream_parser(); 2725 if (!h264_parser) { 2726 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); 2727 eRet = OMX_ErrorInsufficientResources; 2728 } 2729 } 2730 2731 if (pipe(fds)) { 2732 DEBUG_PRINT_ERROR("pipe creation failed"); 2733 eRet = OMX_ErrorInsufficientResources; 2734 } else { 2735 m_pipe_in = fds[0]; 2736 m_pipe_out = fds[1]; 2737 msg_thread_created = true; 2738 r = pthread_create(&msg_thread_id,0,message_thread_dec,this); 2739 2740 if (r < 0) { 2741 DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed"); 2742 msg_thread_created = false; 2743 eRet = OMX_ErrorInsufficientResources; 2744 } 2745 } 2746 } 2747 2748 { 2749 VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore); 2750 init_vendor_extensions(*extStore); 2751 mVendorExtensionStore.dumpExtensions((const char *)role); 2752 } 2753 2754 if (eRet != OMX_ErrorNone) { 2755 DEBUG_PRINT_ERROR("Component Init Failed"); 2756 } else { 2757 DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d", 2758 drv_ctx.video_driver_fd); 2759 } 2760 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); 2761 return eRet; 2762 } 2763 2764 /* ====================================================================== 2765 FUNCTION 2766 omx_vdec::GetComponentVersion 2767 2768 DESCRIPTION 2769 Returns the component version. 2770 2771 PARAMETERS 2772 TBD. 2773 2774 RETURN VALUE 2775 OMX_ErrorNone. 2776 2777 ========================================================================== */ 2778 OMX_ERRORTYPE omx_vdec::get_component_version 2779 ( 2780 OMX_IN OMX_HANDLETYPE hComp, 2781 OMX_OUT OMX_STRING componentName, 2782 OMX_OUT OMX_VERSIONTYPE* componentVersion, 2783 OMX_OUT OMX_VERSIONTYPE* specVersion, 2784 OMX_OUT OMX_UUIDTYPE* componentUUID 2785 ) 2786 { 2787 (void) hComp; 2788 (void) componentName; 2789 (void) componentVersion; 2790 (void) componentUUID; 2791 if (m_state == OMX_StateInvalid) { 2792 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State"); 2793 return OMX_ErrorInvalidState; 2794 } 2795 /* TBD -- Return the proper version */ 2796 if (specVersion) { 2797 specVersion->nVersion = OMX_SPEC_VERSION; 2798 } 2799 return OMX_ErrorNone; 2800 } 2801 /* ====================================================================== 2802 FUNCTION 2803 omx_vdec::SendCommand 2804 2805 DESCRIPTION 2806 Returns zero if all the buffers released.. 2807 2808 PARAMETERS 2809 None. 2810 2811 RETURN VALUE 2812 true/false 2813 2814 ========================================================================== */ 2815 OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 2816 OMX_IN OMX_COMMANDTYPE cmd, 2817 OMX_IN OMX_U32 param1, 2818 OMX_IN OMX_PTR cmdData 2819 ) 2820 { 2821 (void) hComp; 2822 (void) cmdData; 2823 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client"); 2824 if (m_state == OMX_StateInvalid) { 2825 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State"); 2826 return OMX_ErrorInvalidState; 2827 } 2828 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX 2829 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) { 2830 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush " 2831 "to invalid port: %u", (unsigned int)param1); 2832 return OMX_ErrorBadPortIndex; 2833 } 2834 2835 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 2836 sem_wait(&m_cmd_lock); 2837 DEBUG_PRINT_LOW("send_command: Command Processed"); 2838 return OMX_ErrorNone; 2839 } 2840 2841 /* ====================================================================== 2842 FUNCTION 2843 omx_vdec::SendCommand 2844 2845 DESCRIPTION 2846 Returns zero if all the buffers released.. 2847 2848 PARAMETERS 2849 None. 2850 2851 RETURN VALUE 2852 true/false 2853 2854 ========================================================================== */ 2855 OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 2856 OMX_IN OMX_COMMANDTYPE cmd, 2857 OMX_IN OMX_U32 param1, 2858 OMX_IN OMX_PTR cmdData 2859 ) 2860 { 2861 (void) hComp; 2862 (void) cmdData; 2863 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2864 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 2865 int bFlag = 1,sem_posted = 0,ret=0; 2866 2867 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd); 2868 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d", 2869 m_state, eState); 2870 2871 if (cmd == OMX_CommandStateSet) { 2872 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); 2873 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); 2874 /***************************/ 2875 /* Current State is Loaded */ 2876 /***************************/ 2877 if (m_state == OMX_StateLoaded) { 2878 if (eState == OMX_StateIdle) { 2879 //if all buffers are allocated or all ports disabled 2880 if (allocate_done() || 2881 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) { 2882 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); 2883 } else { 2884 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); 2885 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 2886 // Skip the event notification 2887 bFlag = 0; 2888 } 2889 } 2890 /* Requesting transition from Loaded to Loaded */ 2891 else if (eState == OMX_StateLoaded) { 2892 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded"); 2893 post_event(OMX_EventError,OMX_ErrorSameState,\ 2894 OMX_COMPONENT_GENERATE_EVENT); 2895 eRet = OMX_ErrorSameState; 2896 } 2897 /* Requesting transition from Loaded to WaitForResources */ 2898 else if (eState == OMX_StateWaitForResources) { 2899 /* Since error is None , we will post an event 2900 at the end of this function definition */ 2901 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); 2902 } 2903 /* Requesting transition from Loaded to Executing */ 2904 else if (eState == OMX_StateExecuting) { 2905 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing"); 2906 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2907 OMX_COMPONENT_GENERATE_EVENT); 2908 eRet = OMX_ErrorIncorrectStateTransition; 2909 } 2910 /* Requesting transition from Loaded to Pause */ 2911 else if (eState == OMX_StatePause) { 2912 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause"); 2913 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2914 OMX_COMPONENT_GENERATE_EVENT); 2915 eRet = OMX_ErrorIncorrectStateTransition; 2916 } 2917 /* Requesting transition from Loaded to Invalid */ 2918 else if (eState == OMX_StateInvalid) { 2919 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid"); 2920 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2921 eRet = OMX_ErrorInvalidState; 2922 } else { 2923 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\ 2924 eState); 2925 eRet = OMX_ErrorBadParameter; 2926 } 2927 } 2928 2929 /***************************/ 2930 /* Current State is IDLE */ 2931 /***************************/ 2932 else if (m_state == OMX_StateIdle) { 2933 if (eState == OMX_StateLoaded) { 2934 if (release_done()) { 2935 /* 2936 * Since error is None , we will post an event at the end 2937 * of this function definition 2938 * Reset buffer requirements here to ensure setting buffer requirement 2939 * when component move to executing state from loaded state via Idle. 2940 */ 2941 drv_ctx.op_buf.buffer_size = 0; 2942 drv_ctx.op_buf.actualcount = 0; 2943 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded"); 2944 } else { 2945 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending"); 2946 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 2947 // Skip the event notification 2948 bFlag = 0; 2949 } 2950 } 2951 /* Requesting transition from Idle to Executing */ 2952 else if (eState == OMX_StateExecuting) { 2953 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2954 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); 2955 bFlag = 1; 2956 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2957 m_state=OMX_StateExecuting; 2958 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful"); 2959 } 2960 /* Requesting transition from Idle to Idle */ 2961 else if (eState == OMX_StateIdle) { 2962 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle"); 2963 post_event(OMX_EventError,OMX_ErrorSameState,\ 2964 OMX_COMPONENT_GENERATE_EVENT); 2965 eRet = OMX_ErrorSameState; 2966 } 2967 /* Requesting transition from Idle to WaitForResources */ 2968 else if (eState == OMX_StateWaitForResources) { 2969 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources"); 2970 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2971 OMX_COMPONENT_GENERATE_EVENT); 2972 eRet = OMX_ErrorIncorrectStateTransition; 2973 } 2974 /* Requesting transition from Idle to Pause */ 2975 else if (eState == OMX_StatePause) { 2976 /*To pause the Video core we need to start the driver*/ 2977 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 2978 NULL) < */0) { 2979 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED"); 2980 omx_report_error (); 2981 eRet = OMX_ErrorHardware; 2982 } else { 2983 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 2984 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause"); 2985 bFlag = 0; 2986 } 2987 } 2988 /* Requesting transition from Idle to Invalid */ 2989 else if (eState == OMX_StateInvalid) { 2990 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid"); 2991 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2992 eRet = OMX_ErrorInvalidState; 2993 } else { 2994 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState); 2995 eRet = OMX_ErrorBadParameter; 2996 } 2997 } 2998 2999 /******************************/ 3000 /* Current State is Executing */ 3001 /******************************/ 3002 else if (m_state == OMX_StateExecuting) { 3003 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting"); 3004 /* Requesting transition from Executing to Idle */ 3005 if (eState == OMX_StateIdle) { 3006 /* Since error is None , we will post an event 3007 at the end of this function definition 3008 */ 3009 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle"); 3010 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 3011 if (!sem_posted) { 3012 sem_posted = 1; 3013 sem_post (&m_cmd_lock); 3014 execute_omx_flush(OMX_ALL); 3015 } 3016 bFlag = 0; 3017 } 3018 /* Requesting transition from Executing to Paused */ 3019 else if (eState == OMX_StatePause) { 3020 DEBUG_PRINT_LOW("PAUSE Command Issued"); 3021 m_state = OMX_StatePause; 3022 bFlag = 1; 3023 } 3024 /* Requesting transition from Executing to Loaded */ 3025 else if (eState == OMX_StateLoaded) { 3026 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded"); 3027 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3028 OMX_COMPONENT_GENERATE_EVENT); 3029 eRet = OMX_ErrorIncorrectStateTransition; 3030 } 3031 /* Requesting transition from Executing to WaitForResources */ 3032 else if (eState == OMX_StateWaitForResources) { 3033 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources"); 3034 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3035 OMX_COMPONENT_GENERATE_EVENT); 3036 eRet = OMX_ErrorIncorrectStateTransition; 3037 } 3038 /* Requesting transition from Executing to Executing */ 3039 else if (eState == OMX_StateExecuting) { 3040 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing"); 3041 post_event(OMX_EventError,OMX_ErrorSameState,\ 3042 OMX_COMPONENT_GENERATE_EVENT); 3043 eRet = OMX_ErrorSameState; 3044 } 3045 /* Requesting transition from Executing to Invalid */ 3046 else if (eState == OMX_StateInvalid) { 3047 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid"); 3048 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3049 eRet = OMX_ErrorInvalidState; 3050 } else { 3051 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState); 3052 eRet = OMX_ErrorBadParameter; 3053 } 3054 } 3055 /***************************/ 3056 /* Current State is Pause */ 3057 /***************************/ 3058 else if (m_state == OMX_StatePause) { 3059 /* Requesting transition from Pause to Executing */ 3060 if (eState == OMX_StateExecuting) { 3061 DEBUG_PRINT_LOW("Pause --> Executing"); 3062 m_state = OMX_StateExecuting; 3063 bFlag = 1; 3064 } 3065 /* Requesting transition from Pause to Idle */ 3066 else if (eState == OMX_StateIdle) { 3067 /* Since error is None , we will post an event 3068 at the end of this function definition */ 3069 DEBUG_PRINT_LOW("Pause --> Idle"); 3070 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 3071 if (!sem_posted) { 3072 sem_posted = 1; 3073 sem_post (&m_cmd_lock); 3074 execute_omx_flush(OMX_ALL); 3075 } 3076 bFlag = 0; 3077 } 3078 /* Requesting transition from Pause to loaded */ 3079 else if (eState == OMX_StateLoaded) { 3080 DEBUG_PRINT_ERROR("Pause --> loaded"); 3081 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3082 OMX_COMPONENT_GENERATE_EVENT); 3083 eRet = OMX_ErrorIncorrectStateTransition; 3084 } 3085 /* Requesting transition from Pause to WaitForResources */ 3086 else if (eState == OMX_StateWaitForResources) { 3087 DEBUG_PRINT_ERROR("Pause --> WaitForResources"); 3088 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3089 OMX_COMPONENT_GENERATE_EVENT); 3090 eRet = OMX_ErrorIncorrectStateTransition; 3091 } 3092 /* Requesting transition from Pause to Pause */ 3093 else if (eState == OMX_StatePause) { 3094 DEBUG_PRINT_ERROR("Pause --> Pause"); 3095 post_event(OMX_EventError,OMX_ErrorSameState,\ 3096 OMX_COMPONENT_GENERATE_EVENT); 3097 eRet = OMX_ErrorSameState; 3098 } 3099 /* Requesting transition from Pause to Invalid */ 3100 else if (eState == OMX_StateInvalid) { 3101 DEBUG_PRINT_ERROR("Pause --> Invalid"); 3102 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3103 eRet = OMX_ErrorInvalidState; 3104 } else { 3105 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState); 3106 eRet = OMX_ErrorBadParameter; 3107 } 3108 } 3109 /***************************/ 3110 /* Current State is WaitForResources */ 3111 /***************************/ 3112 else if (m_state == OMX_StateWaitForResources) { 3113 /* Requesting transition from WaitForResources to Loaded */ 3114 if (eState == OMX_StateLoaded) { 3115 /* Since error is None , we will post an event 3116 at the end of this function definition */ 3117 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded"); 3118 } 3119 /* Requesting transition from WaitForResources to WaitForResources */ 3120 else if (eState == OMX_StateWaitForResources) { 3121 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources"); 3122 post_event(OMX_EventError,OMX_ErrorSameState, 3123 OMX_COMPONENT_GENERATE_EVENT); 3124 eRet = OMX_ErrorSameState; 3125 } 3126 /* Requesting transition from WaitForResources to Executing */ 3127 else if (eState == OMX_StateExecuting) { 3128 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing"); 3129 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3130 OMX_COMPONENT_GENERATE_EVENT); 3131 eRet = OMX_ErrorIncorrectStateTransition; 3132 } 3133 /* Requesting transition from WaitForResources to Pause */ 3134 else if (eState == OMX_StatePause) { 3135 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause"); 3136 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3137 OMX_COMPONENT_GENERATE_EVENT); 3138 eRet = OMX_ErrorIncorrectStateTransition; 3139 } 3140 /* Requesting transition from WaitForResources to Invalid */ 3141 else if (eState == OMX_StateInvalid) { 3142 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid"); 3143 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3144 eRet = OMX_ErrorInvalidState; 3145 } 3146 /* Requesting transition from WaitForResources to Loaded - 3147 is NOT tested by Khronos TS */ 3148 3149 } else { 3150 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState); 3151 eRet = OMX_ErrorBadParameter; 3152 } 3153 } 3154 /********************************/ 3155 /* Current State is Invalid */ 3156 /*******************************/ 3157 else if (m_state == OMX_StateInvalid) { 3158 /* State Transition from Inavlid to any state */ 3159 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources 3160 || OMX_StateIdle || OMX_StateExecuting 3161 || OMX_StatePause || OMX_StateInvalid)) { 3162 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded"); 3163 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 3164 OMX_COMPONENT_GENERATE_EVENT); 3165 eRet = OMX_ErrorInvalidState; 3166 } 3167 } else if (cmd == OMX_CommandFlush) { 3168 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued" 3169 "with param1: %u", (unsigned int)param1); 3170 #ifdef _MSM8974_ 3171 send_codec_config(); 3172 #endif 3173 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX || 3174 param1 == OMX_ALL)) { 3175 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) { 3176 struct timespec ts; 3177 3178 clock_gettime(CLOCK_REALTIME, &ts); 3179 ts.tv_sec += 2; 3180 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ", 3181 m_queued_codec_config_count); 3182 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED); 3183 if (sem_timedwait(&m_safe_flush, &ts)) { 3184 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers"); 3185 } 3186 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED); 3187 } 3188 } 3189 3190 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 3191 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 3192 } 3193 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 3194 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 3195 } 3196 if (!sem_posted) { 3197 sem_posted = 1; 3198 DEBUG_PRINT_LOW("Set the Semaphore"); 3199 sem_post (&m_cmd_lock); 3200 execute_omx_flush(param1); 3201 } 3202 bFlag = 0; 3203 } else if ( cmd == OMX_CommandPortEnable) { 3204 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued" 3205 "with param1: %u", (unsigned int)param1); 3206 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 3207 m_inp_bEnabled = OMX_TRUE; 3208 3209 if ( (m_state == OMX_StateLoaded && 3210 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3211 || allocate_input_done()) { 3212 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 3213 OMX_COMPONENT_GENERATE_EVENT); 3214 } else { 3215 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 3216 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 3217 // Skip the event notification 3218 bFlag = 0; 3219 } 3220 } 3221 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3222 DEBUG_PRINT_LOW("Enable output Port command recieved"); 3223 m_out_bEnabled = OMX_TRUE; 3224 3225 if ( (m_state == OMX_StateLoaded && 3226 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3227 || (allocate_output_done())) { 3228 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 3229 OMX_COMPONENT_GENERATE_EVENT); 3230 3231 } else { 3232 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 3233 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3234 // Skip the event notification 3235 bFlag = 0; 3236 /* enable/disable downscaling if required */ 3237 ret = decide_downscalar(); 3238 if (ret) { 3239 DEBUG_PRINT_LOW("decide_downscalar failed\n"); 3240 } 3241 } 3242 } 3243 } else if (cmd == OMX_CommandPortDisable) { 3244 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued" 3245 "with param1: %u", (unsigned int)param1); 3246 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 3247 codec_config_flag = false; 3248 m_inp_bEnabled = OMX_FALSE; 3249 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3250 && release_input_done()) { 3251 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 3252 OMX_COMPONENT_GENERATE_EVENT); 3253 } else { 3254 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 3255 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3256 if (!sem_posted) { 3257 sem_posted = 1; 3258 sem_post (&m_cmd_lock); 3259 } 3260 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 3261 } 3262 3263 // Skip the event notification 3264 bFlag = 0; 3265 } 3266 } 3267 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3268 m_out_bEnabled = OMX_FALSE; 3269 DEBUG_PRINT_LOW("Disable output Port command recieved"); 3270 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3271 && release_output_done()) { 3272 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 3273 OMX_COMPONENT_GENERATE_EVENT); 3274 } else { 3275 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 3276 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3277 if (!sem_posted) { 3278 sem_posted = 1; 3279 sem_post (&m_cmd_lock); 3280 } 3281 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 3282 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 3283 } 3284 // Skip the event notification 3285 bFlag = 0; 3286 3287 } 3288 } 3289 } else { 3290 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd); 3291 eRet = OMX_ErrorNotImplemented; 3292 } 3293 if (eRet == OMX_ErrorNone && bFlag) { 3294 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 3295 } 3296 if (!sem_posted) { 3297 sem_post(&m_cmd_lock); 3298 } 3299 3300 return eRet; 3301 } 3302 3303 /* ====================================================================== 3304 FUNCTION 3305 omx_vdec::ExecuteOmxFlush 3306 3307 DESCRIPTION 3308 Executes the OMX flush. 3309 3310 PARAMETERS 3311 flushtype - input flush(1)/output flush(0)/ both. 3312 3313 RETURN VALUE 3314 true/false 3315 3316 ========================================================================== */ 3317 bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 3318 { 3319 bool bRet = false; 3320 struct v4l2_plane plane; 3321 struct v4l2_buffer v4l2_buf; 3322 struct v4l2_decoder_cmd dec; 3323 DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType); 3324 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 3325 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; 3326 3327 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig); 3328 3329 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) { 3330 output_flush_progress = true; 3331 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3332 } else { 3333 /* XXX: The driver/hardware does not support flushing of individual ports 3334 * in all states. So we pretty much need to flush both ports internally, 3335 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it 3336 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, 3337 * we automatically omit sending the FLUSH done for the "opposite" port. */ 3338 input_flush_progress = true; 3339 output_flush_progress = true; 3340 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3341 request_perf_level(VIDC_TURBO); 3342 } 3343 3344 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 3345 DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType); 3346 bRet = false; 3347 } 3348 3349 return bRet; 3350 } 3351 /*========================================================================= 3352 FUNCTION : execute_output_flush 3353 3354 DESCRIPTION 3355 Executes the OMX flush at OUTPUT PORT. 3356 3357 PARAMETERS 3358 None. 3359 3360 RETURN VALUE 3361 true/false 3362 ==========================================================================*/ 3363 bool omx_vdec::execute_output_flush() 3364 { 3365 unsigned long p1 = 0; // Parameter - 1 3366 unsigned long p2 = 0; // Parameter - 2 3367 unsigned long ident = 0; 3368 bool bRet = true; 3369 3370 /*Generate FBD for all Buffers in the FTBq*/ 3371 pthread_mutex_lock(&m_lock); 3372 DEBUG_PRINT_LOW("Initiate Output Flush"); 3373 3374 //reset last render TS 3375 if(m_last_rendered_TS > 0) { 3376 m_last_rendered_TS = 0; 3377 } 3378 3379 while (m_ftb_q.m_size) { 3380 DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d", 3381 m_ftb_q.m_size,pending_output_buffers); 3382 m_ftb_q.pop_entry(&p1,&p2,&ident); 3383 DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2); 3384 if (ident == m_fill_output_msg ) { 3385 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2); 3386 } else if (ident == OMX_COMPONENT_GENERATE_FBD) { 3387 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1); 3388 } 3389 } 3390 pthread_mutex_unlock(&m_lock); 3391 output_flush_progress = false; 3392 3393 if (arbitrary_bytes) { 3394 prev_ts = LLONG_MAX; 3395 rst_prev_ts = true; 3396 } 3397 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); 3398 return bRet; 3399 } 3400 /*========================================================================= 3401 FUNCTION : execute_input_flush 3402 3403 DESCRIPTION 3404 Executes the OMX flush at INPUT PORT. 3405 3406 PARAMETERS 3407 None. 3408 3409 RETURN VALUE 3410 true/false 3411 ==========================================================================*/ 3412 bool omx_vdec::execute_input_flush() 3413 { 3414 unsigned i =0; 3415 unsigned long p1 = 0; // Parameter - 1 3416 unsigned long p2 = 0; // Parameter - 2 3417 unsigned long ident = 0; 3418 bool bRet = true; 3419 3420 /*Generate EBD for all Buffers in the ETBq*/ 3421 DEBUG_PRINT_LOW("Initiate Input Flush"); 3422 3423 pthread_mutex_lock(&m_lock); 3424 DEBUG_PRINT_LOW("Check if the Queue is empty"); 3425 while (m_etb_q.m_size) { 3426 m_etb_q.pop_entry(&p1,&p2,&ident); 3427 3428 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 3429 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 3430 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 3431 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 3432 pending_input_buffers++; 3433 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 3434 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 3435 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 3436 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 3437 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 3438 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p", 3439 (OMX_BUFFERHEADERTYPE *)p1); 3440 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 3441 } 3442 } 3443 time_stamp_dts.flush_timestamp(); 3444 /*Check if Heap Buffers are to be flushed*/ 3445 if (arbitrary_bytes && !(codec_config_flag)) { 3446 DEBUG_PRINT_LOW("Reset all the variables before flusing"); 3447 h264_scratch.nFilledLen = 0; 3448 nal_count = 0; 3449 look_ahead_nal = false; 3450 frame_count = 0; 3451 h264_last_au_ts = LLONG_MAX; 3452 h264_last_au_flags = 0; 3453 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 3454 m_demux_entries = 0; 3455 DEBUG_PRINT_LOW("Initialize parser"); 3456 if (m_frame_parser.mutils) { 3457 m_frame_parser.mutils->initialize_frame_checking_environment(); 3458 } 3459 3460 while (m_input_pending_q.m_size) { 3461 m_input_pending_q.pop_entry(&p1,&p2,&ident); 3462 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 3463 } 3464 3465 if (psource_frame) { 3466 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 3467 psource_frame = NULL; 3468 } 3469 3470 if (pdest_frame) { 3471 pdest_frame->nFilledLen = 0; 3472 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL, 3473 (unsigned int)NULL); 3474 pdest_frame = NULL; 3475 } 3476 m_frame_parser.flush(); 3477 } else if (codec_config_flag) { 3478 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " 3479 "is not sent to the driver yet"); 3480 } 3481 pthread_mutex_unlock(&m_lock); 3482 input_flush_progress = false; 3483 if (!arbitrary_bytes) { 3484 prev_ts = LLONG_MAX; 3485 rst_prev_ts = true; 3486 } 3487 #ifdef _ANDROID_ 3488 if (m_debug_timestamp) { 3489 m_timestamp_list.reset_ts_list(); 3490 } 3491 #endif 3492 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); 3493 return bRet; 3494 } 3495 3496 /*========================================================================= 3497 FUNCTION : notify_flush_done 3498 3499 DESCRIPTION 3500 Notifies flush done to the OMX Client. 3501 3502 PARAMETERS 3503 ctxt -- Context information related to the self.. 3504 3505 RETURN VALUE 3506 NONE 3507 ==========================================================================*/ 3508 void omx_vdec::notify_flush_done(void *ctxt) { 3509 3510 omx_vdec *pThis = (omx_vdec *) ctxt; 3511 3512 if (!pThis->input_flush_progress && !pThis->output_flush_progress) { 3513 if (BITMASK_PRESENT(&pThis->m_flags, 3514 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) { 3515 DEBUG_PRINT_LOW("Notify Output Flush done"); 3516 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 3517 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 3518 OMX_EventCmdComplete,OMX_CommandFlush, 3519 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 3520 } 3521 3522 if (BITMASK_PRESENT(&pThis->m_flags, 3523 OMX_COMPONENT_INPUT_FLUSH_PENDING)) { 3524 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 3525 DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); 3526 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 3527 OMX_EventCmdComplete,OMX_CommandFlush, 3528 OMX_CORE_INPUT_PORT_INDEX,NULL ); 3529 } 3530 } 3531 } 3532 3533 /* ====================================================================== 3534 FUNCTION 3535 omx_vdec::SendCommandEvent 3536 3537 DESCRIPTION 3538 Send the event to decoder pipe. This is needed to generate the callbacks 3539 in decoder thread context. 3540 3541 PARAMETERS 3542 None. 3543 3544 RETURN VALUE 3545 true/false 3546 3547 ========================================================================== */ 3548 bool omx_vdec::post_event(unsigned long p1, 3549 unsigned long p2, 3550 unsigned long id) 3551 { 3552 bool bRet = false; 3553 3554 /* Just drop messages typically generated by hardware (w/o client request), 3555 * if we've reported an error to client. */ 3556 if (m_error_propogated) { 3557 switch (id) { 3558 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 3559 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 3560 DEBUG_PRINT_ERROR("Dropping message %lx " 3561 "since client expected to be in error state", id); 3562 return false; 3563 default: 3564 /* whatever */ 3565 break; 3566 } 3567 } 3568 3569 pthread_mutex_lock(&m_lock); 3570 3571 if (id == m_fill_output_msg || 3572 id == OMX_COMPONENT_GENERATE_FBD || 3573 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG || 3574 id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) { 3575 m_ftb_q.insert_entry(p1,p2,id); 3576 } else if (id == OMX_COMPONENT_GENERATE_ETB || 3577 id == OMX_COMPONENT_GENERATE_EBD || 3578 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY || 3579 id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) { 3580 m_etb_q.insert_entry(p1,p2,id); 3581 } else { 3582 m_cmd_q.insert_entry(p1,p2,id); 3583 } 3584 3585 bRet = true; 3586 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); 3587 post_message(this, id); 3588 3589 pthread_mutex_unlock(&m_lock); 3590 3591 return bRet; 3592 } 3593 3594 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 3595 { 3596 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3597 if (!profileLevelType) 3598 return OMX_ErrorBadParameter; 3599 3600 if (profileLevelType->nPortIndex == 0) { 3601 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 3602 profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; 3603 if (profileLevelType->nProfileIndex == 0) { 3604 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 3605 } else if (profileLevelType->nProfileIndex == 1) { 3606 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 3607 } else if (profileLevelType->nProfileIndex == 2) { 3608 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 3609 } else if (profileLevelType->nProfileIndex == 3) { 3610 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline; 3611 } else if (profileLevelType->nProfileIndex == 4) { 3612 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 3613 } else if (profileLevelType->nProfileIndex == 5) { 3614 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh; 3615 } else if (profileLevelType->nProfileIndex == 6) { 3616 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh; 3617 } else { 3618 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3619 (unsigned int)profileLevelType->nProfileIndex); 3620 eRet = OMX_ErrorNoMore; 3621 } 3622 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 3623 if (profileLevelType->nProfileIndex == 0) { 3624 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh; 3625 profileLevelType->eLevel = QOMX_VIDEO_MVCLevel51; 3626 } else { 3627 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3628 (unsigned int)profileLevelType->nProfileIndex); 3629 eRet = OMX_ErrorNoMore; 3630 } 3631 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 3632 if (profileLevelType->nProfileIndex == 0) { 3633 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain; 3634 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3635 } else if (profileLevelType->nProfileIndex == 1) { 3636 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10; 3637 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3638 } else if (profileLevelType->nProfileIndex == 2) { 3639 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10HDR10; 3640 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3641 } else { 3642 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3643 (unsigned int)profileLevelType->nProfileIndex); 3644 eRet = OMX_ErrorNoMore; 3645 } 3646 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) { 3647 if (profileLevelType->nProfileIndex == 0) { 3648 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 3649 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 3650 } else { 3651 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3652 (unsigned int)profileLevelType->nProfileIndex); 3653 eRet = OMX_ErrorNoMore; 3654 } 3655 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 3656 if (profileLevelType->nProfileIndex == 0) { 3657 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3658 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3659 } else if (profileLevelType->nProfileIndex == 1) { 3660 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 3661 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3662 } else { 3663 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3664 (unsigned int)profileLevelType->nProfileIndex); 3665 eRet = OMX_ErrorNoMore; 3666 } 3667 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || 3668 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 3669 eRet = OMX_ErrorNoMore; 3670 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 3671 if (profileLevelType->nProfileIndex == 0) { 3672 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; 3673 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3674 } else if (profileLevelType->nProfileIndex == 1) { 3675 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; 3676 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3677 } else { 3678 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3679 (unsigned int)profileLevelType->nProfileIndex); 3680 eRet = OMX_ErrorNoMore; 3681 } 3682 } else { 3683 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind); 3684 eRet = OMX_ErrorNoMore; 3685 } 3686 } else { 3687 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u", 3688 (unsigned int)profileLevelType->nPortIndex); 3689 eRet = OMX_ErrorBadPortIndex; 3690 } 3691 return eRet; 3692 } 3693 3694 /* ====================================================================== 3695 FUNCTION 3696 omx_vdec::GetParameter 3697 3698 DESCRIPTION 3699 OMX Get Parameter method implementation 3700 3701 PARAMETERS 3702 <TBD>. 3703 3704 RETURN VALUE 3705 Error None if successful. 3706 3707 ========================================================================== */ 3708 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 3709 OMX_IN OMX_INDEXTYPE paramIndex, 3710 OMX_INOUT OMX_PTR paramData) 3711 { 3712 (void) hComp; 3713 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3714 3715 DEBUG_PRINT_LOW("get_parameter:"); 3716 if (m_state == OMX_StateInvalid) { 3717 DEBUG_PRINT_ERROR("Get Param in Invalid State"); 3718 return OMX_ErrorInvalidState; 3719 } 3720 if (paramData == NULL) { 3721 DEBUG_PRINT_LOW("Get Param in Invalid paramData"); 3722 return OMX_ErrorBadParameter; 3723 } 3724 switch ((unsigned long)paramIndex) { 3725 case OMX_IndexParamPortDefinition: { 3726 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 3727 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = 3728 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 3729 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition"); 3730 decide_dpb_buffer_mode(is_down_scalar_enabled); 3731 eRet = update_portdef(portDefn); 3732 if (eRet == OMX_ErrorNone) 3733 m_port_def = *portDefn; 3734 break; 3735 } 3736 case OMX_IndexParamVideoInit: { 3737 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3738 OMX_PORT_PARAM_TYPE *portParamType = 3739 (OMX_PORT_PARAM_TYPE *) paramData; 3740 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); 3741 3742 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3743 portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3744 portParamType->nPorts = 2; 3745 portParamType->nStartPortNumber = 0; 3746 break; 3747 } 3748 case OMX_IndexParamVideoPortFormat: { 3749 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 3750 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 3751 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 3752 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); 3753 3754 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 3755 portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); 3756 3757 if (0 == portFmt->nPortIndex) { 3758 if (0 == portFmt->nIndex) { 3759 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 3760 portFmt->eCompressionFormat = eCompressionFormat; 3761 } else { 3762 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3763 " NoMore compression formats"); 3764 eRet = OMX_ErrorNoMore; 3765 } 3766 } else if (1 == portFmt->nPortIndex) { 3767 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 3768 3769 // Distinguish non-surface mode from normal playback use-case based on 3770 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2" 3771 // For non-android, use the default list 3772 // Also use default format-list if FLEXIBLE YUV is supported, 3773 // as the client negotiates the standard color-format if it needs to 3774 bool useNonSurfaceMode = false; 3775 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) 3776 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE); 3777 #endif 3778 if (is_thulium_v1) { 3779 portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex); 3780 } else { 3781 portFmt->eColorFormat = useNonSurfaceMode ? 3782 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) : 3783 getPreferredColorFormatDefaultMode(portFmt->nIndex); 3784 } 3785 3786 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) { 3787 eRet = OMX_ErrorNoMore; 3788 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3789 " NoMore Color formats"); 3790 } 3791 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat); 3792 } else { 3793 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d", 3794 (int)portFmt->nPortIndex); 3795 eRet = OMX_ErrorBadPortIndex; 3796 } 3797 break; 3798 } 3799 /*Component should support this port definition*/ 3800 case OMX_IndexParamAudioInit: { 3801 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3802 OMX_PORT_PARAM_TYPE *audioPortParamType = 3803 (OMX_PORT_PARAM_TYPE *) paramData; 3804 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); 3805 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3806 audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3807 audioPortParamType->nPorts = 0; 3808 audioPortParamType->nStartPortNumber = 0; 3809 break; 3810 } 3811 /*Component should support this port definition*/ 3812 case OMX_IndexParamImageInit: { 3813 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3814 OMX_PORT_PARAM_TYPE *imagePortParamType = 3815 (OMX_PORT_PARAM_TYPE *) paramData; 3816 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); 3817 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3818 imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3819 imagePortParamType->nPorts = 0; 3820 imagePortParamType->nStartPortNumber = 0; 3821 break; 3822 3823 } 3824 /*Component should support this port definition*/ 3825 case OMX_IndexParamOtherInit: { 3826 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x", 3827 paramIndex); 3828 eRet =OMX_ErrorUnsupportedIndex; 3829 break; 3830 } 3831 case OMX_IndexParamStandardComponentRole: { 3832 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 3833 OMX_PARAM_COMPONENTROLETYPE *comp_role; 3834 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 3835 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 3836 comp_role->nSize = sizeof(*comp_role); 3837 3838 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d", 3839 paramIndex); 3840 strlcpy((char*)comp_role->cRole,(const char*)m_cRole, 3841 OMX_MAX_STRINGNAME_SIZE); 3842 break; 3843 } 3844 /* Added for parameter test */ 3845 case OMX_IndexParamPriorityMgmt: { 3846 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 3847 OMX_PRIORITYMGMTTYPE *priorityMgmType = 3848 (OMX_PRIORITYMGMTTYPE *) paramData; 3849 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); 3850 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 3851 priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE); 3852 3853 break; 3854 } 3855 /* Added for parameter test */ 3856 case OMX_IndexParamCompBufferSupplier: { 3857 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 3858 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 3859 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 3860 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); 3861 3862 bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); 3863 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 3864 if (0 == bufferSupplierType->nPortIndex) 3865 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3866 else if (1 == bufferSupplierType->nPortIndex) 3867 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3868 else 3869 eRet = OMX_ErrorBadPortIndex; 3870 3871 3872 break; 3873 } 3874 case OMX_IndexParamVideoAvc: { 3875 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x", 3876 paramIndex); 3877 break; 3878 } 3879 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 3880 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x", 3881 paramIndex); 3882 break; 3883 } 3884 case OMX_IndexParamVideoH263: { 3885 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x", 3886 paramIndex); 3887 break; 3888 } 3889 case OMX_IndexParamVideoMpeg4: { 3890 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x", 3891 paramIndex); 3892 break; 3893 } 3894 case OMX_IndexParamVideoMpeg2: { 3895 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x", 3896 paramIndex); 3897 break; 3898 } 3899 case OMX_IndexParamVideoProfileLevelQuerySupported: { 3900 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3901 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex); 3902 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = 3903 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 3904 eRet = get_supported_profile_level(profileLevelType); 3905 break; 3906 } 3907 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3908 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: { 3909 VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams); 3910 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); 3911 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; 3912 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 3913 3914 if (secure_mode && !secure_scaling_to_non_secure_opb) { 3915 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | 3916 GRALLOC_USAGE_PRIVATE_UNCACHED); 3917 } else { 3918 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED; 3919 } 3920 } else { 3921 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); 3922 eRet = OMX_ErrorBadParameter; 3923 } 3924 } 3925 break; 3926 #endif 3927 3928 #ifdef FLEXYUV_SUPPORTED 3929 case OMX_QcomIndexFlexibleYUVDescription: { 3930 DEBUG_PRINT_LOW("get_parameter: describeColorFormat"); 3931 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams); 3932 eRet = describeColorFormat(paramData); 3933 break; 3934 } 3935 #endif 3936 case OMX_IndexParamVideoProfileLevelCurrent: { 3937 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3938 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 3939 struct v4l2_control profile_control, level_control; 3940 3941 switch (drv_ctx.decoder_format) { 3942 case VDEC_CODECTYPE_H264: 3943 profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 3944 level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 3945 break; 3946 default: 3947 DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264"); 3948 eRet = OMX_ErrorNotImplemented; 3949 break; 3950 } 3951 3952 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) { 3953 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) { 3954 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 3955 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 3956 pParam->eProfile = OMX_VIDEO_AVCProfileBaseline; 3957 break; 3958 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 3959 pParam->eProfile = OMX_VIDEO_AVCProfileMain; 3960 break; 3961 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 3962 pParam->eProfile = OMX_VIDEO_AVCProfileExtended; 3963 break; 3964 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 3965 pParam->eProfile = OMX_VIDEO_AVCProfileHigh; 3966 break; 3967 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 3968 pParam->eProfile = OMX_VIDEO_AVCProfileHigh10; 3969 break; 3970 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 3971 pParam->eProfile = OMX_VIDEO_AVCProfileHigh422; 3972 break; 3973 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 3974 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA: 3975 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA: 3976 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA: 3977 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA: 3978 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE: 3979 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH: 3980 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA: 3981 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH: 3982 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH: 3983 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: 3984 eRet = OMX_ErrorUnsupportedIndex; 3985 break; 3986 } 3987 } else { 3988 eRet = OMX_ErrorUnsupportedIndex; 3989 } 3990 3991 3992 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) { 3993 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) { 3994 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 3995 pParam->eLevel = OMX_VIDEO_AVCLevel1; 3996 break; 3997 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 3998 pParam->eLevel = OMX_VIDEO_AVCLevel1b; 3999 break; 4000 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 4001 pParam->eLevel = OMX_VIDEO_AVCLevel11; 4002 break; 4003 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 4004 pParam->eLevel = OMX_VIDEO_AVCLevel12; 4005 break; 4006 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 4007 pParam->eLevel = OMX_VIDEO_AVCLevel13; 4008 break; 4009 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 4010 pParam->eLevel = OMX_VIDEO_AVCLevel2; 4011 break; 4012 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 4013 pParam->eLevel = OMX_VIDEO_AVCLevel21; 4014 break; 4015 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 4016 pParam->eLevel = OMX_VIDEO_AVCLevel22; 4017 break; 4018 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 4019 pParam->eLevel = OMX_VIDEO_AVCLevel3; 4020 break; 4021 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 4022 pParam->eLevel = OMX_VIDEO_AVCLevel31; 4023 break; 4024 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 4025 pParam->eLevel = OMX_VIDEO_AVCLevel32; 4026 break; 4027 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 4028 pParam->eLevel = OMX_VIDEO_AVCLevel4; 4029 break; 4030 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 4031 pParam->eLevel = OMX_VIDEO_AVCLevel41; 4032 break; 4033 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 4034 pParam->eLevel = OMX_VIDEO_AVCLevel42; 4035 break; 4036 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 4037 pParam->eLevel = OMX_VIDEO_AVCLevel5; 4038 break; 4039 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 4040 pParam->eLevel = OMX_VIDEO_AVCLevel51; 4041 break; 4042 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: 4043 pParam->eLevel = OMX_VIDEO_AVCLevel52; 4044 break; 4045 } 4046 } else { 4047 eRet = OMX_ErrorUnsupportedIndex; 4048 } 4049 4050 break; 4051 4052 } 4053 case OMX_QTIIndexParamVideoClientExtradata: 4054 { 4055 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE); 4056 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata"); 4057 QOMX_EXTRADATA_ENABLE *pParam = 4058 (QOMX_EXTRADATA_ENABLE *)paramData; 4059 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) { 4060 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE; 4061 eRet = OMX_ErrorNone; 4062 } else { 4063 eRet = OMX_ErrorUnsupportedIndex; 4064 } 4065 break; 4066 } 4067 case OMX_QTIIndexParamDitherControl: 4068 { 4069 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL); 4070 DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL"); 4071 QOMX_VIDEO_DITHER_CONTROL *pParam = 4072 (QOMX_VIDEO_DITHER_CONTROL *) paramData; 4073 pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config; 4074 eRet = OMX_ErrorNone; 4075 break; 4076 } 4077 default: { 4078 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex); 4079 eRet =OMX_ErrorUnsupportedIndex; 4080 } 4081 4082 } 4083 4084 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", 4085 drv_ctx.video_resolution.frame_width, 4086 drv_ctx.video_resolution.frame_height, 4087 drv_ctx.video_resolution.stride, 4088 drv_ctx.video_resolution.scan_lines); 4089 4090 return eRet; 4091 } 4092 4093 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 4094 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) 4095 { 4096 DEBUG_PRINT_LOW("Inside use_android_native_buffer"); 4097 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4098 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; 4099 4100 if ((params == NULL) || 4101 (params->nativeBuffer == NULL) || 4102 (params->nativeBuffer->handle == NULL) || 4103 !m_enable_android_native_buffers) 4104 return OMX_ErrorBadParameter; 4105 m_use_android_native_buffers = OMX_TRUE; 4106 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 4107 private_handle_t *handle = (private_handle_t *)nBuf->handle; 4108 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port 4109 OMX_U8 *buffer = NULL; 4110 if (!secure_mode) { 4111 buffer = (OMX_U8*)mmap(0, handle->size, 4112 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 4113 if (buffer == MAP_FAILED) { 4114 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 4115 return OMX_ErrorInsufficientResources; 4116 } 4117 } 4118 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); 4119 } else { 4120 eRet = OMX_ErrorBadParameter; 4121 } 4122 return eRet; 4123 } 4124 #endif 4125 4126 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() { 4127 struct v4l2_control control; 4128 struct v4l2_format fmt; 4129 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; 4130 control.value = 1; 4131 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 4132 if (rc < 0) { 4133 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 4134 return OMX_ErrorHardware; 4135 } 4136 m_smoothstreaming_mode = true; 4137 return OMX_ErrorNone; 4138 } 4139 4140 /* ====================================================================== 4141 FUNCTION 4142 omx_vdec::Setparameter 4143 4144 DESCRIPTION 4145 OMX Set Parameter method implementation. 4146 4147 PARAMETERS 4148 <TBD>. 4149 4150 RETURN VALUE 4151 OMX Error None if successful. 4152 4153 ========================================================================== */ 4154 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 4155 OMX_IN OMX_INDEXTYPE paramIndex, 4156 OMX_IN OMX_PTR paramData) 4157 { 4158 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4159 int ret=0; 4160 struct v4l2_format fmt; 4161 #ifdef _ANDROID_ 4162 char property_value[PROPERTY_VALUE_MAX] = {0}; 4163 #endif 4164 if (m_state == OMX_StateInvalid) { 4165 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 4166 return OMX_ErrorInvalidState; 4167 } 4168 if (paramData == NULL) { 4169 DEBUG_PRINT_ERROR("Get Param in Invalid paramData"); 4170 return OMX_ErrorBadParameter; 4171 } 4172 if ((m_state != OMX_StateLoaded) && 4173 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && 4174 (m_out_bEnabled == OMX_TRUE) && 4175 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && 4176 (m_inp_bEnabled == OMX_TRUE)) { 4177 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 4178 return OMX_ErrorIncorrectStateOperation; 4179 } 4180 switch ((unsigned long)paramIndex) { 4181 case OMX_IndexParamPortDefinition: { 4182 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 4183 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 4184 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 4185 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has 4186 //been called. 4187 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", 4188 (int)portDefn->format.video.nFrameHeight, 4189 (int)portDefn->format.video.nFrameWidth); 4190 4191 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4192 DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d", 4193 portDefn->nBufferCountActual); 4194 eRet = OMX_ErrorBadParameter; 4195 break; 4196 } 4197 if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) { 4198 if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS || 4199 portDefn->nBufferSize != m_client_out_extradata_info.getSize()) { 4200 DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d", 4201 portDefn->nBufferCountActual, portDefn->nBufferSize); 4202 eRet = OMX_ErrorBadParameter; 4203 break; 4204 } 4205 m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize, 4206 portDefn->nBufferCountActual); 4207 break; 4208 } 4209 4210 if (OMX_DirOutput == portDefn->eDir) { 4211 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); 4212 bool port_format_changed = false; 4213 m_display_id = portDefn->format.video.pNativeWindow; 4214 unsigned int buffer_size; 4215 /* update output port resolution with client supplied dimensions 4216 in case scaling is enabled, else it follows input resolution set 4217 */ 4218 decide_dpb_buffer_mode(is_down_scalar_enabled); 4219 if (is_down_scalar_enabled) { 4220 DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)", 4221 (unsigned int)portDefn->format.video.nFrameWidth, 4222 (unsigned int)portDefn->format.video.nFrameHeight); 4223 if (portDefn->format.video.nFrameHeight != 0x0 && 4224 portDefn->format.video.nFrameWidth != 0x0) { 4225 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4226 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4227 fmt.fmt.pix_mp.pixelformat = capture_capability; 4228 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 4229 if (ret) { 4230 DEBUG_PRINT_ERROR("Get Resolution failed"); 4231 eRet = OMX_ErrorHardware; 4232 break; 4233 } 4234 if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) || 4235 (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) { 4236 port_format_changed = true; 4237 } 4238 4239 /* set crop info */ 4240 rectangle.nLeft = 0; 4241 rectangle.nTop = 0; 4242 rectangle.nWidth = portDefn->format.video.nFrameWidth; 4243 rectangle.nHeight = portDefn->format.video.nFrameHeight; 4244 4245 m_extradata_info.output_crop_rect.nLeft = 0; 4246 m_extradata_info.output_crop_rect.nTop = 0; 4247 m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth; 4248 m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight; 4249 4250 eRet = is_video_session_supported(); 4251 if (eRet) 4252 break; 4253 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4254 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4255 fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight; 4256 fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth; 4257 fmt.fmt.pix_mp.pixelformat = capture_capability; 4258 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d", 4259 fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width); 4260 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4261 if (ret) { 4262 DEBUG_PRINT_ERROR("Set Resolution failed"); 4263 eRet = OMX_ErrorUnsupportedSetting; 4264 } else 4265 eRet = get_buffer_req(&drv_ctx.op_buf); 4266 } 4267 4268 if (eRet) { 4269 break; 4270 } 4271 4272 if (secure_mode) { 4273 struct v4l2_control control; 4274 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD; 4275 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 4276 DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id); 4277 eRet = OMX_ErrorHardware; 4278 } else { 4279 /* This is a workaround for a bug in fw which uses stride 4280 * and slice instead of width and height to check against 4281 * the threshold. 4282 */ 4283 OMX_U32 stride, slice; 4284 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 4285 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth); 4286 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight); 4287 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 4288 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth); 4289 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight); 4290 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 4291 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameWidth); 4292 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameHeight); 4293 } else { 4294 stride = portDefn->format.video.nFrameWidth; 4295 slice = portDefn->format.video.nFrameHeight; 4296 } 4297 4298 DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice); 4299 DEBUG_PRINT_LOW("Threshold value is %d\n", control.value); 4300 4301 if (stride * slice <= (OMX_U32)control.value) { 4302 secure_scaling_to_non_secure_opb = true; 4303 DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ"); 4304 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2; 4305 control.value = 1; 4306 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) { 4307 DEBUG_PRINT_ERROR("Enabling non-secure output2 failed"); 4308 eRet = OMX_ErrorUnsupportedSetting; 4309 } 4310 } 4311 } 4312 } 4313 } 4314 4315 if (eRet) { 4316 break; 4317 } 4318 4319 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4320 DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)", 4321 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4322 eRet = OMX_ErrorBadParameter; 4323 } else if (!client_buffers.get_buffer_req(buffer_size)) { 4324 DEBUG_PRINT_ERROR("Error in getting buffer requirements"); 4325 eRet = OMX_ErrorBadParameter; 4326 } else if (!port_format_changed) { 4327 4328 // Buffer count can change only when port is unallocated 4329 if (m_out_mem_ptr && 4330 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount || 4331 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) { 4332 4333 DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !"); 4334 eRet = OMX_ErrorInvalidState; 4335 break; 4336 } 4337 4338 // route updating of buffer requirements via c2d proxy. 4339 // Based on whether c2d is enabled, requirements will be handed 4340 // to the vidc driver appropriately 4341 eRet = client_buffers.set_buffer_req(portDefn->nBufferSize, 4342 portDefn->nBufferCountActual); 4343 if (eRet == OMX_ErrorNone) { 4344 m_port_def = *portDefn; 4345 } else { 4346 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)", 4347 drv_ctx.op_buf.mincount, (unsigned int)buffer_size, 4348 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4349 eRet = OMX_ErrorBadParameter; 4350 } 4351 } 4352 } else if (OMX_DirInput == portDefn->eDir) { 4353 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); 4354 bool port_format_changed = false; 4355 if ((portDefn->format.video.xFramerate >> 16) > 0 && 4356 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) { 4357 // Frame rate only should be set if this is a "known value" or to 4358 // activate ts prediction logic (arbitrary mode only) sending input 4359 // timestamps with max value (LLONG_MAX). 4360 m_fps_received = portDefn->format.video.xFramerate; 4361 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u", 4362 (unsigned int)portDefn->format.video.xFramerate >> 16); 4363 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, 4364 drv_ctx.frame_rate.fps_denominator); 4365 if (!drv_ctx.frame_rate.fps_numerator) { 4366 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 4367 drv_ctx.frame_rate.fps_numerator = 30; 4368 } 4369 if (drv_ctx.frame_rate.fps_denominator) 4370 drv_ctx.frame_rate.fps_numerator = (int) 4371 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 4372 drv_ctx.frame_rate.fps_denominator = 1; 4373 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 4374 drv_ctx.frame_rate.fps_numerator; 4375 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", 4376 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 4377 (float)drv_ctx.frame_rate.fps_denominator); 4378 4379 struct v4l2_outputparm oparm; 4380 /*XXX: we're providing timing info as seconds per frame rather than frames 4381 * per second.*/ 4382 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 4383 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 4384 4385 struct v4l2_streamparm sparm; 4386 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4387 sparm.parm.output = oparm; 4388 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 4389 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected"); 4390 eRet = OMX_ErrorHardware; 4391 break; 4392 } 4393 m_perf_control.request_cores(frm_int); 4394 } 4395 4396 if (drv_ctx.video_resolution.frame_height != 4397 portDefn->format.video.nFrameHeight || 4398 drv_ctx.video_resolution.frame_width != 4399 portDefn->format.video.nFrameWidth) { 4400 DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)", 4401 (unsigned int)portDefn->format.video.nFrameWidth, 4402 (unsigned int)portDefn->format.video.nFrameHeight); 4403 port_format_changed = true; 4404 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth; 4405 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight; 4406 if (frameHeight != 0x0 && frameWidth != 0x0) { 4407 if (m_smoothstreaming_mode && 4408 ((frameWidth * frameHeight) < 4409 (m_smoothstreaming_width * m_smoothstreaming_height))) { 4410 frameWidth = m_smoothstreaming_width; 4411 frameHeight = m_smoothstreaming_height; 4412 DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u " 4413 "for adaptive-playback/smooth-streaming", 4414 (unsigned int)frameWidth, (unsigned int)frameHeight); 4415 } 4416 4417 m_extradata_info.output_crop_rect.nLeft = 0; 4418 m_extradata_info.output_crop_rect.nTop = 0; 4419 m_extradata_info.output_crop_rect.nWidth = frameWidth; 4420 m_extradata_info.output_crop_rect.nHeight = frameHeight; 4421 4422 update_resolution(frameWidth, frameHeight, 4423 frameWidth, frameHeight); 4424 eRet = is_video_session_supported(); 4425 if (eRet) 4426 break; 4427 if (is_down_scalar_enabled) { 4428 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4429 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4430 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4431 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4432 fmt.fmt.pix_mp.pixelformat = output_capability; 4433 DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d", 4434 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 4435 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4436 } else { 4437 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4438 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4439 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4440 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4441 fmt.fmt.pix_mp.pixelformat = output_capability; 4442 DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d", 4443 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 4444 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4445 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4446 fmt.fmt.pix_mp.pixelformat = capture_capability; 4447 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4448 } 4449 if (ret) { 4450 DEBUG_PRINT_ERROR("Set Resolution failed"); 4451 eRet = OMX_ErrorUnsupportedSetting; 4452 } else { 4453 if (!is_down_scalar_enabled) 4454 eRet = get_buffer_req(&drv_ctx.op_buf); 4455 } 4456 } 4457 } 4458 if (m_custom_buffersize.input_buffersize 4459 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) { 4460 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d", 4461 m_custom_buffersize.input_buffersize, portDefn->nBufferSize); 4462 eRet = OMX_ErrorBadParameter; 4463 break; 4464 } 4465 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4466 DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)", 4467 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4468 eRet = OMX_ErrorBadParameter; 4469 break; 4470 } 4471 // Buffer count can change only when port is unallocated 4472 if (m_inp_mem_ptr && 4473 (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount || 4474 portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) { 4475 DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !"); 4476 eRet = OMX_ErrorInvalidState; 4477 break; 4478 } 4479 4480 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount 4481 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) { 4482 port_format_changed = true; 4483 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; 4484 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; 4485 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & 4486 (~(buffer_prop->alignment - 1)); 4487 eRet = set_buffer_req(buffer_prop); 4488 } 4489 if (false == port_format_changed) { 4490 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)", 4491 drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size, 4492 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4493 eRet = OMX_ErrorBadParameter; 4494 } 4495 } else if (portDefn->eDir == OMX_DirMax) { 4496 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 4497 (int)portDefn->nPortIndex); 4498 eRet = OMX_ErrorBadPortIndex; 4499 } 4500 } 4501 break; 4502 case OMX_IndexParamVideoPortFormat: { 4503 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 4504 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 4505 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 4506 int ret=0; 4507 struct v4l2_format fmt; 4508 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u", 4509 portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex); 4510 4511 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4512 if (1 == portFmt->nPortIndex) { 4513 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4514 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 4515 if (ret < 0) { 4516 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 4517 return OMX_ErrorBadParameter; 4518 } 4519 enum vdec_output_fromat op_format; 4520 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4521 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m || 4522 portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4523 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView || 4524 portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar || 4525 portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 4526 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; 4527 } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4528 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4529 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC; 4530 } else 4531 eRet = OMX_ErrorBadParameter; 4532 4533 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4534 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4535 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC; 4536 } else { 4537 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12; 4538 } 4539 4540 if (eRet == OMX_ErrorNone) { 4541 drv_ctx.output_format = op_format; 4542 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4543 if (ret) { 4544 DEBUG_PRINT_ERROR("Set output format failed"); 4545 eRet = OMX_ErrorUnsupportedSetting; 4546 /*TODO: How to handle this case */ 4547 } else { 4548 eRet = get_buffer_req(&drv_ctx.op_buf); 4549 } 4550 } 4551 if (eRet == OMX_ErrorNone) { 4552 if (!client_buffers.set_color_format(portFmt->eColorFormat)) { 4553 DEBUG_PRINT_ERROR("Set color format failed"); 4554 eRet = OMX_ErrorBadParameter; 4555 } 4556 } 4557 } 4558 } 4559 break; 4560 4561 case OMX_QcomIndexPortDefn: { 4562 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE); 4563 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 4564 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 4565 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u", 4566 (unsigned int)portFmt->nFramePackingFormat); 4567 4568 /* Input port */ 4569 if (portFmt->nPortIndex == 0) { 4570 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how: 4571 // - headers are allocated and 4572 // - headers-indices are derived 4573 // Avoid changing arbitrary_bytes when the port is already allocated 4574 if (m_inp_mem_ptr) { 4575 DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!"); 4576 return OMX_ErrorUnsupportedSetting; 4577 } 4578 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) { 4579 if (secure_mode || m_input_pass_buffer_fd) { 4580 arbitrary_bytes = false; 4581 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode"); 4582 eRet = OMX_ErrorUnsupportedSetting; 4583 } else { 4584 arbitrary_bytes = true; 4585 } 4586 } else if (portFmt->nFramePackingFormat == 4587 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) { 4588 arbitrary_bytes = false; 4589 #ifdef _ANDROID_ 4590 property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 4591 if (atoi(property_value)) { 4592 DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command"); 4593 arbitrary_bytes = true; 4594 } 4595 #endif 4596 } else { 4597 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u", 4598 (unsigned int)portFmt->nFramePackingFormat); 4599 eRet = OMX_ErrorUnsupportedSetting; 4600 } 4601 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 4602 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); 4603 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && 4604 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && 4605 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) { 4606 m_out_mem_region_smi = OMX_TRUE; 4607 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4608 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set"); 4609 m_use_output_pmem = OMX_TRUE; 4610 } 4611 } 4612 } 4613 } 4614 if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 4615 OMX_MAX_STRINGNAME_SIZE)) { 4616 arbitrary_bytes = true; 4617 DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264"); 4618 } 4619 break; 4620 4621 case OMX_QTIIndexParamVideoClientExtradata: { 4622 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE); 4623 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata"); 4624 QOMX_EXTRADATA_ENABLE *pParam = 4625 (QOMX_EXTRADATA_ENABLE *)paramData; 4626 4627 if (m_state != OMX_StateLoaded) { 4628 DEBUG_PRINT_ERROR("Set Parameter called in Invalid state"); 4629 return OMX_ErrorIncorrectStateOperation; 4630 } 4631 4632 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) { 4633 m_client_out_extradata_info.enable_client_extradata(pParam->bEnable); 4634 } else { 4635 DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex); 4636 eRet = OMX_ErrorUnsupportedIndex; 4637 } 4638 break; 4639 } 4640 case OMX_IndexParamStandardComponentRole: { 4641 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 4642 OMX_PARAM_COMPONENTROLETYPE *comp_role; 4643 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 4644 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", 4645 comp_role->cRole); 4646 4647 if ((m_state == OMX_StateLoaded)&& 4648 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) { 4649 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 4650 } else { 4651 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4652 return OMX_ErrorIncorrectStateOperation; 4653 } 4654 4655 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4656 if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4657 strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE); 4658 } else { 4659 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4660 eRet =OMX_ErrorUnsupportedSetting; 4661 } 4662 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4663 if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4664 strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 4665 } else { 4666 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4667 eRet = OMX_ErrorUnsupportedSetting; 4668 } 4669 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4670 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4671 strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE); 4672 } else { 4673 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4674 eRet = OMX_ErrorUnsupportedSetting; 4675 } 4676 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4677 if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4678 strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE); 4679 } else { 4680 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4681 eRet =OMX_ErrorUnsupportedSetting; 4682 } 4683 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4684 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4685 strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE); 4686 } else { 4687 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4688 eRet = OMX_ErrorUnsupportedSetting; 4689 } 4690 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) || 4691 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) || 4692 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE)) 4693 ) { 4694 if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) { 4695 strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE); 4696 } else { 4697 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4698 eRet =OMX_ErrorUnsupportedSetting; 4699 } 4700 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) || 4701 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) 4702 ) { 4703 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 4704 strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE); 4705 } else { 4706 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4707 eRet =OMX_ErrorUnsupportedSetting; 4708 } 4709 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 4710 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 4711 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4712 strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE); 4713 } else { 4714 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4715 eRet = OMX_ErrorUnsupportedSetting; 4716 } 4717 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 4718 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) || 4719 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4720 strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE); 4721 } else { 4722 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4723 eRet = OMX_ErrorUnsupportedSetting; 4724 } 4725 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4726 if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4727 strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 4728 } else { 4729 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4730 eRet = OMX_ErrorUnsupportedSetting; 4731 } 4732 } else { 4733 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind); 4734 eRet = OMX_ErrorInvalidComponentName; 4735 } 4736 break; 4737 } 4738 4739 case OMX_IndexParamPriorityMgmt: { 4740 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 4741 if (m_state != OMX_StateLoaded) { 4742 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4743 return OMX_ErrorIncorrectStateOperation; 4744 } 4745 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 4746 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u", 4747 (unsigned int)priorityMgmtype->nGroupID); 4748 4749 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u", 4750 (unsigned int)priorityMgmtype->nGroupPriority); 4751 4752 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 4753 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 4754 4755 break; 4756 } 4757 4758 case OMX_IndexParamCompBufferSupplier: { 4759 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 4760 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 4761 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d", 4762 bufferSupplierType->eBufferSupplier); 4763 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 4764 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 4765 4766 else 4767 4768 eRet = OMX_ErrorBadPortIndex; 4769 4770 break; 4771 4772 } 4773 case OMX_IndexParamVideoAvc: { 4774 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d", 4775 paramIndex); 4776 break; 4777 } 4778 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 4779 DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d", 4780 paramIndex); 4781 break; 4782 } 4783 case OMX_IndexParamVideoH263: { 4784 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d", 4785 paramIndex); 4786 break; 4787 } 4788 case OMX_IndexParamVideoMpeg4: { 4789 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d", 4790 paramIndex); 4791 break; 4792 } 4793 case OMX_IndexParamVideoMpeg2: { 4794 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d", 4795 paramIndex); 4796 break; 4797 } 4798 case OMX_QTIIndexParamLowLatencyMode: { 4799 struct v4l2_control control; 4800 int rc = 0; 4801 QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam = 4802 (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData; 4803 if (pParam->bLowLatencyMode) { 4804 DEBUG_PRINT_HIGH("Enabling DECODE order"); 4805 time_stamp_dts.set_timestamp_reorder_mode(false); 4806 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4807 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4808 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4809 if (rc) { 4810 DEBUG_PRINT_ERROR("Set picture order failed"); 4811 eRet = OMX_ErrorUnsupportedSetting; 4812 } 4813 } 4814 break; 4815 } 4816 case OMX_QcomIndexParamVideoDecoderPictureOrder: { 4817 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER); 4818 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = 4819 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; 4820 struct v4l2_control control; 4821 int pic_order,rc=0; 4822 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d", 4823 pictureOrder->eOutputPictureOrder); 4824 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { 4825 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 4826 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) { 4827 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4828 time_stamp_dts.set_timestamp_reorder_mode(false); 4829 } else 4830 eRet = OMX_ErrorBadParameter; 4831 if (eRet == OMX_ErrorNone) { 4832 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4833 control.value = pic_order; 4834 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4835 if (rc) { 4836 DEBUG_PRINT_ERROR("Set picture order failed"); 4837 eRet = OMX_ErrorUnsupportedSetting; 4838 } 4839 } 4840 m_decode_order_mode = 4841 pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER; 4842 break; 4843 } 4844 case OMX_QcomIndexParamConcealMBMapExtraData: 4845 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4846 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, 4847 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4848 break; 4849 case OMX_QcomIndexParamFrameInfoExtraData: 4850 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4851 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 4852 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4853 break; 4854 case OMX_ExtraDataFrameDimension: 4855 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4856 eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false, 4857 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4858 break; 4859 case OMX_QcomIndexParamInterlaceExtraData: 4860 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4861 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, 4862 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4863 break; 4864 case OMX_QcomIndexParamH264TimeInfo: 4865 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4866 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, 4867 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4868 break; 4869 case OMX_QcomIndexParamVideoFramePackingExtradata: 4870 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4871 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false, 4872 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4873 break; 4874 case OMX_QcomIndexParamVideoQPExtraData: 4875 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4876 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 4877 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4878 break; 4879 case OMX_QcomIndexParamVideoInputBitsInfoExtraData: 4880 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4881 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false, 4882 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4883 break; 4884 case OMX_QcomIndexEnableExtnUserData: 4885 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4886 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false, 4887 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4888 break; 4889 case OMX_QTIIndexParamVQZipSEIExtraData: 4890 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4891 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 4892 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4893 break; 4894 case OMX_QcomIndexParamVideoDivx: { 4895 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; 4896 } 4897 break; 4898 case OMX_QcomIndexPlatformPvt: { 4899 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN); 4900 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); 4901 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; 4902 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 4903 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); 4904 eRet = OMX_ErrorUnsupportedSetting; 4905 } else { 4906 m_out_pvt_entry_pmem = OMX_TRUE; 4907 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4908 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set"); 4909 m_use_output_pmem = OMX_TRUE; 4910 } 4911 } 4912 4913 } 4914 break; 4915 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: { 4916 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); 4917 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); 4918 struct v4l2_control control; 4919 int rc; 4920 drv_ctx.idr_only_decoding = 1; 4921 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4922 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4923 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4924 if (rc) { 4925 DEBUG_PRINT_ERROR("Set picture order failed"); 4926 eRet = OMX_ErrorUnsupportedSetting; 4927 } else { 4928 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; 4929 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; 4930 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4931 if (rc) { 4932 DEBUG_PRINT_ERROR("Sync frame setting failed"); 4933 eRet = OMX_ErrorUnsupportedSetting; 4934 } 4935 /*Setting sync frame decoding on driver might change buffer 4936 * requirements so update them here*/ 4937 if (get_buffer_req(&drv_ctx.ip_buf)) { 4938 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements"); 4939 eRet = OMX_ErrorUnsupportedSetting; 4940 } 4941 if (get_buffer_req(&drv_ctx.op_buf)) { 4942 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements"); 4943 eRet = OMX_ErrorUnsupportedSetting; 4944 } 4945 } 4946 } 4947 break; 4948 4949 case OMX_QcomIndexParamIndexExtraDataType: { 4950 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE); 4951 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; 4952 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && 4953 (extradataIndexType->bEnabled == OMX_TRUE) && 4954 (extradataIndexType->nPortIndex == 1)) { 4955 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); 4956 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); 4957 4958 } 4959 } 4960 break; 4961 case OMX_QcomIndexParamEnableSmoothStreaming: { 4962 #ifndef SMOOTH_STREAMING_DISABLED 4963 eRet = enable_smoothstreaming(); 4964 #else 4965 eRet = OMX_ErrorUnsupportedSetting; 4966 #endif 4967 } 4968 break; 4969 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 4970 /* Need to allow following two set_parameters even in Idle 4971 * state. This is ANDROID architecture which is not in sync 4972 * with openmax standard. */ 4973 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: { 4974 VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams); 4975 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; 4976 if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 4977 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!"); 4978 eRet = OMX_ErrorUnsupportedSetting; 4979 break; 4980 } else if (m_out_mem_ptr) { 4981 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !"); 4982 eRet = OMX_ErrorInvalidState; 4983 break; 4984 } 4985 if (enableNativeBuffers) { 4986 m_enable_android_native_buffers = enableNativeBuffers->enable; 4987 } 4988 #if !defined(FLEXYUV_SUPPORTED) 4989 if (m_enable_android_native_buffers) { 4990 // Use the most-preferred-native-color-format as surface-mode is hinted here 4991 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) { 4992 DEBUG_PRINT_ERROR("Failed to set native color format!"); 4993 eRet = OMX_ErrorUnsupportedSetting; 4994 } 4995 } 4996 #endif 4997 } 4998 break; 4999 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: { 5000 VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams); 5001 eRet = use_android_native_buffer(hComp, paramData); 5002 } 5003 break; 5004 #if ALLOCATE_OUTPUT_NATIVEHANDLE 5005 case OMX_GoogleAndroidIndexAllocateNativeHandle: { 5006 5007 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData; 5008 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams); 5009 5010 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 5011 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!"); 5012 eRet = OMX_ErrorUnsupportedSetting; 5013 break; 5014 } else if (m_inp_mem_ptr) { 5015 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !"); 5016 eRet = OMX_ErrorInvalidState; 5017 break; 5018 } 5019 5020 if (allocateNativeHandleParams != NULL) { 5021 allocate_native_handle = allocateNativeHandleParams->enable; 5022 } 5023 } 5024 break; 5025 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE 5026 #endif 5027 case OMX_QcomIndexParamEnableTimeStampReorder: { 5028 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER); 5029 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; 5030 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { 5031 if (reorder->bEnable == OMX_TRUE) { 5032 frm_int =0; 5033 time_stamp_dts.set_timestamp_reorder_mode(true); 5034 } else 5035 time_stamp_dts.set_timestamp_reorder_mode(false); 5036 } else { 5037 time_stamp_dts.set_timestamp_reorder_mode(false); 5038 if (reorder->bEnable == OMX_TRUE) { 5039 eRet = OMX_ErrorUnsupportedSetting; 5040 } 5041 } 5042 } 5043 break; 5044 case OMX_IndexParamVideoProfileLevelCurrent: { 5045 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 5046 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = 5047 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 5048 if (pParam) { 5049 m_profile_lvl.eProfile = pParam->eProfile; 5050 m_profile_lvl.eLevel = pParam->eLevel; 5051 } 5052 break; 5053 5054 } 5055 case OMX_QcomIndexParamVideoMetaBufferMode: 5056 { 5057 VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams); 5058 StoreMetaDataInBuffersParams *metabuffer = 5059 (StoreMetaDataInBuffersParams *)paramData; 5060 if (!metabuffer) { 5061 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer); 5062 eRet = OMX_ErrorBadParameter; 5063 break; 5064 } 5065 if (m_disable_dynamic_buf_mode) { 5066 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled"); 5067 eRet = OMX_ErrorUnsupportedSetting; 5068 break; 5069 } 5070 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 5071 5072 if (m_out_mem_ptr) { 5073 DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !"); 5074 eRet = OMX_ErrorInvalidState; 5075 break; 5076 } 5077 //set property dynamic buffer mode to driver. 5078 struct v4l2_control control; 5079 struct v4l2_format fmt; 5080 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT; 5081 if (metabuffer->bStoreMetaData == true) { 5082 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC; 5083 } else { 5084 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC; 5085 } 5086 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 5087 if (!rc) { 5088 DEBUG_PRINT_HIGH("%s buffer mode", 5089 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic"); 5090 } else { 5091 DEBUG_PRINT_ERROR("Failed to %s buffer mode", 5092 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic"); 5093 } 5094 dynamic_buf_mode = metabuffer->bStoreMetaData; 5095 } else { 5096 DEBUG_PRINT_ERROR( 5097 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u", 5098 (unsigned int)metabuffer->nPortIndex); 5099 eRet = OMX_ErrorUnsupportedSetting; 5100 } 5101 break; 5102 } 5103 case OMX_QcomIndexParamVideoDownScalar: 5104 { 5105 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR); 5106 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData; 5107 struct v4l2_control control; 5108 int rc; 5109 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable); 5110 5111 if (pParam && pParam->bEnable) { 5112 rc = enable_downscalar(); 5113 if (rc < 0) { 5114 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 5115 return OMX_ErrorUnsupportedSetting; 5116 } 5117 m_force_down_scalar = pParam->bEnable; 5118 } else { 5119 rc = disable_downscalar(); 5120 if (rc < 0) { 5121 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 5122 return OMX_ErrorUnsupportedSetting; 5123 } 5124 m_force_down_scalar = pParam->bEnable; 5125 } 5126 break; 5127 } 5128 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 5129 case OMX_QcomIndexParamVideoAdaptivePlaybackMode: 5130 { 5131 VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams); 5132 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback"); 5133 PrepareForAdaptivePlaybackParams* pParams = 5134 (PrepareForAdaptivePlaybackParams *) paramData; 5135 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 5136 if (!pParams->bEnable) { 5137 return OMX_ErrorNone; 5138 } 5139 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth 5140 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) { 5141 DEBUG_PRINT_ERROR( 5142 "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]", 5143 (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight, 5144 (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight); 5145 eRet = OMX_ErrorBadParameter; 5146 } else { 5147 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight); 5148 } 5149 } else { 5150 DEBUG_PRINT_ERROR( 5151 "Prepare for adaptive playback supported only on output port"); 5152 eRet = OMX_ErrorBadParameter; 5153 } 5154 break; 5155 } 5156 5157 case OMX_QTIIndexParamVideoPreferAdaptivePlayback: 5158 { 5159 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 5160 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback"); 5161 m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable; 5162 if (m_disable_dynamic_buf_mode) { 5163 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set"); 5164 } 5165 break; 5166 } 5167 #endif 5168 case OMX_QcomIndexParamVideoCustomBufferSize: 5169 { 5170 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE); 5171 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize"); 5172 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData; 5173 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 5174 struct v4l2_control control; 5175 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT; 5176 control.value = pParam->nBufferSize; 5177 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5178 DEBUG_PRINT_ERROR("Failed to set input buffer size"); 5179 eRet = OMX_ErrorUnsupportedSetting; 5180 } else { 5181 eRet = get_buffer_req(&drv_ctx.ip_buf); 5182 if (eRet == OMX_ErrorNone) { 5183 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size; 5184 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d", 5185 m_custom_buffersize.input_buffersize); 5186 } else { 5187 DEBUG_PRINT_ERROR("Failed to get buffer requirement"); 5188 } 5189 } 5190 } else { 5191 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port"); 5192 eRet = OMX_ErrorBadParameter; 5193 } 5194 break; 5195 } 5196 case OMX_QTIIndexParamVQZIPSEIType: 5197 { 5198 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE); 5199 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType"); 5200 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam = 5201 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData; 5202 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable); 5203 5204 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 5205 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5206 if (eRet != OMX_ErrorNone) { 5207 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata"); 5208 eRet = OMX_ErrorBadParameter; 5209 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5210 break; 5211 } 5212 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 5213 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5214 if (eRet != OMX_ErrorNone) { 5215 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata"); 5216 eRet = OMX_ErrorBadParameter; 5217 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5218 client_extradata = client_extradata & ~OMX_QP_EXTRADATA; 5219 break; 5220 } 5221 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 5222 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5223 if (eRet != OMX_ErrorNone) { 5224 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata"); 5225 eRet = OMX_ErrorBadParameter; 5226 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5227 client_extradata = client_extradata & ~OMX_QP_EXTRADATA; 5228 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA; 5229 } 5230 break; 5231 } 5232 case OMX_QTIIndexParamPassInputBufferFd: 5233 { 5234 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 5235 if (arbitrary_bytes) { 5236 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode"); 5237 eRet = OMX_ErrorUnsupportedSetting; 5238 break; 5239 } 5240 5241 m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable; 5242 if (m_input_pass_buffer_fd) 5243 DEBUG_PRINT_LOW("Enable passing input buffer FD"); 5244 break; 5245 } 5246 case OMX_QTIIndexParamForceCompressedForDPB: 5247 { 5248 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE); 5249 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB"); 5250 OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam = 5251 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData; 5252 if (m_disable_ubwc_mode) { 5253 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled"); 5254 eRet = OMX_ErrorUnsupportedSetting; 5255 break; 5256 } 5257 if (!paramData) { 5258 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL"); 5259 eRet = OMX_ErrorBadParameter; 5260 break; 5261 } 5262 5263 m_force_compressed_for_dpb = pParam->bEnable; 5264 break; 5265 } 5266 case OMX_QTIIndexParamForceUnCompressedForOPB: 5267 { 5268 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB"); 5269 OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam = 5270 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData; 5271 if (!paramData) { 5272 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL"); 5273 eRet = OMX_ErrorBadParameter; 5274 break; 5275 } 5276 m_disable_ubwc_mode = pParam->bEnable; 5277 DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled"); 5278 break; 5279 } 5280 case OMX_QTIIndexParamDitherControl: 5281 { 5282 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL); 5283 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl"); 5284 QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData; 5285 DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType); 5286 if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) || 5287 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) { 5288 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range"); 5289 eRet = OMX_ErrorBadParameter; 5290 break; 5291 } 5292 m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE; 5293 DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config); 5294 break; 5295 } 5296 default: { 5297 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex); 5298 eRet = OMX_ErrorUnsupportedIndex; 5299 } 5300 } 5301 if (eRet != OMX_ErrorNone) 5302 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex); 5303 return eRet; 5304 } 5305 5306 /* ====================================================================== 5307 FUNCTION 5308 omx_vdec::GetConfig 5309 5310 DESCRIPTION 5311 OMX Get Config Method implementation. 5312 5313 PARAMETERS 5314 <TBD>. 5315 5316 RETURN VALUE 5317 OMX Error None if successful. 5318 5319 ========================================================================== */ 5320 OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 5321 OMX_IN OMX_INDEXTYPE configIndex, 5322 OMX_INOUT OMX_PTR configData) 5323 { 5324 (void) hComp; 5325 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5326 5327 if (m_state == OMX_StateInvalid) { 5328 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 5329 return OMX_ErrorInvalidState; 5330 } 5331 5332 switch ((unsigned long)configIndex) { 5333 case OMX_QcomIndexConfigInterlaced: { 5334 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE); 5335 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 5336 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 5337 if (configFmt->nPortIndex == 1) { 5338 if (configFmt->nIndex == 0) { 5339 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 5340 } else if (configFmt->nIndex == 1) { 5341 configFmt->eInterlaceType = 5342 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 5343 } else if (configFmt->nIndex == 2) { 5344 configFmt->eInterlaceType = 5345 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 5346 } else { 5347 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 5348 " NoMore Interlaced formats"); 5349 eRet = OMX_ErrorNoMore; 5350 } 5351 5352 } else { 5353 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port", 5354 (int)configFmt->nPortIndex); 5355 eRet = OMX_ErrorBadPortIndex; 5356 } 5357 break; 5358 } 5359 case OMX_QcomIndexQueryNumberOfVideoDecInstance: { 5360 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES); 5361 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 5362 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 5363 decoderinstances->nNumOfInstances = 16; 5364 /*TODO: How to handle this case */ 5365 break; 5366 } 5367 case OMX_QcomIndexConfigVideoFramePackingArrangement: { 5368 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) { 5369 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT); 5370 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = 5371 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; 5372 memcpy(configFmt, &m_frame_pack_arrangement, 5373 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 5374 } else { 5375 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); 5376 } 5377 break; 5378 } 5379 case OMX_IndexConfigCommonOutputCrop: { 5380 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE); 5381 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; 5382 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); 5383 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u", 5384 rectangle.nLeft, rectangle.nTop, 5385 rectangle.nWidth, rectangle.nHeight); 5386 break; 5387 } 5388 case OMX_QcomIndexConfigPerfLevel: { 5389 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); 5390 struct v4l2_control control; 5391 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 5392 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 5393 5394 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5395 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 5396 DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno); 5397 eRet = OMX_ErrorHardware; 5398 } 5399 5400 if (eRet == OMX_ErrorNone) { 5401 switch (control.value) { 5402 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO: 5403 perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo; 5404 break; 5405 default: 5406 DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value); 5407 /* Fall through */ 5408 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL: 5409 perf->ePerfLevel = OMX_QCOM_PerfLevelNominal; 5410 break; 5411 } 5412 } 5413 5414 break; 5415 } 5416 case OMX_QcomIndexConfigH264EntropyCodingCabac: { 5417 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE); 5418 QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData; 5419 struct v4l2_control control; 5420 5421 if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) { 5422 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264"); 5423 eRet = OMX_ErrorNotImplemented; 5424 break; 5425 } 5426 5427 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 5428 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) { 5429 coding->bCabac = (OMX_BOOL) 5430 (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC); 5431 /* We can't query driver at the moment for the cabac mode, so 5432 * just use 0xff...f as a place holder for future improvement */ 5433 coding->nCabacInitIdc = ~0; 5434 } else { 5435 eRet = OMX_ErrorUnsupportedIndex; 5436 } 5437 5438 break; 5439 } 5440 case OMX_QTIIndexConfigDescribeColorAspects: 5441 { 5442 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5443 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5444 5445 if (params->bRequestingDataSpace) { 5446 DEBUG_PRINT_HIGH("Does not handle dataspace request"); 5447 return OMX_ErrorUnsupportedSetting; 5448 } 5449 5450 print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client"); 5451 print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal"); 5452 5453 // For VPX, use client-color if specified. 5454 // For the rest, try to use the stream-color if present 5455 bool preferClientColor = (output_capability == V4L2_PIX_FMT_VP8 || 5456 output_capability == V4L2_PIX_FMT_VP9); 5457 5458 const ColorAspects &preferredColor = preferClientColor ? 5459 m_client_color_space.sAspects : m_internal_color_space.sAspects; 5460 const ColorAspects &defaultColor = preferClientColor ? 5461 m_internal_color_space.sAspects : m_client_color_space.sAspects; 5462 5463 params->sAspects.mPrimaries = preferredColor.mPrimaries != ColorAspects::PrimariesUnspecified ? 5464 preferredColor.mPrimaries : defaultColor.mPrimaries; 5465 params->sAspects.mTransfer = preferredColor.mTransfer != ColorAspects::TransferUnspecified ? 5466 preferredColor.mTransfer : defaultColor.mTransfer; 5467 params->sAspects.mMatrixCoeffs = preferredColor.mMatrixCoeffs != ColorAspects::MatrixUnspecified ? 5468 preferredColor.mMatrixCoeffs : defaultColor.mMatrixCoeffs; 5469 params->sAspects.mRange = preferredColor.mRange != ColorAspects::RangeUnspecified ? 5470 preferredColor.mRange : defaultColor.mRange; 5471 5472 print_debug_color_aspects(&(params->sAspects), "GetConfig"); 5473 5474 break; 5475 } 5476 case OMX_QTIIndexConfigDescribeHDRColorInfo: 5477 { 5478 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams); 5479 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData; 5480 auto_lock lock(m_hdr_info_client_lock); 5481 5482 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR"); 5483 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR"); 5484 5485 if (m_change_client_hdr_info) { 5486 DEBUG_PRINT_LOW("Updating Client's HDR Info with internal"); 5487 memcpy(&m_client_hdr_info.sInfo, 5488 &m_internal_hdr_info.sInfo, sizeof(HDRStaticInfo)); 5489 m_change_client_hdr_info = false; 5490 } 5491 5492 memcpy(&(params->sInfo), &(m_client_hdr_info.sInfo), sizeof(HDRStaticInfo)); 5493 5494 break; 5495 } 5496 case OMX_IndexConfigAndroidVendorExtension: 5497 { 5498 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); 5499 5500 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = 5501 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); 5502 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); 5503 return get_vendor_extension_config(ext); 5504 } 5505 default: 5506 { 5507 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex); 5508 eRet = OMX_ErrorBadParameter; 5509 } 5510 5511 } 5512 5513 return eRet; 5514 } 5515 5516 /* ====================================================================== 5517 FUNCTION 5518 omx_vdec::SetConfig 5519 5520 DESCRIPTION 5521 OMX Set Config method implementation 5522 5523 PARAMETERS 5524 <TBD>. 5525 5526 RETURN VALUE 5527 OMX Error None if successful. 5528 ========================================================================== */ 5529 OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 5530 OMX_IN OMX_INDEXTYPE configIndex, 5531 OMX_IN OMX_PTR configData) 5532 { 5533 (void) hComp; 5534 if (m_state == OMX_StateInvalid) { 5535 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 5536 return OMX_ErrorInvalidState; 5537 } 5538 5539 OMX_ERRORTYPE ret = OMX_ErrorNone; 5540 OMX_VIDEO_CONFIG_NALSIZE *pNal; 5541 5542 DEBUG_PRINT_LOW("Set Config Called"); 5543 5544 if (configIndex == OMX_IndexConfigVideoNalSize) { 5545 struct v4l2_control temp; 5546 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT; 5547 5548 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE); 5549 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 5550 switch (pNal->nNaluBytes) { 5551 case 0: 5552 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES; 5553 break; 5554 case 2: 5555 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH; 5556 break; 5557 case 4: 5558 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH; 5559 break; 5560 default: 5561 return OMX_ErrorUnsupportedSetting; 5562 } 5563 5564 if (!arbitrary_bytes) { 5565 /* In arbitrary bytes mode, the assembler strips out nal size and replaces 5566 * with start code, so only need to notify driver in frame by frame mode */ 5567 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) { 5568 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT"); 5569 return OMX_ErrorHardware; 5570 } 5571 } 5572 5573 nal_length = pNal->nNaluBytes; 5574 m_frame_parser.init_nal_length(nal_length); 5575 5576 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length); 5577 return ret; 5578 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) { 5579 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData; 5580 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps); 5581 5582 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 5583 if (config->bEnabled) { 5584 if ((config->nFps >> 16) > 0 && 5585 (config->nFps >> 16) <= MAX_SUPPORTED_FPS) { 5586 m_fps_received = config->nFps; 5587 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u", 5588 (unsigned int)config->nFps >> 16); 5589 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator, 5590 drv_ctx.frame_rate.fps_denominator); 5591 5592 if (!drv_ctx.frame_rate.fps_numerator) { 5593 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 5594 drv_ctx.frame_rate.fps_numerator = 30; 5595 } 5596 5597 if (drv_ctx.frame_rate.fps_denominator) { 5598 drv_ctx.frame_rate.fps_numerator = (int) 5599 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 5600 } 5601 5602 drv_ctx.frame_rate.fps_denominator = 1; 5603 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 5604 drv_ctx.frame_rate.fps_numerator; 5605 5606 struct v4l2_outputparm oparm; 5607 /*XXX: we're providing timing info as seconds per frame rather than frames 5608 * per second.*/ 5609 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 5610 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 5611 5612 struct v4l2_streamparm sparm; 5613 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5614 sparm.parm.output = oparm; 5615 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 5616 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 5617 performance might be affected"); 5618 ret = OMX_ErrorHardware; 5619 } 5620 client_set_fps = true; 5621 } else { 5622 DEBUG_PRINT_ERROR("Frame rate not supported."); 5623 ret = OMX_ErrorUnsupportedSetting; 5624 } 5625 } else { 5626 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate"); 5627 client_set_fps = false; 5628 } 5629 } else { 5630 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d", 5631 (int)config->nPortIndex); 5632 ret = OMX_ErrorBadPortIndex; 5633 } 5634 5635 return ret; 5636 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) { 5637 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 5638 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 5639 struct v4l2_control control; 5640 5641 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel); 5642 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5643 5644 switch (perf->ePerfLevel) { 5645 case OMX_QCOM_PerfLevelNominal: 5646 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 5647 m_need_turbo &= ~TURBO_MODE_CLIENT_REQUESTED; 5648 break; 5649 case OMX_QCOM_PerfLevelTurbo: 5650 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 5651 m_need_turbo |= TURBO_MODE_CLIENT_REQUESTED; 5652 break; 5653 default: 5654 ret = OMX_ErrorUnsupportedSetting; 5655 break; 5656 } 5657 5658 if (ret == OMX_ErrorNone) { 5659 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5660 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5661 } 5662 5663 return ret; 5664 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) { 5665 OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config = 5666 (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData; 5667 struct v4l2_control control; 5668 DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType); 5669 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE; 5670 5671 switch (config->eDecodeType) { 5672 case OMX_QCOM_PictypeDecode_I: 5673 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON; 5674 break; 5675 case OMX_QCOM_PictypeDecode_IPB: 5676 default: 5677 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF; 5678 break; 5679 } 5680 5681 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5682 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5683 if (ret) 5684 DEBUG_PRINT_ERROR("Failed to set picture type decode"); 5685 5686 return ret; 5687 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) { 5688 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData; 5689 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32); 5690 5691 struct v4l2_control control; 5692 5693 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY; 5694 if (priority->nU32 == 0) 5695 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE; 5696 else 5697 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE; 5698 5699 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5700 DEBUG_PRINT_ERROR("Failed to set Priority"); 5701 ret = OMX_ErrorUnsupportedSetting; 5702 } 5703 return ret; 5704 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) { 5705 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData; 5706 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16); 5707 5708 struct v4l2_control control; 5709 5710 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE; 5711 control.value = rate->nU32; 5712 5713 operating_frame_rate = rate->nU32 >> 16; 5714 5715 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5716 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources : 5717 OMX_ErrorUnsupportedSetting; 5718 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)", 5719 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno)); 5720 } 5721 return ret; 5722 5723 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) { 5724 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5725 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5726 if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) { 5727 enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true); 5728 } 5729 5730 print_debug_color_aspects(&(params->sAspects), "Set Config"); 5731 memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams)); 5732 return ret; 5733 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) { 5734 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams); 5735 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData; 5736 if (!DEFAULT_EXTRADATA & OMX_HDR_COLOR_INFO_EXTRADATA) { 5737 ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, true, true); 5738 if (ret != OMX_ErrorNone) { 5739 DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA"); 5740 return ret; 5741 } 5742 } 5743 5744 print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR"); 5745 memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams)); 5746 return ret; 5747 5748 } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) { 5749 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); 5750 5751 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = 5752 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); 5753 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); 5754 5755 return set_vendor_extension_config(ext); 5756 } 5757 5758 return OMX_ErrorNotImplemented; 5759 } 5760 5761 #define extn_equals(param, extn) (!strcmp(param, extn)) 5762 5763 /* ====================================================================== 5764 FUNCTION 5765 omx_vdec::GetExtensionIndex 5766 5767 DESCRIPTION 5768 OMX GetExtensionIndex method implementaion. <TBD> 5769 5770 PARAMETERS 5771 <TBD>. 5772 5773 RETURN VALUE 5774 OMX Error None if everything successful. 5775 5776 ========================================================================== */ 5777 OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 5778 OMX_IN OMX_STRING paramName, 5779 OMX_OUT OMX_INDEXTYPE* indexType) 5780 { 5781 (void) hComp; 5782 if (m_state == OMX_StateInvalid) { 5783 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State"); 5784 return OMX_ErrorInvalidState; 5785 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) { 5786 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; 5787 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) { 5788 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; 5789 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) { 5790 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata; 5791 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) { 5792 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement; 5793 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) { 5794 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData; 5795 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) { 5796 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData; 5797 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) { 5798 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData; 5799 } 5800 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 5801 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) { 5802 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; 5803 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) { 5804 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; 5805 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) { 5806 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; 5807 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) { 5808 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; 5809 } 5810 #if ALLOCATE_OUTPUT_NATIVEHANDLE 5811 else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) { 5812 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle; 5813 } 5814 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE 5815 #endif 5816 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) { 5817 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; 5818 } 5819 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 5820 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) { 5821 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode; 5822 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) { 5823 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback; 5824 } 5825 #endif 5826 #ifdef FLEXYUV_SUPPORTED 5827 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) { 5828 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription; 5829 } 5830 #endif 5831 else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) { 5832 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd; 5833 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) { 5834 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB; 5835 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) { 5836 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB; 5837 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) { 5838 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode; 5839 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) { 5840 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata; 5841 } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) { 5842 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects; 5843 } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) { 5844 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo; 5845 } else { 5846 DEBUG_PRINT_HIGH("Extension: %s not implemented", paramName); 5847 return OMX_ErrorNotImplemented; 5848 } 5849 return OMX_ErrorNone; 5850 } 5851 5852 /* ====================================================================== 5853 FUNCTION 5854 omx_vdec::GetState 5855 5856 DESCRIPTION 5857 Returns the state information back to the caller.<TBD> 5858 5859 PARAMETERS 5860 <TBD>. 5861 5862 RETURN VALUE 5863 Error None if everything is successful. 5864 ========================================================================== */ 5865 OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 5866 OMX_OUT OMX_STATETYPE* state) 5867 { 5868 (void) hComp; 5869 *state = m_state; 5870 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); 5871 return OMX_ErrorNone; 5872 } 5873 5874 /* ====================================================================== 5875 FUNCTION 5876 omx_vdec::ComponentTunnelRequest 5877 5878 DESCRIPTION 5879 OMX Component Tunnel Request method implementation. <TBD> 5880 5881 PARAMETERS 5882 None. 5883 5884 RETURN VALUE 5885 OMX Error None if everything successful. 5886 5887 ========================================================================== */ 5888 OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 5889 OMX_IN OMX_U32 port, 5890 OMX_IN OMX_HANDLETYPE peerComponent, 5891 OMX_IN OMX_U32 peerPort, 5892 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 5893 { 5894 (void) hComp; 5895 (void) port; 5896 (void) peerComponent; 5897 (void) peerPort; 5898 (void) tunnelSetup; 5899 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented"); 5900 return OMX_ErrorNotImplemented; 5901 } 5902 5903 /* ====================================================================== 5904 FUNCTION 5905 omx_vdec::UseOutputBuffer 5906 5907 DESCRIPTION 5908 Helper function for Use buffer in the input pin 5909 5910 PARAMETERS 5911 None. 5912 5913 RETURN VALUE 5914 true/false 5915 5916 ========================================================================== */ 5917 OMX_ERRORTYPE omx_vdec::allocate_extradata() 5918 { 5919 #ifdef USE_ION 5920 if (drv_ctx.extradata_info.buffer_size) { 5921 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { 5922 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5923 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5924 free_ion_memory(&drv_ctx.extradata_info.ion); 5925 } 5926 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); 5927 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( 5928 drv_ctx.extradata_info.size, 4096, 5929 &drv_ctx.extradata_info.ion.ion_alloc_data, 5930 &drv_ctx.extradata_info.ion.fd_ion_data, 0); 5931 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { 5932 DEBUG_PRINT_ERROR("Failed to alloc extradata memory"); 5933 return OMX_ErrorInsufficientResources; 5934 } 5935 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, 5936 drv_ctx.extradata_info.size, 5937 PROT_READ|PROT_WRITE, MAP_SHARED, 5938 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); 5939 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { 5940 DEBUG_PRINT_ERROR("Failed to map extradata memory"); 5941 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5942 free_ion_memory(&drv_ctx.extradata_info.ion); 5943 return OMX_ErrorInsufficientResources; 5944 } 5945 } 5946 #endif 5947 if (!m_other_extradata) { 5948 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size); 5949 if (!m_other_extradata) { 5950 DEBUG_PRINT_ERROR("Failed to alloc memory\n"); 5951 return OMX_ErrorInsufficientResources; 5952 } 5953 } 5954 return OMX_ErrorNone; 5955 } 5956 5957 void omx_vdec::free_extradata() 5958 { 5959 #ifdef USE_ION 5960 if (drv_ctx.extradata_info.uaddr) { 5961 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5962 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5963 free_ion_memory(&drv_ctx.extradata_info.ion); 5964 } 5965 #endif 5966 if (m_other_extradata) { 5967 free(m_other_extradata); 5968 m_other_extradata = NULL; 5969 } 5970 } 5971 5972 OMX_ERRORTYPE omx_vdec::use_output_buffer( 5973 OMX_IN OMX_HANDLETYPE hComp, 5974 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5975 OMX_IN OMX_U32 port, 5976 OMX_IN OMX_PTR appData, 5977 OMX_IN OMX_U32 bytes, 5978 OMX_IN OMX_U8* buffer) 5979 { 5980 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5981 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 5982 unsigned i= 0; // Temporary counter 5983 struct vdec_setbuffer_cmd setbuffers; 5984 OMX_PTR privateAppData = NULL; 5985 private_handle_t *handle = NULL; 5986 OMX_U8 *buff = buffer; 5987 struct v4l2_buffer buf; 5988 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 5989 int extra_idx = 0; 5990 (void) hComp; 5991 (void) port; 5992 5993 if (!m_out_mem_ptr) { 5994 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); 5995 eRet = allocate_output_headers(); 5996 if (eRet == OMX_ErrorNone) 5997 eRet = allocate_extradata(); 5998 } 5999 6000 if (eRet == OMX_ErrorNone) { 6001 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 6002 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 6003 break; 6004 } 6005 } 6006 } 6007 6008 if (i >= drv_ctx.op_buf.actualcount) { 6009 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount); 6010 eRet = OMX_ErrorInsufficientResources; 6011 } 6012 6013 if (eRet != OMX_ErrorNone) 6014 return eRet; 6015 6016 if (dynamic_buf_mode) { 6017 *bufferHdr = (m_out_mem_ptr + i ); 6018 (*bufferHdr)->pBuffer = NULL; 6019 if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) { 6020 enum v4l2_buf_type buf_type; 6021 int rr = 0; 6022 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6023 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) { 6024 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr); 6025 return OMX_ErrorInsufficientResources; 6026 } else { 6027 streaming[CAPTURE_PORT] = true; 6028 DEBUG_PRINT_LOW("STREAMON Successful"); 6029 } 6030 6031 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 6032 request_perf_level(VIDC_TURBO); 6033 } 6034 BITMASK_SET(&m_out_bm_count,i); 6035 (*bufferHdr)->pAppPrivate = appData; 6036 (*bufferHdr)->pBuffer = buffer; 6037 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 6038 return eRet; 6039 } 6040 6041 if (eRet == OMX_ErrorNone) { 6042 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 6043 if (m_enable_android_native_buffers) { 6044 if (m_use_android_native_buffers) { 6045 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; 6046 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 6047 handle = (private_handle_t *)nBuf->handle; 6048 privateAppData = params->pAppPrivate; 6049 } else { 6050 handle = (private_handle_t *)buff; 6051 privateAppData = appData; 6052 } 6053 if (!handle) { 6054 DEBUG_PRINT_ERROR("handle is invalid"); 6055 return OMX_ErrorBadParameter; 6056 } 6057 6058 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 6059 if (secure_mode && secure_scaling_to_non_secure_opb) { 6060 DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it", 6061 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 6062 } else { 6063 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 6064 " expected %u, got %u", 6065 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 6066 return OMX_ErrorBadParameter; 6067 } 6068 } 6069 6070 drv_ctx.op_buf.buffer_size = handle->size; 6071 6072 if (!m_use_android_native_buffers) { 6073 if (!secure_mode) { 6074 buff = (OMX_U8*)mmap(0, handle->size, 6075 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 6076 if (buff == MAP_FAILED) { 6077 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 6078 return OMX_ErrorInsufficientResources; 6079 } 6080 } 6081 } 6082 #if defined(_ANDROID_ICS_) 6083 native_buffer[i].nativehandle = handle; 6084 native_buffer[i].privatehandle = handle; 6085 #endif 6086 if (!handle) { 6087 DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); 6088 return OMX_ErrorBadParameter; 6089 } 6090 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; 6091 drv_ctx.ptr_outputbuffer[i].offset = 0; 6092 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 6093 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 6094 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size; 6095 } else 6096 #endif 6097 6098 if (!ouput_egl_buffers && !m_use_output_pmem) { 6099 #ifdef USE_ION 6100 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 6101 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 6102 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 6103 &drv_ctx.op_buf_ion_info[i].fd_ion_data, 6104 secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0); 6105 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 6106 DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd); 6107 return OMX_ErrorInsufficientResources; 6108 } 6109 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6110 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 6111 #else 6112 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6113 open (MEM_DEVICE,O_RDWR); 6114 6115 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 6116 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 6117 return OMX_ErrorInsufficientResources; 6118 } 6119 6120 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ 6121 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) { 6122 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6123 open (MEM_DEVICE,O_RDWR); 6124 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 6125 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 6126 return OMX_ErrorInsufficientResources; 6127 } 6128 } 6129 6130 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, 6131 drv_ctx.op_buf.buffer_size, 6132 drv_ctx.op_buf.alignment)) { 6133 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6134 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 6135 return OMX_ErrorInsufficientResources; 6136 } 6137 #endif 6138 if (!secure_mode) { 6139 drv_ctx.ptr_outputbuffer[i].bufferaddr = 6140 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, 6141 PROT_READ|PROT_WRITE, MAP_SHARED, 6142 drv_ctx.ptr_outputbuffer[i].pmem_fd,0); 6143 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { 6144 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 6145 #ifdef USE_ION 6146 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 6147 #endif 6148 DEBUG_PRINT_ERROR("Unable to mmap output buffer"); 6149 return OMX_ErrorInsufficientResources; 6150 } 6151 } 6152 drv_ctx.ptr_outputbuffer[i].offset = 0; 6153 privateAppData = appData; 6154 } else { 6155 6156 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); 6157 if (!appData || !bytes ) { 6158 if (!secure_mode && !buffer) { 6159 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case"); 6160 return OMX_ErrorBadParameter; 6161 } 6162 } 6163 6164 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; 6165 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; 6166 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; 6167 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry || 6168 !pmem_list->nEntries || 6169 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 6170 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer"); 6171 return OMX_ErrorBadParameter; 6172 } 6173 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 6174 pmem_list->entryList->entry; 6175 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx", 6176 pmem_info->pmem_fd); 6177 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; 6178 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; 6179 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 6180 drv_ctx.ptr_outputbuffer[i].mmaped_size = 6181 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 6182 privateAppData = appData; 6183 } 6184 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 6185 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; 6186 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 6187 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 6188 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 6189 6190 *bufferHdr = (m_out_mem_ptr + i ); 6191 if (secure_mode) 6192 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 6193 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 6194 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], 6195 sizeof (vdec_bufferpayload)); 6196 6197 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, 6198 drv_ctx.ptr_outputbuffer[i].bufferaddr, 6199 drv_ctx.ptr_outputbuffer[i].pmem_fd ); 6200 6201 buf.index = i; 6202 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6203 buf.memory = V4L2_MEMORY_USERPTR; 6204 plane[0].length = drv_ctx.op_buf.buffer_size; 6205 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 6206 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 6207 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; 6208 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 6209 plane[0].data_offset = 0; 6210 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 6211 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 6212 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 6213 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 6214 #ifdef USE_ION 6215 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 6216 #endif 6217 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 6218 plane[extra_idx].data_offset = 0; 6219 } else if (extra_idx >= VIDEO_MAX_PLANES) { 6220 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 6221 return OMX_ErrorBadParameter; 6222 } 6223 buf.m.planes = plane; 6224 buf.length = drv_ctx.num_planes; 6225 6226 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { 6227 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 6228 /*TODO: How to handle this case */ 6229 return OMX_ErrorInsufficientResources; 6230 } 6231 6232 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { 6233 enum v4l2_buf_type buf_type; 6234 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6235 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { 6236 return OMX_ErrorInsufficientResources; 6237 } else { 6238 streaming[CAPTURE_PORT] = true; 6239 DEBUG_PRINT_LOW("STREAMON Successful"); 6240 } 6241 6242 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 6243 request_perf_level(VIDC_TURBO); 6244 } 6245 6246 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 6247 if (m_enable_android_native_buffers) { 6248 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); 6249 (*bufferHdr)->pBuffer = (OMX_U8 *)handle; 6250 } else { 6251 (*bufferHdr)->pBuffer = buff; 6252 } 6253 (*bufferHdr)->pAppPrivate = privateAppData; 6254 BITMASK_SET(&m_out_bm_count,i); 6255 } 6256 return eRet; 6257 } 6258 6259 OMX_ERRORTYPE omx_vdec::allocate_client_output_extradata_headers() { 6260 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6261 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 6262 int i = 0; 6263 6264 if (!m_client_output_extradata_mem_ptr) { 6265 int nBufferCount = 0; 6266 6267 nBufferCount = m_client_out_extradata_info.getBufferCount(); 6268 DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount); 6269 6270 m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE)); 6271 6272 if (m_client_output_extradata_mem_ptr) { 6273 bufHdr = m_client_output_extradata_mem_ptr; 6274 for (i=0; i < nBufferCount; i++) { 6275 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6276 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 6277 // Set the values when we determine the right HxW param 6278 bufHdr->nAllocLen = 0; 6279 bufHdr->nFilledLen = 0; 6280 bufHdr->pAppPrivate = NULL; 6281 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_EXTRADATA_INDEX; 6282 bufHdr->pBuffer = NULL; 6283 bufHdr->pOutputPortPrivate = NULL; 6284 bufHdr++; 6285 } 6286 } else { 6287 DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\ 6288 m_client_output_extradata_mem_ptr); 6289 eRet = OMX_ErrorInsufficientResources; 6290 } 6291 } 6292 return eRet; 6293 } 6294 OMX_ERRORTYPE omx_vdec::use_client_output_extradata_buffer( 6295 OMX_IN OMX_HANDLETYPE hComp, 6296 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6297 OMX_IN OMX_U32 port, 6298 OMX_IN OMX_PTR appData, 6299 OMX_IN OMX_U32 bytes, 6300 OMX_IN OMX_U8* buffer) 6301 { 6302 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6303 unsigned i = 0; // Temporary counter 6304 unsigned buffer_count = m_client_out_extradata_info.getBufferCount();; 6305 OMX_U32 buffer_size = m_client_out_extradata_info.getSize(); 6306 (void) hComp; 6307 6308 if (port != OMX_CORE_OUTPUT_EXTRADATA_INDEX || 6309 !client_extradata || bytes != buffer_size|| bufferHdr == NULL) { 6310 DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d," 6311 "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port, 6312 OMX_CORE_OUTPUT_EXTRADATA_INDEX, client_extradata, bytes, buffer_size, bufferHdr); 6313 eRet = OMX_ErrorBadParameter; 6314 return eRet; 6315 } 6316 6317 if (!m_client_output_extradata_mem_ptr) { 6318 eRet = allocate_client_output_extradata_headers(); 6319 } 6320 6321 if (eRet == OMX_ErrorNone) { 6322 for (i = 0; i < buffer_count; i++) { 6323 if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) { 6324 break; 6325 } 6326 } 6327 } 6328 6329 if (i >= buffer_count) { 6330 DEBUG_PRINT_ERROR("Already using %d Extradata o/p buffers", buffer_count); 6331 eRet = OMX_ErrorInsufficientResources; 6332 } 6333 6334 if (eRet == OMX_ErrorNone) { 6335 BITMASK_SET(&m_out_extradata_bm_count,i); 6336 *bufferHdr = (m_client_output_extradata_mem_ptr + i ); 6337 (*bufferHdr)->pAppPrivate = appData; 6338 (*bufferHdr)->pBuffer = buffer; 6339 (*bufferHdr)->nAllocLen = bytes; 6340 } 6341 6342 return eRet; 6343 } 6344 /* ====================================================================== 6345 FUNCTION 6346 omx_vdec::use_input_heap_buffers 6347 6348 DESCRIPTION 6349 OMX Use Buffer Heap allocation method implementation. 6350 6351 PARAMETERS 6352 <TBD>. 6353 6354 RETURN VALUE 6355 OMX Error None , if everything successful. 6356 6357 ========================================================================== */ 6358 OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( 6359 OMX_IN OMX_HANDLETYPE hComp, 6360 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6361 OMX_IN OMX_U32 port, 6362 OMX_IN OMX_PTR appData, 6363 OMX_IN OMX_U32 bytes, 6364 OMX_IN OMX_U8* buffer) 6365 { 6366 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); 6367 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6368 6369 if (secure_mode) { 6370 DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode"); 6371 return OMX_ErrorUndefined; 6372 } 6373 6374 if (!m_inp_heap_ptr) 6375 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) 6376 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 6377 drv_ctx.ip_buf.actualcount); 6378 if (!m_phdr_pmem_ptr) 6379 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) 6380 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 6381 drv_ctx.ip_buf.actualcount); 6382 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) { 6383 DEBUG_PRINT_ERROR("Insufficent memory"); 6384 eRet = OMX_ErrorInsufficientResources; 6385 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) { 6386 input_use_buffer = true; 6387 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); 6388 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; 6389 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; 6390 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; 6391 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; 6392 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; 6393 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; 6394 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); 6395 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); 6396 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt], 6397 (unsigned)NULL, (unsigned)NULL)) { 6398 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 6399 return OMX_ErrorInsufficientResources; 6400 } 6401 m_in_alloc_cnt++; 6402 } else { 6403 DEBUG_PRINT_ERROR("All i/p buffers have been set!"); 6404 eRet = OMX_ErrorInsufficientResources; 6405 } 6406 return eRet; 6407 } 6408 6409 /* ====================================================================== 6410 FUNCTION 6411 omx_vdec::UseBuffer 6412 6413 DESCRIPTION 6414 OMX Use Buffer method implementation. 6415 6416 PARAMETERS 6417 <TBD>. 6418 6419 RETURN VALUE 6420 OMX Error None , if everything successful. 6421 6422 ========================================================================== */ 6423 OMX_ERRORTYPE omx_vdec::use_buffer( 6424 OMX_IN OMX_HANDLETYPE hComp, 6425 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6426 OMX_IN OMX_U32 port, 6427 OMX_IN OMX_PTR appData, 6428 OMX_IN OMX_U32 bytes, 6429 OMX_IN OMX_U8* buffer) 6430 { 6431 OMX_ERRORTYPE error = OMX_ErrorNone; 6432 struct vdec_setbuffer_cmd setbuffers; 6433 6434 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) { 6435 DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer); 6436 return OMX_ErrorBadParameter; 6437 } 6438 if (m_state == OMX_StateInvalid) { 6439 DEBUG_PRINT_ERROR("Use Buffer in Invalid State"); 6440 return OMX_ErrorInvalidState; 6441 } 6442 if (port == OMX_CORE_INPUT_PORT_INDEX) { 6443 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated), 6444 // ensure that use-buffer was called for previous allocation. 6445 // Mix-and-match of useBuffer and allocateBuffer is not allowed 6446 if (m_inp_mem_ptr && !input_use_buffer) { 6447 DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !"); 6448 return OMX_ErrorUndefined; 6449 } 6450 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); 6451 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 6452 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested 6453 } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) { 6454 error = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 6455 } else { 6456 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 6457 error = OMX_ErrorBadPortIndex; 6458 } 6459 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error); 6460 if (error == OMX_ErrorNone) { 6461 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 6462 // Send the callback now 6463 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 6464 post_event(OMX_CommandStateSet,OMX_StateIdle, 6465 OMX_COMPONENT_GENERATE_EVENT); 6466 } 6467 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && 6468 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 6469 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 6470 post_event(OMX_CommandPortEnable, 6471 OMX_CORE_INPUT_PORT_INDEX, 6472 OMX_COMPONENT_GENERATE_EVENT); 6473 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && 6474 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 6475 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 6476 post_event(OMX_CommandPortEnable, 6477 OMX_CORE_OUTPUT_PORT_INDEX, 6478 OMX_COMPONENT_GENERATE_EVENT); 6479 } 6480 } 6481 return error; 6482 } 6483 6484 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, 6485 OMX_BUFFERHEADERTYPE *pmem_bufferHdr) 6486 { 6487 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) { 6488 if (m_inp_heap_ptr[bufferindex].pBuffer) 6489 free(m_inp_heap_ptr[bufferindex].pBuffer); 6490 m_inp_heap_ptr[bufferindex].pBuffer = NULL; 6491 } 6492 if (pmem_bufferHdr) 6493 free_input_buffer(pmem_bufferHdr); 6494 return OMX_ErrorNone; 6495 } 6496 6497 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 6498 { 6499 unsigned int index = 0; 6500 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { 6501 return OMX_ErrorBadParameter; 6502 } 6503 6504 index = bufferHdr - m_inp_mem_ptr; 6505 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 6506 6507 auto_lock l(buf_lock); 6508 bufferHdr->pInputPortPrivate = NULL; 6509 6510 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) { 6511 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 6512 if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) { 6513 struct vdec_setbuffer_cmd setbuffers; 6514 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 6515 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], 6516 sizeof (vdec_bufferpayload)); 6517 if (!secure_mode) { 6518 DEBUG_PRINT_LOW("unmap the input buffer fd=%d", 6519 drv_ctx.ptr_inputbuffer[index].pmem_fd); 6520 DEBUG_PRINT_LOW("unmap the input buffer size=%u address = %p", 6521 (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size, 6522 drv_ctx.ptr_inputbuffer[index].bufferaddr); 6523 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, 6524 drv_ctx.ptr_inputbuffer[index].mmaped_size); 6525 } 6526 6527 if (allocate_native_handle){ 6528 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer; 6529 native_handle_close(nh); 6530 native_handle_delete(nh); 6531 } else { 6532 // Close fd for non-secure and secure non-native-handle case 6533 close(drv_ctx.ptr_inputbuffer[index].pmem_fd); 6534 } 6535 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; 6536 6537 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) { 6538 free(m_desc_buffer_ptr[index].buf_addr); 6539 m_desc_buffer_ptr[index].buf_addr = NULL; 6540 m_desc_buffer_ptr[index].desc_data_size = 0; 6541 } 6542 #ifdef USE_ION 6543 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); 6544 #endif 6545 m_in_alloc_cnt--; 6546 } 6547 } 6548 6549 return OMX_ErrorNone; 6550 } 6551 6552 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 6553 { 6554 unsigned int index = 0; 6555 6556 if (bufferHdr == NULL || m_out_mem_ptr == NULL) { 6557 return OMX_ErrorBadParameter; 6558 } 6559 6560 index = bufferHdr - m_out_mem_ptr; 6561 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); 6562 6563 if (index < drv_ctx.op_buf.actualcount 6564 && drv_ctx.ptr_outputbuffer) { 6565 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index, 6566 drv_ctx.ptr_outputbuffer[index].bufferaddr); 6567 6568 struct vdec_setbuffer_cmd setbuffers; 6569 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 6570 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], 6571 sizeof (vdec_bufferpayload)); 6572 6573 if (!dynamic_buf_mode) { 6574 if (streaming[CAPTURE_PORT] && 6575 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) { 6576 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 6577 DEBUG_PRINT_ERROR("STREAMOFF Failed"); 6578 } else { 6579 DEBUG_PRINT_LOW("STREAMOFF Successful"); 6580 } 6581 } 6582 #ifdef _ANDROID_ 6583 if (m_enable_android_native_buffers) { 6584 if (!secure_mode) { 6585 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { 6586 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, 6587 drv_ctx.ptr_outputbuffer[index].mmaped_size); 6588 } 6589 } 6590 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 6591 } else { 6592 #endif 6593 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 6594 && !ouput_egl_buffers && !m_use_output_pmem) { 6595 if (drv_ctx.op_buf_map_info[index].free_buffer) { 6596 if (!secure_mode) { 6597 DEBUG_PRINT_LOW("unmap the output buffer fd = %d", 6598 drv_ctx.ptr_outputbuffer[0].pmem_fd); 6599 DEBUG_PRINT_LOW("unmap the ouput buffer size=%u address = %p", 6600 (unsigned int)drv_ctx.op_buf_map_info[index].map_size, 6601 drv_ctx.op_buf_map_info[index].base_address); 6602 munmap (drv_ctx.op_buf_map_info[index].base_address, 6603 drv_ctx.op_buf_map_info[index].map_size); 6604 } 6605 close (drv_ctx.ptr_outputbuffer[index].pmem_fd); 6606 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 6607 #ifdef USE_ION 6608 free_ion_memory(&drv_ctx.op_buf_ion_info[index]); 6609 #endif 6610 } else { 6611 drv_ctx.op_buf_ion_info[index].ion_device_fd = -1; 6612 drv_ctx.op_buf_ion_info[index].ion_alloc_data.handle = 0; 6613 drv_ctx.op_buf_ion_info[index].fd_ion_data.fd = -1; 6614 } 6615 drv_ctx.op_buf_map_info[index].free_buffer = false; 6616 drv_ctx.op_buf_map_info[index].base_address = NULL; 6617 drv_ctx.op_buf_map_info[index].map_size = 0; 6618 drv_ctx.op_buf_map_info[index].offset = 0; 6619 } 6620 #ifdef _ANDROID_ 6621 } 6622 #endif 6623 } //!dynamic_buf_mode 6624 if (release_output_done()) { 6625 free_extradata(); 6626 } 6627 } 6628 6629 return OMX_ErrorNone; 6630 6631 } 6632 6633 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 6634 OMX_BUFFERHEADERTYPE **bufferHdr, 6635 OMX_U32 port, 6636 OMX_PTR appData, 6637 OMX_U32 bytes) 6638 { 6639 OMX_BUFFERHEADERTYPE *input = NULL; 6640 unsigned char *buf_addr = NULL; 6641 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6642 unsigned i = 0; 6643 6644 /* Sanity Check*/ 6645 if (bufferHdr == NULL) { 6646 return OMX_ErrorBadParameter; 6647 } 6648 6649 if (m_inp_heap_ptr == NULL) { 6650 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 6651 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 6652 drv_ctx.ip_buf.actualcount); 6653 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 6654 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 6655 drv_ctx.ip_buf.actualcount); 6656 6657 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) { 6658 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed "); 6659 return OMX_ErrorInsufficientResources; 6660 } 6661 } 6662 6663 /*Find a Free index*/ 6664 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6665 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) { 6666 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6667 break; 6668 } 6669 } 6670 6671 if (i < drv_ctx.ip_buf.actualcount) { 6672 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); 6673 6674 if (buf_addr == NULL) { 6675 return OMX_ErrorInsufficientResources; 6676 } 6677 6678 *bufferHdr = (m_inp_heap_ptr + i); 6679 input = *bufferHdr; 6680 BITMASK_SET(&m_heap_inp_bm_count,i); 6681 6682 input->pBuffer = (OMX_U8 *)buf_addr; 6683 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6684 input->nVersion.nVersion = OMX_SPEC_VERSION; 6685 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6686 input->pAppPrivate = appData; 6687 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6688 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); 6689 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 6690 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); 6691 /*Add the Buffers to freeq*/ 6692 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i], 6693 (unsigned)NULL, (unsigned)NULL)) { 6694 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 6695 return OMX_ErrorInsufficientResources; 6696 } 6697 } else { 6698 return OMX_ErrorBadParameter; 6699 } 6700 6701 return eRet; 6702 6703 } 6704 6705 6706 /* ====================================================================== 6707 FUNCTION 6708 omx_vdec::AllocateInputBuffer 6709 6710 DESCRIPTION 6711 Helper function for allocate buffer in the input pin 6712 6713 PARAMETERS 6714 None. 6715 6716 RETURN VALUE 6717 true/false 6718 6719 ========================================================================== */ 6720 OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 6721 OMX_IN OMX_HANDLETYPE hComp, 6722 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6723 OMX_IN OMX_U32 port, 6724 OMX_IN OMX_PTR appData, 6725 OMX_IN OMX_U32 bytes) 6726 { 6727 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6728 struct vdec_setbuffer_cmd setbuffers; 6729 OMX_BUFFERHEADERTYPE *input = NULL; 6730 unsigned i = 0; 6731 unsigned char *buf_addr = NULL; 6732 int pmem_fd = -1, ret = 0; 6733 6734 (void) hComp; 6735 (void) port; 6736 6737 6738 if (bytes != drv_ctx.ip_buf.buffer_size) { 6739 DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u", 6740 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size); 6741 return OMX_ErrorBadParameter; 6742 } 6743 6744 if (!m_inp_mem_ptr) { 6745 struct v4l2_requestbuffers bufreq; 6746 bufreq.memory = V4L2_MEMORY_USERPTR; 6747 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 6748 bufreq.count = drv_ctx.ip_buf.actualcount; 6749 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 6750 if (ret) { 6751 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %s", strerror(errno)); 6752 /*TODO: How to handle this case */ 6753 eRet = OMX_ErrorInsufficientResources; 6754 } else if (bufreq.count != drv_ctx.ip_buf.actualcount) { 6755 DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d", 6756 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count); 6757 eRet = OMX_ErrorInsufficientResources; 6758 } 6759 6760 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)", 6761 drv_ctx.ip_buf.actualcount, 6762 (unsigned int)drv_ctx.ip_buf.buffer_size); 6763 6764 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 6765 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); 6766 6767 if (m_inp_mem_ptr == NULL) { 6768 return OMX_ErrorInsufficientResources; 6769 } 6770 6771 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 6772 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); 6773 6774 if (drv_ctx.ptr_inputbuffer == NULL) { 6775 return OMX_ErrorInsufficientResources; 6776 } 6777 #ifdef USE_ION 6778 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ 6779 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); 6780 6781 if (drv_ctx.ip_buf_ion_info == NULL) { 6782 return OMX_ErrorInsufficientResources; 6783 } 6784 #endif 6785 6786 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) { 6787 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; 6788 #ifdef USE_ION 6789 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; 6790 #endif 6791 } 6792 } 6793 6794 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6795 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 6796 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6797 break; 6798 } 6799 } 6800 6801 if (i < drv_ctx.ip_buf.actualcount) { 6802 struct v4l2_buffer buf; 6803 struct v4l2_plane plane; 6804 int rc; 6805 DEBUG_PRINT_LOW("Allocate input Buffer"); 6806 #ifdef USE_ION 6807 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 6808 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, 6809 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, 6810 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? 6811 SECURE_FLAGS_INPUT_BUFFER : 0); 6812 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { 6813 return OMX_ErrorInsufficientResources; 6814 } 6815 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; 6816 #else 6817 pmem_fd = open (MEM_DEVICE,O_RDWR); 6818 6819 if (pmem_fd < 0) { 6820 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6821 return OMX_ErrorInsufficientResources; 6822 } 6823 6824 if (pmem_fd == 0) { 6825 pmem_fd = open (MEM_DEVICE,O_RDWR); 6826 6827 if (pmem_fd < 0) { 6828 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6829 return OMX_ErrorInsufficientResources; 6830 } 6831 } 6832 6833 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, 6834 drv_ctx.ip_buf.alignment)) { 6835 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6836 close(pmem_fd); 6837 return OMX_ErrorInsufficientResources; 6838 } 6839 #endif 6840 if (!secure_mode) { 6841 buf_addr = (unsigned char *)mmap(NULL, 6842 drv_ctx.ip_buf.buffer_size, 6843 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); 6844 6845 if (buf_addr == MAP_FAILED) { 6846 close(pmem_fd); 6847 #ifdef USE_ION 6848 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); 6849 #endif 6850 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer"); 6851 return OMX_ErrorInsufficientResources; 6852 } 6853 } 6854 *bufferHdr = (m_inp_mem_ptr + i); 6855 if (secure_mode) 6856 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; 6857 else 6858 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; 6859 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; 6860 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; 6861 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; 6862 drv_ctx.ptr_inputbuffer [i].offset = 0; 6863 6864 6865 buf.index = i; 6866 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 6867 buf.memory = V4L2_MEMORY_USERPTR; 6868 plane.bytesused = 0; 6869 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; 6870 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; 6871 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; 6872 plane.reserved[1] = 0; 6873 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; 6874 buf.m.planes = &plane; 6875 buf.length = 1; 6876 6877 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i, 6878 drv_ctx.ptr_inputbuffer[i].bufferaddr); 6879 6880 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 6881 6882 if (rc) { 6883 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 6884 /*TODO: How to handle this case */ 6885 return OMX_ErrorInsufficientResources; 6886 } 6887 6888 input = *bufferHdr; 6889 BITMASK_SET(&m_inp_bm_count,i); 6890 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); 6891 if (allocate_native_handle) { 6892 native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/); 6893 if (!nh) { 6894 DEBUG_PRINT_ERROR("Native handle create failed"); 6895 return OMX_ErrorInsufficientResources; 6896 } 6897 nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd; 6898 input->pBuffer = (OMX_U8 *)nh; 6899 } else if (secure_mode || m_input_pass_buffer_fd) { 6900 /*Legacy method, pass ion fd stashed directly in pBuffer*/ 6901 input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd; 6902 } else { 6903 input->pBuffer = (OMX_U8 *)buf_addr; 6904 } 6905 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6906 input->nVersion.nVersion = OMX_SPEC_VERSION; 6907 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6908 input->pAppPrivate = appData; 6909 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6910 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; 6911 6912 if (drv_ctx.disable_dmx) { 6913 eRet = allocate_desc_buffer(i); 6914 } 6915 } else { 6916 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found"); 6917 eRet = OMX_ErrorInsufficientResources; 6918 } 6919 return eRet; 6920 } 6921 6922 6923 /* ====================================================================== 6924 FUNCTION 6925 omx_vdec::AllocateOutputBuffer 6926 6927 DESCRIPTION 6928 Helper fn for AllocateBuffer in the output pin 6929 6930 PARAMETERS 6931 <TBD>. 6932 6933 RETURN VALUE 6934 OMX Error None if everything went well. 6935 6936 ========================================================================== */ 6937 OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 6938 OMX_IN OMX_HANDLETYPE hComp, 6939 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6940 OMX_IN OMX_U32 port, 6941 OMX_IN OMX_PTR appData, 6942 OMX_IN OMX_U32 bytes) 6943 { 6944 (void)hComp; 6945 (void)port; 6946 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6947 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 6948 unsigned i= 0; // Temporary counter 6949 struct vdec_setbuffer_cmd setbuffers; 6950 int extra_idx = 0; 6951 #ifdef USE_ION 6952 int ion_device_fd =-1; 6953 struct ion_allocation_data ion_alloc_data; 6954 struct ion_fd_data fd_ion_data; 6955 #endif 6956 if (!m_out_mem_ptr) { 6957 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)", 6958 drv_ctx.op_buf.actualcount, 6959 (unsigned int)drv_ctx.op_buf.buffer_size); 6960 int nBufHdrSize = 0; 6961 int nPlatformEntrySize = 0; 6962 int nPlatformListSize = 0; 6963 int nPMEMInfoSize = 0; 6964 6965 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 6966 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 6967 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 6968 6969 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", 6970 drv_ctx.op_buf.actualcount); 6971 nBufHdrSize = drv_ctx.op_buf.actualcount * 6972 sizeof(OMX_BUFFERHEADERTYPE); 6973 6974 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 6975 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 6976 nPlatformListSize = drv_ctx.op_buf.actualcount * 6977 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 6978 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 6979 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 6980 6981 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 6982 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 6983 nPMEMInfoSize, 6984 nPlatformListSize); 6985 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, 6986 drv_ctx.op_buf.actualcount); 6987 unsigned char *pmem_baseaddress_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {NULL}; 6988 int pmem_fd[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {-1}; 6989 int alloc_size[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {0}; 6990 static const int block_max_size = 128 * 1024 * 1024; 6991 unsigned int block_buf_count = block_max_size / drv_ctx.op_buf.buffer_size; 6992 unsigned int last_block_buf_count = 0, block_count = 1; 6993 if (drv_ctx.op_buf.actualcount <= block_buf_count) { 6994 block_buf_count = drv_ctx.op_buf.actualcount; 6995 } else { 6996 last_block_buf_count = drv_ctx.op_buf.actualcount % block_buf_count; 6997 block_count = (drv_ctx.op_buf.actualcount + block_buf_count - 1) / block_buf_count; 6998 } 6999 unsigned int idx = 0; 7000 DEBUG_PRINT_LOW("block_count = %d block_buf_count = %d last_block_buf_count = %d", 7001 block_count, block_buf_count, last_block_buf_count); 7002 #ifdef USE_ION 7003 struct vdec_ion op_buf_ion_info_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS]; 7004 int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED; 7005 for (; idx < block_count; idx++) { 7006 int cnt = ((idx == block_count - 1) && last_block_buf_count) ? 7007 last_block_buf_count : block_buf_count; 7008 alloc_size[idx] = drv_ctx.op_buf.buffer_size * cnt; 7009 // Allocate output buffers as cached to improve performance of software-reading 7010 // of the YUVs. Output buffers are cache-invalidated in driver. 7011 // If color-conversion is involved, Only the C2D output buffers are cached, no 7012 // need to cache the decoder's output buffers 7013 op_buf_ion_info_temp[idx].ion_device_fd = alloc_map_ion_memory( 7014 alloc_size[idx], 7015 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment, 7016 &op_buf_ion_info_temp[idx].ion_alloc_data, &op_buf_ion_info_temp[idx].fd_ion_data, 7017 (secure_mode && !secure_scaling_to_non_secure_opb) ? 7018 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag); 7019 if (op_buf_ion_info_temp[idx].ion_device_fd < 0) { 7020 DEBUG_PRINT_LOW("Failed to allocate chunk %ul size = %d", idx, alloc_size[idx]); 7021 break; 7022 } 7023 pmem_fd[idx] = op_buf_ion_info_temp[idx].fd_ion_data.fd; 7024 DEBUG_PRINT_LOW("Allocated chunk %ul fd = %ul size = %d", idx, pmem_fd[idx], alloc_size[idx]); 7025 } 7026 if (idx != block_count) { 7027 for (OMX_U32 i = 0; i < idx; i++) { 7028 close(pmem_fd[i]); 7029 free_ion_memory(&op_buf_ion_info_temp[i]); 7030 } 7031 return OMX_ErrorInsufficientResources; 7032 } 7033 7034 #else 7035 for (idx = 0; idx < block_count; idx++) { 7036 pmem_fd[idx] = open (MEM_DEVICE,O_RDWR); 7037 7038 if (pmem_fd[idx] < 0) { 7039 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d", 7040 drv_ctx.op_buf.buffer_size); 7041 break; 7042 } 7043 int cnt = ((idx == block_count - 1) && last_block_buf_count) ? 7044 last_block_buf_count : block_buf_count; 7045 if (!align_pmem_buffers(pmem_fd[idx], drv_ctx.op_buf.buffer_size * cnt, 7046 drv_ctx.op_buf.alignment)) { 7047 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 7048 close(pmem_fd[idx]); 7049 break; 7050 } 7051 } 7052 if (idx != block_count) { 7053 for (i = 0; i < idx; i++) { 7054 close(pmem_fd[i]); 7055 } 7056 return OMX_ErrorInsufficientResources; 7057 } 7058 #endif 7059 if (!secure_mode) { 7060 idx = 0; 7061 for (; idx < block_count; idx++) { 7062 pmem_baseaddress_temp[idx] = (unsigned char *)mmap(NULL, 7063 alloc_size[idx], 7064 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd[idx], 0); 7065 7066 if (pmem_baseaddress_temp[idx] == MAP_FAILED) { 7067 DEBUG_PRINT_ERROR("MMAP failed for Size %u for fd = %d", 7068 (unsigned int)alloc_size[idx], pmem_fd[idx]); 7069 close(pmem_fd[idx]); 7070 #ifdef USE_ION 7071 free_ion_memory(&op_buf_ion_info_temp[idx]); 7072 #endif 7073 break; 7074 } 7075 } 7076 if (idx != block_count) { 7077 for (i = 0; i < idx; i++) { 7078 munmap(pmem_baseaddress_temp[idx], alloc_size[idx]); 7079 close(pmem_fd[i]); 7080 #ifdef USE_ION 7081 free_ion_memory(&op_buf_ion_info_temp[i]); 7082 #endif 7083 } 7084 return OMX_ErrorInsufficientResources; 7085 } 7086 } 7087 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 7088 // Alloc mem for platform specific info 7089 char *pPtr=NULL; 7090 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 7091 nPMEMInfoSize,1); 7092 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ 7093 calloc (sizeof(struct vdec_bufferpayload), 7094 drv_ctx.op_buf.actualcount); 7095 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 7096 calloc (sizeof (struct vdec_output_frameinfo), 7097 drv_ctx.op_buf.actualcount); 7098 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 7099 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer "); 7100 return OMX_ErrorInsufficientResources; 7101 } 7102 7103 #ifdef USE_ION 7104 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ 7105 calloc (sizeof(struct vdec_ion), 7106 drv_ctx.op_buf.actualcount); 7107 if (!drv_ctx.op_buf_ion_info) { 7108 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 7109 return OMX_ErrorInsufficientResources; 7110 } 7111 #endif 7112 drv_ctx.op_buf_map_info = (struct vdec_ion_map_info *)\ 7113 calloc (sizeof(struct vdec_ion_map_info), 7114 drv_ctx.op_buf.actualcount); 7115 if (!drv_ctx.op_buf_map_info) { 7116 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_map_info"); 7117 return OMX_ErrorInsufficientResources; 7118 } 7119 7120 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 7121 && drv_ctx.ptr_respbuffer) { 7122 drv_ctx.ptr_outputbuffer[0].mmaped_size = 7123 (drv_ctx.op_buf.buffer_size * 7124 drv_ctx.op_buf.actualcount); 7125 bufHdr = m_out_mem_ptr; 7126 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 7127 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 7128 (((char *) m_platform_list) + nPlatformListSize); 7129 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 7130 (((char *) m_platform_entry) + nPlatformEntrySize); 7131 pPlatformList = m_platform_list; 7132 pPlatformEntry = m_platform_entry; 7133 pPMEMInfo = m_pmem_info; 7134 7135 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 7136 7137 // Settting the entire storage nicely 7138 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); 7139 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 7140 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 7141 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 7142 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 7143 // Set the values when we determine the right HxW param 7144 bufHdr->nAllocLen = bytes; 7145 bufHdr->nFilledLen = 0; 7146 bufHdr->pAppPrivate = appData; 7147 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7148 // Platform specific PMEM Information 7149 // Initialize the Platform Entry 7150 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); 7151 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 7152 pPlatformEntry->entry = pPMEMInfo; 7153 // Initialize the Platform List 7154 pPlatformList->nEntries = 1; 7155 pPlatformList->entryList = pPlatformEntry; 7156 // Keep pBuffer NULL till vdec is opened 7157 bufHdr->pBuffer = NULL; 7158 bufHdr->nOffset = 0; 7159 7160 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; 7161 pPMEMInfo->pmem_fd = -1; 7162 bufHdr->pPlatformPrivate = pPlatformList; 7163 7164 int block_idx = i / block_buf_count; 7165 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd[block_idx]; 7166 m_pmem_info[i].pmem_fd = pmem_fd[block_idx]; 7167 #ifdef USE_ION 7168 drv_ctx.op_buf_ion_info[i].ion_device_fd = op_buf_ion_info_temp[block_idx].ion_device_fd; 7169 drv_ctx.op_buf_ion_info[i].ion_alloc_data = op_buf_ion_info_temp[block_idx].ion_alloc_data; 7170 drv_ctx.op_buf_ion_info[i].fd_ion_data = op_buf_ion_info_temp[block_idx].fd_ion_data; 7171 #endif 7172 drv_ctx.op_buf_map_info[i].free_buffer = !(i % block_buf_count); 7173 drv_ctx.op_buf_map_info[i].base_address = pmem_baseaddress_temp[block_idx]; 7174 drv_ctx.op_buf_map_info[i].map_size = alloc_size[block_idx]; 7175 drv_ctx.op_buf_map_info[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count); 7176 7177 /*Create a mapping between buffers*/ 7178 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 7179 drv_ctx.ptr_respbuffer[i].client_data = (void *)\ 7180 &drv_ctx.ptr_outputbuffer[i]; 7181 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count); 7182 drv_ctx.ptr_outputbuffer[i].bufferaddr = 7183 pmem_baseaddress_temp[block_idx] + (drv_ctx.op_buf.buffer_size * (i % block_buf_count)); 7184 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 7185 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 7186 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 7187 7188 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p", 7189 pmem_fd[block_idx], (unsigned int)drv_ctx.ptr_outputbuffer[i].offset, 7190 drv_ctx.ptr_outputbuffer[i].bufferaddr); 7191 // Move the buffer and buffer header pointers 7192 bufHdr++; 7193 pPMEMInfo++; 7194 pPlatformEntry++; 7195 pPlatformList++; 7196 } 7197 } else { 7198 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 7199 m_out_mem_ptr, pPtr); 7200 if (m_out_mem_ptr) { 7201 free(m_out_mem_ptr); 7202 m_out_mem_ptr = NULL; 7203 } 7204 if (pPtr) { 7205 free(pPtr); 7206 pPtr = NULL; 7207 } 7208 if (drv_ctx.ptr_outputbuffer) { 7209 free(drv_ctx.ptr_outputbuffer); 7210 drv_ctx.ptr_outputbuffer = NULL; 7211 } 7212 if (drv_ctx.ptr_respbuffer) { 7213 free(drv_ctx.ptr_respbuffer); 7214 drv_ctx.ptr_respbuffer = NULL; 7215 } 7216 #ifdef USE_ION 7217 if (drv_ctx.op_buf_ion_info) { 7218 DEBUG_PRINT_LOW("Free o/p ion context"); 7219 free(drv_ctx.op_buf_ion_info); 7220 drv_ctx.op_buf_ion_info = NULL; 7221 } 7222 #endif 7223 free(drv_ctx.op_buf_map_info); 7224 drv_ctx.op_buf_map_info = NULL; 7225 eRet = OMX_ErrorInsufficientResources; 7226 } 7227 if (eRet == OMX_ErrorNone) 7228 eRet = allocate_extradata(); 7229 } 7230 7231 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 7232 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 7233 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i); 7234 break; 7235 } 7236 } 7237 7238 if (eRet == OMX_ErrorNone) { 7239 if (i < drv_ctx.op_buf.actualcount) { 7240 struct v4l2_buffer buf; 7241 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 7242 int rc; 7243 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 7244 7245 drv_ctx.ptr_outputbuffer[i].buffer_len = 7246 drv_ctx.op_buf.buffer_size; 7247 7248 *bufferHdr = (m_out_mem_ptr + i ); 7249 if (secure_mode) { 7250 #ifdef USE_ION 7251 drv_ctx.ptr_outputbuffer[i].bufferaddr = 7252 (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 7253 #else 7254 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 7255 #endif 7256 } 7257 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; 7258 7259 buf.index = i; 7260 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7261 buf.memory = V4L2_MEMORY_USERPTR; 7262 plane[0].length = drv_ctx.op_buf.buffer_size; 7263 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 7264 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 7265 #ifdef USE_ION 7266 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 7267 #endif 7268 plane[0].reserved[1] = drv_ctx.op_buf_map_info[i].offset; 7269 plane[0].data_offset = 0; 7270 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 7271 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 7272 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 7273 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 7274 #ifdef USE_ION 7275 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 7276 #endif 7277 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 7278 plane[extra_idx].data_offset = 0; 7279 } else if (extra_idx >= VIDEO_MAX_PLANES) { 7280 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx); 7281 return OMX_ErrorBadParameter; 7282 } 7283 buf.m.planes = plane; 7284 buf.length = drv_ctx.num_planes; 7285 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr); 7286 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 7287 if (rc) { 7288 /*TODO: How to handle this case */ 7289 return OMX_ErrorInsufficientResources; 7290 } 7291 7292 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { 7293 enum v4l2_buf_type buf_type; 7294 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7295 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 7296 if (rc) { 7297 return OMX_ErrorInsufficientResources; 7298 } else { 7299 streaming[CAPTURE_PORT] = true; 7300 DEBUG_PRINT_LOW("STREAMON Successful"); 7301 } 7302 7303 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 7304 request_perf_level(VIDC_TURBO); 7305 } 7306 7307 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; 7308 (*bufferHdr)->pAppPrivate = appData; 7309 BITMASK_SET(&m_out_bm_count,i); 7310 } else { 7311 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient"); 7312 eRet = OMX_ErrorInsufficientResources; 7313 } 7314 } 7315 7316 return eRet; 7317 } 7318 7319 7320 // AllocateBuffer -- API Call 7321 /* ====================================================================== 7322 FUNCTION 7323 omx_vdec::AllocateBuffer 7324 7325 DESCRIPTION 7326 Returns zero if all the buffers released.. 7327 7328 PARAMETERS 7329 None. 7330 7331 RETURN VALUE 7332 true/false 7333 7334 ========================================================================== */ 7335 OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 7336 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 7337 OMX_IN OMX_U32 port, 7338 OMX_IN OMX_PTR appData, 7339 OMX_IN OMX_U32 bytes) 7340 { 7341 unsigned i = 0; 7342 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 7343 7344 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); 7345 if (m_state == OMX_StateInvalid) { 7346 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State"); 7347 return OMX_ErrorInvalidState; 7348 } 7349 7350 if (port == OMX_CORE_INPUT_PORT_INDEX) { 7351 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated), 7352 // ensure that use-buffer was never called. 7353 // Mix-and-match of useBuffer and allocateBuffer is not allowed 7354 if (m_inp_mem_ptr && input_use_buffer) { 7355 DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !"); 7356 return OMX_ErrorUndefined; 7357 } 7358 if (arbitrary_bytes) { 7359 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 7360 } else { 7361 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 7362 } 7363 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 7364 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, 7365 appData,bytes); 7366 } else { 7367 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 7368 eRet = OMX_ErrorBadPortIndex; 7369 } 7370 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 7371 if (eRet == OMX_ErrorNone) { 7372 if (allocate_done()) { 7373 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 7374 // Send the callback now 7375 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 7376 post_event(OMX_CommandStateSet,OMX_StateIdle, 7377 OMX_COMPONENT_GENERATE_EVENT); 7378 } 7379 } 7380 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) { 7381 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 7382 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 7383 post_event(OMX_CommandPortEnable, 7384 OMX_CORE_INPUT_PORT_INDEX, 7385 OMX_COMPONENT_GENERATE_EVENT); 7386 } 7387 } 7388 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) { 7389 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 7390 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 7391 post_event(OMX_CommandPortEnable, 7392 OMX_CORE_OUTPUT_PORT_INDEX, 7393 OMX_COMPONENT_GENERATE_EVENT); 7394 } 7395 } 7396 } 7397 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); 7398 return eRet; 7399 } 7400 7401 // Free Buffer - API call 7402 /* ====================================================================== 7403 FUNCTION 7404 omx_vdec::FreeBuffer 7405 7406 DESCRIPTION 7407 7408 PARAMETERS 7409 None. 7410 7411 RETURN VALUE 7412 true/false 7413 7414 ========================================================================== */ 7415 OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 7416 OMX_IN OMX_U32 port, 7417 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7418 { 7419 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7420 unsigned int nPortIndex; 7421 (void) hComp; 7422 DEBUG_PRINT_LOW("In for decoder free_buffer"); 7423 7424 if (m_state == OMX_StateIdle && 7425 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 7426 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); 7427 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 7428 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) { 7429 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port); 7430 } else if ((port == OMX_CORE_INPUT_PORT_INDEX && 7431 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || 7432 (port == OMX_CORE_OUTPUT_PORT_INDEX && 7433 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) { 7434 DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port); 7435 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) { 7436 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled"); 7437 post_event(OMX_EventError, 7438 OMX_ErrorPortUnpopulated, 7439 OMX_COMPONENT_GENERATE_EVENT); 7440 7441 return OMX_ErrorIncorrectStateOperation; 7442 } else if (m_state != OMX_StateInvalid) { 7443 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers"); 7444 post_event(OMX_EventError, 7445 OMX_ErrorPortUnpopulated, 7446 OMX_COMPONENT_GENERATE_EVENT); 7447 } 7448 7449 if (port == OMX_CORE_INPUT_PORT_INDEX) { 7450 /*Check if arbitrary bytes*/ 7451 if (!arbitrary_bytes && !input_use_buffer) 7452 nPortIndex = buffer - m_inp_mem_ptr; 7453 else 7454 nPortIndex = buffer - m_inp_heap_ptr; 7455 7456 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); 7457 if (nPortIndex < drv_ctx.ip_buf.actualcount && 7458 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) { 7459 // Clear the bit associated with it. 7460 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 7461 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 7462 if (input_use_buffer == true) { 7463 7464 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); 7465 if (m_phdr_pmem_ptr) 7466 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 7467 } else { 7468 if (arbitrary_bytes) { 7469 if (m_phdr_pmem_ptr) 7470 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); 7471 else 7472 free_input_buffer(nPortIndex,NULL); 7473 } else 7474 free_input_buffer(buffer); 7475 } 7476 m_inp_bPopulated = OMX_FALSE; 7477 if(release_input_done()) 7478 release_buffers(this, VDEC_BUFFER_TYPE_INPUT); 7479 /*Free the Buffer Header*/ 7480 if (release_input_done()) { 7481 DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); 7482 free_input_buffer_header(); 7483 } 7484 } else { 7485 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid"); 7486 eRet = OMX_ErrorBadPortIndex; 7487 } 7488 7489 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 7490 && release_input_done()) { 7491 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 7492 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 7493 post_event(OMX_CommandPortDisable, 7494 OMX_CORE_INPUT_PORT_INDEX, 7495 OMX_COMPONENT_GENERATE_EVENT); 7496 } 7497 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 7498 // check if the buffer is valid 7499 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 7500 if (nPortIndex < drv_ctx.op_buf.actualcount && 7501 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) { 7502 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); 7503 // Clear the bit associated with it. 7504 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 7505 m_out_bPopulated = OMX_FALSE; 7506 client_buffers.free_output_buffer (buffer); 7507 7508 if(release_output_done()) { 7509 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT); 7510 } 7511 if (release_output_done()) { 7512 free_output_buffer_header(); 7513 } 7514 } else { 7515 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid"); 7516 eRet = OMX_ErrorBadPortIndex; 7517 } 7518 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 7519 && release_output_done()) { 7520 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); 7521 7522 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 7523 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 7524 #ifdef _ANDROID_ICS_ 7525 if (m_enable_android_native_buffers) { 7526 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); 7527 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 7528 } 7529 #endif 7530 7531 post_event(OMX_CommandPortDisable, 7532 OMX_CORE_OUTPUT_PORT_INDEX, 7533 OMX_COMPONENT_GENERATE_EVENT); 7534 } 7535 } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) { 7536 nPortIndex = buffer - m_client_output_extradata_mem_ptr; 7537 DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex); 7538 7539 BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex); 7540 7541 if (release_output_extradata_done()) { 7542 free_output_extradata_buffer_header(); 7543 } 7544 } else { 7545 eRet = OMX_ErrorBadPortIndex; 7546 } 7547 if ((eRet == OMX_ErrorNone) && 7548 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 7549 if (release_done()) { 7550 /* 7551 * Reset buffer requirements here to ensure setting buffer requirement 7552 * when component move to executing state from loaded state via idle. 7553 */ 7554 drv_ctx.op_buf.buffer_size = 0; 7555 drv_ctx.op_buf.actualcount = 0; 7556 7557 // Send the callback now 7558 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 7559 post_event(OMX_CommandStateSet, OMX_StateLoaded, 7560 OMX_COMPONENT_GENERATE_EVENT); 7561 } 7562 } 7563 return eRet; 7564 } 7565 7566 7567 /* ====================================================================== 7568 FUNCTION 7569 omx_vdec::EmptyThisBuffer 7570 7571 DESCRIPTION 7572 This routine is used to push the encoded video frames to 7573 the video decoder. 7574 7575 PARAMETERS 7576 None. 7577 7578 RETURN VALUE 7579 OMX Error None if everything went successful. 7580 7581 ========================================================================== */ 7582 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 7583 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7584 { 7585 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 7586 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; 7587 7588 if (m_state != OMX_StateExecuting && 7589 m_state != OMX_StatePause && 7590 m_state != OMX_StateIdle) { 7591 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State"); 7592 return OMX_ErrorInvalidState; 7593 } 7594 7595 if (buffer == NULL) { 7596 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL"); 7597 return OMX_ErrorBadParameter; 7598 } 7599 7600 if (!m_inp_bEnabled) { 7601 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled."); 7602 return OMX_ErrorIncorrectStateOperation; 7603 } 7604 7605 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 7606 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex); 7607 return OMX_ErrorBadPortIndex; 7608 } 7609 7610 if (perf_flag) { 7611 if (!latency) { 7612 dec_time.stop(); 7613 latency = dec_time.processing_time_us(); 7614 dec_time.start(); 7615 } 7616 } 7617 7618 if (arbitrary_bytes) { 7619 nBufferIndex = buffer - m_inp_heap_ptr; 7620 } else { 7621 if (input_use_buffer == true) { 7622 nBufferIndex = buffer - m_inp_heap_ptr; 7623 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) { 7624 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode"); 7625 return OMX_ErrorBadParameter; 7626 } 7627 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; 7628 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; 7629 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; 7630 buffer = &m_inp_mem_ptr[nBufferIndex]; 7631 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u", 7632 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen); 7633 } else { 7634 nBufferIndex = buffer - m_inp_mem_ptr; 7635 } 7636 } 7637 7638 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) { 7639 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid"); 7640 return OMX_ErrorBadParameter; 7641 } 7642 7643 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 7644 codec_config_flag = true; 7645 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); 7646 } 7647 7648 /* The client should not set this when codec is in arbitrary bytes mode */ 7649 if (m_input_pass_buffer_fd) { 7650 buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr; 7651 } 7652 7653 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)", 7654 buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen); 7655 if (arbitrary_bytes) { 7656 post_event ((unsigned long)hComp,(unsigned long)buffer, 7657 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 7658 } else { 7659 post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB); 7660 } 7661 time_stamp_dts.insert_timestamp(buffer); 7662 return OMX_ErrorNone; 7663 } 7664 7665 /* ====================================================================== 7666 FUNCTION 7667 omx_vdec::empty_this_buffer_proxy 7668 7669 DESCRIPTION 7670 This routine is used to push the encoded video frames to 7671 the video decoder. 7672 7673 PARAMETERS 7674 None. 7675 7676 RETURN VALUE 7677 OMX Error None if everything went successful. 7678 7679 ========================================================================== */ 7680 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 7681 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7682 { 7683 VIDC_TRACE_NAME_HIGH("ETB"); 7684 (void) hComp; 7685 int push_cnt = 0,i=0; 7686 unsigned nPortIndex = 0; 7687 OMX_ERRORTYPE ret = OMX_ErrorNone; 7688 struct vdec_input_frameinfo frameinfo; 7689 struct vdec_bufferpayload *temp_buffer; 7690 struct vdec_seqheader seq_header; 7691 bool port_setting_changed = true; 7692 7693 /*Should we generate a Aync error event*/ 7694 if (buffer == NULL || buffer->pInputPortPrivate == NULL) { 7695 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid"); 7696 return OMX_ErrorBadParameter; 7697 } 7698 7699 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 7700 7701 if (nPortIndex >= drv_ctx.ip_buf.actualcount) { 7702 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 7703 nPortIndex); 7704 return OMX_ErrorBadParameter; 7705 } 7706 7707 pending_input_buffers++; 7708 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 7709 7710 /* return zero length and not an EOS buffer */ 7711 if (!arbitrary_bytes && (buffer->nFilledLen == 0) && 7712 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) { 7713 DEBUG_PRINT_HIGH("return zero legth buffer"); 7714 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 7715 OMX_COMPONENT_GENERATE_EBD); 7716 return OMX_ErrorNone; 7717 } 7718 7719 if (input_flush_progress == true) { 7720 DEBUG_PRINT_LOW("Flush in progress return buffer "); 7721 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 7722 OMX_COMPONENT_GENERATE_EBD); 7723 return OMX_ErrorNone; 7724 } 7725 7726 auto_lock l(buf_lock); 7727 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 7728 7729 if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) { 7730 return OMX_ErrorBadParameter; 7731 } 7732 /* If its first frame, H264 codec and reject is true, then parse the nal 7733 and get the profile. Based on this, reject the clip playback */ 7734 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 && 7735 m_reject_avc_1080p_mp) { 7736 first_frame = 1; 7737 DEBUG_PRINT_ERROR("Parse nal to get the profile"); 7738 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen, 7739 NALU_TYPE_SPS); 7740 m_profile = h264_parser->get_profile(); 7741 ret = is_video_session_supported(); 7742 if (ret) { 7743 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD); 7744 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT); 7745 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */ 7746 m_state = OMX_StateInvalid; 7747 return OMX_ErrorNone; 7748 } 7749 } 7750 7751 VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000); 7752 VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen); 7753 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 7754 /*for use buffer we need to memcpy the data*/ 7755 temp_buffer->buffer_len = buffer->nFilledLen; 7756 7757 if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) { 7758 if (buffer->nFilledLen <= temp_buffer->buffer_len) { 7759 if (arbitrary_bytes) { 7760 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 7761 } else { 7762 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), 7763 buffer->nFilledLen); 7764 } 7765 } else { 7766 return OMX_ErrorBadParameter; 7767 } 7768 7769 } 7770 7771 frameinfo.bufferaddr = temp_buffer->bufferaddr; 7772 frameinfo.client_data = (void *) buffer; 7773 frameinfo.datalen = temp_buffer->buffer_len; 7774 frameinfo.flags = 0; 7775 frameinfo.offset = buffer->nOffset; 7776 frameinfo.pmem_fd = temp_buffer->pmem_fd; 7777 frameinfo.pmem_offset = temp_buffer->offset; 7778 frameinfo.timestamp = buffer->nTimeStamp; 7779 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) { 7780 DEBUG_PRINT_LOW("ETB: dmx enabled"); 7781 if (m_demux_entries == 0) { 7782 extract_demux_addr_offsets(buffer); 7783 } 7784 7785 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries); 7786 handle_demux_data(buffer); 7787 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; 7788 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; 7789 } else { 7790 frameinfo.desc_addr = NULL; 7791 frameinfo.desc_size = 0; 7792 } 7793 if (!arbitrary_bytes) { 7794 frameinfo.flags |= buffer->nFlags; 7795 } 7796 7797 #ifdef _ANDROID_ 7798 if (m_debug_timestamp) { 7799 if (arbitrary_bytes) { 7800 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7801 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7802 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7803 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7804 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7805 } 7806 } 7807 #endif 7808 7809 log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len); 7810 7811 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 7812 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7813 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7814 } 7815 7816 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7817 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); 7818 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 7819 h264_scratch.nFilledLen = 0; 7820 nal_count = 0; 7821 look_ahead_nal = false; 7822 frame_count = 0; 7823 if (m_frame_parser.mutils) 7824 m_frame_parser.mutils->initialize_frame_checking_environment(); 7825 m_frame_parser.flush(); 7826 h264_last_au_ts = LLONG_MAX; 7827 h264_last_au_flags = 0; 7828 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 7829 m_demux_entries = 0; 7830 } 7831 struct v4l2_buffer buf; 7832 struct v4l2_plane plane; 7833 memset( (void *)&buf, 0, sizeof(buf)); 7834 memset( (void *)&plane, 0, sizeof(plane)); 7835 int rc; 7836 unsigned long print_count; 7837 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7838 buf.flags = V4L2_QCOM_BUF_FLAG_EOS; 7839 DEBUG_PRINT_HIGH("INPUT EOS reached") ; 7840 } 7841 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7842 buf.index = nPortIndex; 7843 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7844 buf.memory = V4L2_MEMORY_USERPTR; 7845 plane.bytesused = temp_buffer->buffer_len; 7846 plane.length = drv_ctx.ip_buf.buffer_size; 7847 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - 7848 (unsigned long)temp_buffer->offset; 7849 plane.reserved[0] = temp_buffer->pmem_fd; 7850 plane.reserved[1] = temp_buffer->offset; 7851 plane.data_offset = 0; 7852 buf.m.planes = &plane; 7853 buf.length = 1; 7854 if (frameinfo.timestamp >= LLONG_MAX) { 7855 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; 7856 } 7857 //assumption is that timestamp is in milliseconds 7858 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; 7859 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); 7860 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; 7861 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0; 7862 7863 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 7864 DEBUG_PRINT_LOW("Increment codec_config buffer counter"); 7865 android_atomic_inc(&m_queued_codec_config_count); 7866 } 7867 7868 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 7869 if (rc) { 7870 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client"); 7871 m_cb.EmptyBufferDone(hComp, m_app_data, buffer); 7872 return OMX_ErrorHardware; 7873 } 7874 7875 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7876 codec_config_flag = false; 7877 } 7878 if (!streaming[OUTPUT_PORT]) { 7879 enum v4l2_buf_type buf_type; 7880 int ret,r; 7881 7882 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7883 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 7884 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 7885 if (!ret) { 7886 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful"); 7887 streaming[OUTPUT_PORT] = true; 7888 } else if (errno == EBUSY) { 7889 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD"); 7890 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7891 OMX_COMPONENT_GENERATE_EBD); 7892 return OMX_ErrorInsufficientResources; 7893 } else { 7894 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT"); 7895 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); 7896 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7897 OMX_COMPONENT_GENERATE_EBD); 7898 return OMX_ErrorBadParameter; 7899 } 7900 } 7901 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)", 7902 frameinfo.bufferaddr, (long long)frameinfo.timestamp, 7903 (unsigned int)frameinfo.datalen); 7904 7905 return ret; 7906 } 7907 7908 /* ====================================================================== 7909 FUNCTION 7910 omx_vdec::FillThisBuffer 7911 7912 DESCRIPTION 7913 IL client uses this method to release the frame buffer 7914 after displaying them. 7915 7916 PARAMETERS 7917 None. 7918 7919 RETURN VALUE 7920 true/false 7921 7922 ========================================================================== */ 7923 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 7924 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7925 { 7926 if (m_state != OMX_StateExecuting && 7927 m_state != OMX_StatePause && 7928 m_state != OMX_StateIdle) { 7929 DEBUG_PRINT_ERROR("FTB in Invalid State"); 7930 return OMX_ErrorInvalidState; 7931 } 7932 7933 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 7934 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex); 7935 return OMX_ErrorBadPortIndex; 7936 } 7937 7938 if (!m_out_bEnabled) { 7939 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); 7940 return OMX_ErrorIncorrectStateOperation; 7941 } 7942 7943 unsigned nPortIndex = 0; 7944 if (dynamic_buf_mode) { 7945 private_handle_t *handle = NULL; 7946 struct VideoDecoderOutputMetaData *meta; 7947 unsigned int nPortIndex = 0; 7948 7949 if (!buffer || !buffer->pBuffer) { 7950 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer); 7951 return OMX_ErrorBadParameter; 7952 } 7953 7954 //get the buffer type and fd info 7955 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer; 7956 handle = (private_handle_t *)meta->pHandle; 7957 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle); 7958 7959 if (!handle) { 7960 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle); 7961 return OMX_ErrorBadParameter; 7962 } 7963 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF 7964 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 7965 if (nPortIndex < drv_ctx.op_buf.actualcount && 7966 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 7967 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd; 7968 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer; 7969 7970 //Store private handle from GraphicBuffer 7971 native_buffer[nPortIndex].privatehandle = handle; 7972 native_buffer[nPortIndex].nativehandle = handle; 7973 } else { 7974 DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex); 7975 return OMX_ErrorBadParameter; 7976 } 7977 7978 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite 7979 //this with a more sane size so that we don't compensate in rest of code 7980 //We'll restore this size later on, so that it's transparent to client 7981 buffer->nFilledLen = 0; 7982 buffer->nAllocLen = handle->size; 7983 7984 if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) { 7985 m_is_display_session = true; 7986 } else { 7987 m_is_display_session = false; 7988 } 7989 DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session); 7990 7991 drv_ctx.op_buf.buffer_size = handle->size; 7992 } 7993 7994 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 7995 if (buffer == NULL || 7996 (nPortIndex >= drv_ctx.op_buf.actualcount)) { 7997 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 7998 nPortIndex, drv_ctx.op_buf.actualcount); 7999 return OMX_ErrorBadParameter; 8000 } 8001 8002 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 8003 post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg); 8004 return OMX_ErrorNone; 8005 } 8006 /* ====================================================================== 8007 FUNCTION 8008 omx_vdec::fill_this_buffer_proxy 8009 8010 DESCRIPTION 8011 IL client uses this method to release the frame buffer 8012 after displaying them. 8013 8014 PARAMETERS 8015 None. 8016 8017 RETURN VALUE 8018 true/false 8019 8020 ========================================================================== */ 8021 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 8022 OMX_IN OMX_HANDLETYPE hComp, 8023 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 8024 { 8025 VIDC_TRACE_NAME_HIGH("FTB"); 8026 OMX_ERRORTYPE nRet = OMX_ErrorNone; 8027 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 8028 unsigned nPortIndex = 0; 8029 struct vdec_fillbuffer_cmd fillbuffer; 8030 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 8031 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 8032 8033 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 8034 8035 if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) { 8036 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 8037 nPortIndex, drv_ctx.op_buf.actualcount); 8038 return OMX_ErrorBadParameter; 8039 } 8040 8041 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 8042 bufferAdd, bufferAdd->pBuffer); 8043 /*Return back the output buffer to client*/ 8044 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) { 8045 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); 8046 buffer->nFilledLen = 0; 8047 m_cb.FillBufferDone (hComp,m_app_data,buffer); 8048 return OMX_ErrorNone; 8049 } 8050 8051 if (dynamic_buf_mode) { 8052 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0; 8053 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen; 8054 buf_ref_add(nPortIndex); 8055 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen; 8056 } 8057 8058 pending_output_buffers++; 8059 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 8060 buffer = client_buffers.get_dr_buf_hdr(bufferAdd); 8061 if (!buffer) { 8062 DEBUG_PRINT_ERROR("err: client_buffer ptr invalid"); 8063 return OMX_ErrorBadParameter; 8064 } 8065 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 8066 if (ptr_respbuffer) { 8067 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 8068 } 8069 8070 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) { 8071 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); 8072 buffer->nFilledLen = 0; 8073 m_cb.FillBufferDone (hComp,m_app_data,buffer); 8074 pending_output_buffers--; 8075 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 8076 return OMX_ErrorBadParameter; 8077 } 8078 8079 int rc = 0; 8080 struct v4l2_buffer buf; 8081 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 8082 memset( (void *)&buf, 0, sizeof(buf)); 8083 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); 8084 unsigned int extra_idx = 0; 8085 8086 buf.index = nPortIndex; 8087 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 8088 buf.memory = V4L2_MEMORY_USERPTR; 8089 plane[0].bytesused = buffer->nFilledLen; 8090 plane[0].length = buffer->nAllocLen; 8091 plane[0].m.userptr = 8092 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - 8093 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; 8094 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 8095 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 8096 plane[0].data_offset = 0; 8097 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 8098 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 8099 plane[extra_idx].bytesused = 0; 8100 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 8101 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); 8102 #ifdef USE_ION 8103 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 8104 #endif 8105 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; 8106 plane[extra_idx].data_offset = 0; 8107 } else if (extra_idx >= VIDEO_MAX_PLANES) { 8108 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx); 8109 return OMX_ErrorBadParameter; 8110 } 8111 buf.m.planes = plane; 8112 buf.length = drv_ctx.num_planes; 8113 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d", 8114 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress); 8115 8116 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 8117 if (rc) { 8118 buffer->nFilledLen = 0; 8119 DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno)); 8120 m_cb.FillBufferDone(hComp, m_app_data, buffer); 8121 return OMX_ErrorHardware; 8122 } 8123 8124 return OMX_ErrorNone; 8125 } 8126 8127 /* ====================================================================== 8128 FUNCTION 8129 omx_vdec::SetCallbacks 8130 8131 DESCRIPTION 8132 Set the callbacks. 8133 8134 PARAMETERS 8135 None. 8136 8137 RETURN VALUE 8138 OMX Error None if everything successful. 8139 8140 ========================================================================== */ 8141 OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 8142 OMX_IN OMX_CALLBACKTYPE* callbacks, 8143 OMX_IN OMX_PTR appData) 8144 { 8145 (void) hComp; 8146 m_cb = *callbacks; 8147 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 8148 m_cb.EventHandler,m_cb.FillBufferDone); 8149 m_app_data = appData; 8150 return OMX_ErrorNotImplemented; 8151 } 8152 8153 /* ====================================================================== 8154 FUNCTION 8155 omx_vdec::ComponentDeInit 8156 8157 DESCRIPTION 8158 Destroys the component and release memory allocated to the heap. 8159 8160 PARAMETERS 8161 <TBD>. 8162 8163 RETURN VALUE 8164 OMX Error None if everything successful. 8165 8166 ========================================================================== */ 8167 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 8168 { 8169 (void) hComp; 8170 8171 unsigned i = 0; 8172 if (OMX_StateLoaded != m_state) { 8173 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\ 8174 m_state); 8175 DEBUG_PRINT_ERROR("Playback Ended - FAILED"); 8176 } else { 8177 DEBUG_PRINT_HIGH("Playback Ended - PASSED"); 8178 } 8179 8180 /*Check if the output buffers have to be cleaned up*/ 8181 if (m_out_mem_ptr) { 8182 DEBUG_PRINT_LOW("Freeing the Output Memory"); 8183 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) { 8184 if (BITMASK_PRESENT(&m_out_bm_count, i)) { 8185 BITMASK_CLEAR(&m_out_bm_count, i); 8186 client_buffers.free_output_buffer (&m_out_mem_ptr[i]); 8187 } 8188 8189 if (release_output_done()) { 8190 break; 8191 } 8192 } 8193 #ifdef _ANDROID_ICS_ 8194 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 8195 #endif 8196 } 8197 8198 /*Check if the input buffers have to be cleaned up*/ 8199 if (m_inp_mem_ptr || m_inp_heap_ptr) { 8200 DEBUG_PRINT_LOW("Freeing the Input Memory"); 8201 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) { 8202 8203 if (BITMASK_PRESENT(&m_inp_bm_count, i)) { 8204 BITMASK_CLEAR(&m_inp_bm_count, i); 8205 if (m_inp_mem_ptr) 8206 free_input_buffer (i,&m_inp_mem_ptr[i]); 8207 else 8208 free_input_buffer (i,NULL); 8209 } 8210 8211 if (release_input_done()) { 8212 break; 8213 } 8214 } 8215 } 8216 free_input_buffer_header(); 8217 free_output_buffer_header(); 8218 if (h264_scratch.pBuffer) { 8219 free(h264_scratch.pBuffer); 8220 h264_scratch.pBuffer = NULL; 8221 } 8222 8223 if (h264_parser) { 8224 delete h264_parser; 8225 h264_parser = NULL; 8226 } 8227 8228 if (m_frame_parser.mutils) { 8229 DEBUG_PRINT_LOW("Free utils parser"); 8230 delete (m_frame_parser.mutils); 8231 m_frame_parser.mutils = NULL; 8232 } 8233 8234 if (m_platform_list) { 8235 free(m_platform_list); 8236 m_platform_list = NULL; 8237 } 8238 if (m_vendor_config.pData) { 8239 free(m_vendor_config.pData); 8240 m_vendor_config.pData = NULL; 8241 } 8242 8243 // Reset counters in mesg queues 8244 m_ftb_q.m_size=0; 8245 m_cmd_q.m_size=0; 8246 m_etb_q.m_size=0; 8247 m_ftb_q.m_read = m_ftb_q.m_write =0; 8248 m_cmd_q.m_read = m_cmd_q.m_write =0; 8249 m_etb_q.m_read = m_etb_q.m_write =0; 8250 #ifdef _ANDROID_ 8251 if (m_debug_timestamp) { 8252 m_timestamp_list.reset_ts_list(); 8253 } 8254 #endif 8255 8256 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG"); 8257 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 8258 // NULL); 8259 DEBUG_PRINT_HIGH("Close the driver instance"); 8260 8261 if (m_debug.infile) { 8262 fclose(m_debug.infile); 8263 m_debug.infile = NULL; 8264 } 8265 if (m_debug.outfile) { 8266 fclose(m_debug.outfile); 8267 m_debug.outfile = NULL; 8268 } 8269 if (m_debug.out_ymeta_file) { 8270 fclose(m_debug.out_ymeta_file); 8271 m_debug.out_ymeta_file = NULL; 8272 } 8273 if (m_debug.out_uvmeta_file) { 8274 fclose(m_debug.out_uvmeta_file); 8275 m_debug.out_uvmeta_file = NULL; 8276 } 8277 #ifdef OUTPUT_EXTRADATA_LOG 8278 if (outputExtradataFile) 8279 fclose (outputExtradataFile); 8280 #endif 8281 DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete"); 8282 return OMX_ErrorNone; 8283 } 8284 8285 /* ====================================================================== 8286 FUNCTION 8287 omx_vdec::UseEGLImage 8288 8289 DESCRIPTION 8290 OMX Use EGL Image method implementation <TBD>. 8291 8292 PARAMETERS 8293 <TBD>. 8294 8295 RETURN VALUE 8296 Not Implemented error. 8297 8298 ========================================================================== */ 8299 OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 8300 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 8301 OMX_IN OMX_U32 port, 8302 OMX_IN OMX_PTR appData, 8303 OMX_IN void* eglImage) 8304 { 8305 (void) appData; 8306 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; 8307 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; 8308 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; 8309 8310 #ifdef USE_EGL_IMAGE_GPU 8311 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; 8312 EGLint fd = -1, offset = 0,pmemPtr = 0; 8313 #else 8314 int fd = -1, offset = 0; 8315 #endif 8316 DEBUG_PRINT_HIGH("use EGL image support for decoder"); 8317 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { 8318 DEBUG_PRINT_ERROR("Invalid EGL image"); 8319 } 8320 #ifdef USE_EGL_IMAGE_GPU 8321 if (m_display_id == NULL) { 8322 DEBUG_PRINT_ERROR("Display ID is not set by IL client"); 8323 return OMX_ErrorInsufficientResources; 8324 } 8325 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) 8326 eglGetProcAddress("eglQueryImageKHR"); 8327 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd); 8328 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset); 8329 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr); 8330 #else //with OMX test app 8331 struct temp_egl { 8332 int pmem_fd; 8333 int offset; 8334 }; 8335 struct temp_egl *temp_egl_id = NULL; 8336 void * pmemPtr = (void *) eglImage; 8337 temp_egl_id = (struct temp_egl *)eglImage; 8338 if (temp_egl_id != NULL) { 8339 fd = temp_egl_id->pmem_fd; 8340 offset = temp_egl_id->offset; 8341 } 8342 #endif 8343 if (fd < 0) { 8344 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd); 8345 return OMX_ErrorInsufficientResources; 8346 } 8347 pmem_info.pmem_fd = (OMX_U32) fd; 8348 pmem_info.offset = (OMX_U32) offset; 8349 pmem_entry.entry = (void *) &pmem_info; 8350 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 8351 pmem_list.entryList = &pmem_entry; 8352 pmem_list.nEntries = 1; 8353 ouput_egl_buffers = true; 8354 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, 8355 (void *)&pmem_list, drv_ctx.op_buf.buffer_size, 8356 (OMX_U8 *)pmemPtr)) { 8357 DEBUG_PRINT_ERROR("use buffer call failed for egl image"); 8358 return OMX_ErrorInsufficientResources; 8359 } 8360 return OMX_ErrorNone; 8361 } 8362 8363 /* ====================================================================== 8364 FUNCTION 8365 omx_vdec::ComponentRoleEnum 8366 8367 DESCRIPTION 8368 OMX Component Role Enum method implementation. 8369 8370 PARAMETERS 8371 <TBD>. 8372 8373 RETURN VALUE 8374 OMX Error None if everything is successful. 8375 ========================================================================== */ 8376 OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 8377 OMX_OUT OMX_U8* role, 8378 OMX_IN OMX_U32 index) 8379 { 8380 (void) hComp; 8381 OMX_ERRORTYPE eRet = OMX_ErrorNone; 8382 8383 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 8384 if ((0 == index) && role) { 8385 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 8386 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8387 } else { 8388 eRet = OMX_ErrorNoMore; 8389 } 8390 } 8391 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 8392 if ((0 == index) && role) { 8393 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 8394 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8395 } else { 8396 eRet = OMX_ErrorNoMore; 8397 } 8398 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 8399 if ((0 == index) && role) { 8400 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 8401 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8402 } else { 8403 DEBUG_PRINT_LOW("No more roles"); 8404 eRet = OMX_ErrorNoMore; 8405 } 8406 } 8407 8408 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 8409 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) { 8410 if ((0 == index) && role) { 8411 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 8412 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8413 } else { 8414 DEBUG_PRINT_LOW("No more roles"); 8415 eRet = OMX_ErrorNoMore; 8416 } 8417 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 8418 if ((0 == index) && role) { 8419 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 8420 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8421 } else { 8422 DEBUG_PRINT_LOW("No more roles"); 8423 eRet = OMX_ErrorNoMore; 8424 } 8425 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 8426 if ((0 == index) && role) { 8427 strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 8428 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8429 } else { 8430 DEBUG_PRINT_LOW("No more roles"); 8431 eRet = OMX_ErrorNoMore; 8432 } 8433 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 8434 if ((0 == index) && role) { 8435 strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 8436 DEBUG_PRINT_LOW("component_role_enum: role %s", role); 8437 } else { 8438 DEBUG_PRINT_LOW("No more roles"); 8439 eRet = OMX_ErrorNoMore; 8440 } 8441 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 8442 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 8443 ) { 8444 if ((0 == index) && role) { 8445 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 8446 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8447 } else { 8448 DEBUG_PRINT_LOW("No more roles"); 8449 eRet = OMX_ErrorNoMore; 8450 } 8451 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 8452 if ((0 == index) && role) { 8453 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 8454 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8455 } else { 8456 DEBUG_PRINT_LOW("No more roles"); 8457 eRet = OMX_ErrorNoMore; 8458 } 8459 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 8460 if ((0 == index) && role) { 8461 strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 8462 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8463 } else { 8464 DEBUG_PRINT_LOW("No more roles"); 8465 eRet = OMX_ErrorNoMore; 8466 } 8467 } else { 8468 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component"); 8469 eRet = OMX_ErrorInvalidComponentName; 8470 } 8471 return eRet; 8472 } 8473 8474 8475 8476 8477 /* ====================================================================== 8478 FUNCTION 8479 omx_vdec::AllocateDone 8480 8481 DESCRIPTION 8482 Checks if entire buffer pool is allocated by IL Client or not. 8483 Need this to move to IDLE state. 8484 8485 PARAMETERS 8486 None. 8487 8488 RETURN VALUE 8489 true/false. 8490 8491 ========================================================================== */ 8492 bool omx_vdec::allocate_done(void) 8493 { 8494 bool bRet = false; 8495 bool bRet_In = false; 8496 bool bRet_Out = false; 8497 bool bRet_Out_Extra = false; 8498 8499 bRet_In = allocate_input_done(); 8500 bRet_Out = allocate_output_done(); 8501 bRet_Out_Extra = allocate_output_extradata_done(); 8502 8503 if (bRet_In && bRet_Out && bRet_Out_Extra) { 8504 bRet = true; 8505 } 8506 8507 return bRet; 8508 } 8509 /* ====================================================================== 8510 FUNCTION 8511 omx_vdec::AllocateInputDone 8512 8513 DESCRIPTION 8514 Checks if I/P buffer pool is allocated by IL Client or not. 8515 8516 PARAMETERS 8517 None. 8518 8519 RETURN VALUE 8520 true/false. 8521 8522 ========================================================================== */ 8523 bool omx_vdec::allocate_input_done(void) 8524 { 8525 bool bRet = false; 8526 unsigned i=0; 8527 8528 if (m_inp_mem_ptr == NULL) { 8529 return bRet; 8530 } 8531 if (m_inp_mem_ptr ) { 8532 for (; i<drv_ctx.ip_buf.actualcount; i++) { 8533 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 8534 break; 8535 } 8536 } 8537 } 8538 if (i == drv_ctx.ip_buf.actualcount) { 8539 bRet = true; 8540 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers"); 8541 } 8542 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) { 8543 m_inp_bPopulated = OMX_TRUE; 8544 } 8545 return bRet; 8546 } 8547 /* ====================================================================== 8548 FUNCTION 8549 omx_vdec::AllocateOutputDone 8550 8551 DESCRIPTION 8552 Checks if entire O/P buffer pool is allocated by IL Client or not. 8553 8554 PARAMETERS 8555 None. 8556 8557 RETURN VALUE 8558 true/false. 8559 8560 ========================================================================== */ 8561 bool omx_vdec::allocate_output_done(void) 8562 { 8563 bool bRet = false; 8564 unsigned j=0; 8565 8566 if (m_out_mem_ptr == NULL) { 8567 return bRet; 8568 } 8569 8570 if (m_out_mem_ptr) { 8571 for (; j < drv_ctx.op_buf.actualcount; j++) { 8572 if (BITMASK_ABSENT(&m_out_bm_count,j)) { 8573 break; 8574 } 8575 } 8576 } 8577 8578 if (j == drv_ctx.op_buf.actualcount) { 8579 bRet = true; 8580 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers"); 8581 if (m_out_bEnabled) 8582 m_out_bPopulated = OMX_TRUE; 8583 } 8584 8585 return bRet; 8586 } 8587 8588 bool omx_vdec::allocate_output_extradata_done(void) { 8589 bool bRet = false; 8590 unsigned j=0; 8591 unsigned nBufferCount = 0; 8592 8593 nBufferCount = m_client_out_extradata_info.getBufferCount(); 8594 8595 if (!m_client_out_extradata_info.is_client_extradata_enabled()) { 8596 return true; 8597 } 8598 8599 if (m_client_output_extradata_mem_ptr) { 8600 for (; j < nBufferCount; j++) { 8601 if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) { 8602 break; 8603 } 8604 } 8605 8606 if (j == nBufferCount) { 8607 bRet = true; 8608 DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers"); 8609 } 8610 } 8611 8612 return bRet; 8613 } 8614 /* ====================================================================== 8615 FUNCTION 8616 omx_vdec::ReleaseDone 8617 8618 DESCRIPTION 8619 Checks if IL client has released all the buffers. 8620 8621 PARAMETERS 8622 None. 8623 8624 RETURN VALUE 8625 true/false 8626 8627 ========================================================================== */ 8628 bool omx_vdec::release_done(void) 8629 { 8630 bool bRet = false; 8631 8632 if (release_input_done()) { 8633 if (release_output_done()) { 8634 if (release_output_extradata_done()) { 8635 bRet = true; 8636 } 8637 } 8638 } 8639 return bRet; 8640 } 8641 8642 8643 /* ====================================================================== 8644 FUNCTION 8645 omx_vdec::ReleaseOutputDone 8646 8647 DESCRIPTION 8648 Checks if IL client has released all the buffers. 8649 8650 PARAMETERS 8651 None. 8652 8653 RETURN VALUE 8654 true/false 8655 8656 ========================================================================== */ 8657 bool omx_vdec::release_output_done(void) 8658 { 8659 bool bRet = false; 8660 unsigned i=0,j=0; 8661 8662 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr); 8663 if (m_out_mem_ptr) { 8664 for (; j < drv_ctx.op_buf.actualcount ; j++) { 8665 if (BITMASK_PRESENT(&m_out_bm_count,j)) { 8666 break; 8667 } 8668 } 8669 if (j == drv_ctx.op_buf.actualcount) { 8670 m_out_bm_count = 0; 8671 bRet = true; 8672 } 8673 } else { 8674 m_out_bm_count = 0; 8675 bRet = true; 8676 } 8677 return bRet; 8678 } 8679 /* ====================================================================== 8680 FUNCTION 8681 omx_vdec::ReleaseInputDone 8682 8683 DESCRIPTION 8684 Checks if IL client has released all the buffers. 8685 8686 PARAMETERS 8687 None. 8688 8689 RETURN VALUE 8690 true/false 8691 8692 ========================================================================== */ 8693 bool omx_vdec::release_input_done(void) 8694 { 8695 bool bRet = false; 8696 unsigned i=0,j=0; 8697 8698 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 8699 if (m_inp_mem_ptr) { 8700 for (; j<drv_ctx.ip_buf.actualcount; j++) { 8701 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) { 8702 break; 8703 } 8704 } 8705 if (j==drv_ctx.ip_buf.actualcount) { 8706 bRet = true; 8707 } 8708 } else { 8709 bRet = true; 8710 } 8711 return bRet; 8712 } 8713 8714 bool omx_vdec::release_output_extradata_done(void) { 8715 bool bRet = false; 8716 unsigned i=0,j=0, buffer_count=0; 8717 8718 buffer_count = m_client_out_extradata_info.getBufferCount(); 8719 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d", 8720 m_client_output_extradata_mem_ptr, buffer_count); 8721 8722 if (m_client_output_extradata_mem_ptr) { 8723 for (; j<buffer_count; j++) { 8724 if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) { 8725 break; 8726 } 8727 } 8728 if (j == buffer_count) { 8729 bRet = true; 8730 } 8731 } else { 8732 bRet = true; 8733 } 8734 return bRet; 8735 } 8736 8737 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 8738 OMX_BUFFERHEADERTYPE * buffer) 8739 { 8740 VIDC_TRACE_NAME_HIGH("FBD"); 8741 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 8742 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) { 8743 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer); 8744 return OMX_ErrorBadParameter; 8745 } else if (output_flush_progress) { 8746 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); 8747 buffer->nFilledLen = 0; 8748 buffer->nTimeStamp = 0; 8749 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 8750 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 8751 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; 8752 } 8753 8754 if (m_debug_extradata) { 8755 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 8756 DEBUG_PRINT_HIGH("***************************************************"); 8757 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received"); 8758 DEBUG_PRINT_HIGH("***************************************************"); 8759 } 8760 8761 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) { 8762 DEBUG_PRINT_HIGH("***************************************************"); 8763 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 8764 DEBUG_PRINT_HIGH("***************************************************"); 8765 } 8766 } 8767 8768 8769 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld", 8770 buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp); 8771 pending_output_buffers --; 8772 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 8773 8774 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8775 DEBUG_PRINT_HIGH("Output EOS has been reached"); 8776 if (!output_flush_progress) 8777 post_event((unsigned)NULL, (unsigned)NULL, 8778 OMX_COMPONENT_GENERATE_EOS_DONE); 8779 8780 if (psource_frame) { 8781 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); 8782 psource_frame = NULL; 8783 } 8784 if (pdest_frame) { 8785 pdest_frame->nFilledLen = 0; 8786 m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL, 8787 (unsigned)NULL); 8788 pdest_frame = NULL; 8789 } 8790 } 8791 8792 #ifdef OUTPUT_EXTRADATA_LOG 8793 if (outputExtradataFile) { 8794 int buf_index = buffer - m_out_mem_ptr; 8795 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr); 8796 8797 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 8798 p_extra = (OMX_OTHER_EXTRADATATYPE *) 8799 ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3)); 8800 8801 while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) { 8802 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x", 8803 p_extra->nSize, p_extra->eType); 8804 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); 8805 8806 if (p_extra->eType == OMX_ExtraDataNone) { 8807 break; 8808 } 8809 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8810 } 8811 } 8812 #endif 8813 8814 /* For use buffer we need to copy the data */ 8815 if (!output_flush_progress) { 8816 /* This is the error check for non-recoverable errros */ 8817 bool is_duplicate_ts_valid = true; 8818 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive); 8819 8820 if (output_capability == V4L2_PIX_FMT_MPEG4 || 8821 output_capability == V4L2_PIX_FMT_MPEG2 || 8822 output_capability == V4L2_PIX_FMT_DIVX || 8823 output_capability == V4L2_PIX_FMT_DIVX_311) 8824 is_duplicate_ts_valid = false; 8825 8826 if ((output_capability == V4L2_PIX_FMT_H264 || 8827 output_capability == V4L2_PIX_FMT_H264_MVC) && 8828 is_interlaced) { 8829 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) { 8830 is_interlaced = false; 8831 } 8832 } 8833 8834 if (buffer->nFilledLen > 0) { 8835 time_stamp_dts.get_next_timestamp(buffer, 8836 is_interlaced && is_duplicate_ts_valid); 8837 if (m_debug_timestamp) { 8838 { 8839 OMX_TICKS expected_ts = 0; 8840 m_timestamp_list.pop_min_ts(expected_ts); 8841 if (is_interlaced && is_duplicate_ts_valid) { 8842 m_timestamp_list.pop_min_ts(expected_ts); 8843 } 8844 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", 8845 buffer->nTimeStamp, expected_ts); 8846 8847 if (buffer->nTimeStamp != expected_ts) { 8848 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check"); 8849 } 8850 } 8851 } 8852 } 8853 } 8854 VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000); 8855 8856 if (m_cb.FillBufferDone) { 8857 if (buffer->nFilledLen > 0) { 8858 if (arbitrary_bytes) 8859 adjust_timestamp(buffer->nTimeStamp); 8860 else 8861 set_frame_rate(buffer->nTimeStamp); 8862 8863 proc_frms++; 8864 if (perf_flag) { 8865 if (1 == proc_frms) { 8866 dec_time.stop(); 8867 latency = dec_time.processing_time_us() - latency; 8868 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); 8869 dec_time.start(); 8870 fps_metrics.start(); 8871 } 8872 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8873 OMX_U64 proc_time = 0; 8874 fps_metrics.stop(); 8875 proc_time = fps_metrics.processing_time_us(); 8876 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)", 8877 (unsigned int)proc_frms, (float)proc_time / 1e6, 8878 (float)(1e6 * proc_frms) / proc_time); 8879 } 8880 } 8881 } 8882 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8883 prev_ts = LLONG_MAX; 8884 rst_prev_ts = true; 8885 proc_frms = 0; 8886 } 8887 8888 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 8889 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 8890 buffer->pPlatformPrivate)->entryList->entry; 8891 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd); 8892 OMX_BUFFERHEADERTYPE *il_buffer; 8893 il_buffer = client_buffers.get_il_buf_hdr(buffer); 8894 OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator); 8895 8896 if (il_buffer && m_last_rendered_TS >= 0) { 8897 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS); 8898 8899 // Current frame can be send for rendering if 8900 // (a) current FPS is <= 60 8901 // (b) is the next frame after the frame with TS 0 8902 // (c) is the first frame after seek 8903 // (d) the delta TS b\w two consecutive frames is > 16 ms 8904 // (e) its TS is equal to previous frame TS 8905 // (f) if marked EOS 8906 8907 if(current_framerate <= 60 || m_last_rendered_TS == 0 || 8908 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 || 8909 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 8910 m_last_rendered_TS = il_buffer->nTimeStamp; 8911 } else { 8912 //mark for droping 8913 buffer->nFilledLen = 0; 8914 } 8915 8916 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)", 8917 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS, 8918 il_buffer->nTimeStamp,ts_delta); 8919 8920 //above code makes sure that delta b\w two consecutive frames is not 8921 //greater than 16ms, slow-mo feature, so cap fps to max 60 8922 if (current_framerate > 60 ) { 8923 current_framerate = 60; 8924 } 8925 } 8926 8927 // add current framerate to gralloc meta data 8928 if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && m_out_mem_ptr) { 8929 // If valid fps was received, directly send it to display for the 1st fbd. 8930 // Otherwise, calculate fps using fbd timestamps 8931 float refresh_rate = m_fps_prev; 8932 if (m_fps_received) { 8933 if (1 == proc_frms) { 8934 refresh_rate = m_fps_received / (float)(1<<16); 8935 } 8936 } else { 8937 // check if dynamic refresh rate change feature enabled or not 8938 if (m_drc_enable) { 8939 // set coarse fps when 2 fbds received and 8940 // set fps again when 30 fbds received as it should be 8941 // more accurate than the one set when only 2 fbds received. 8942 if (2 == proc_frms || 30 == proc_frms) { 8943 if (drv_ctx.frame_rate.fps_denominator) { 8944 refresh_rate = drv_ctx.frame_rate.fps_numerator / 8945 (float) drv_ctx.frame_rate.fps_denominator; 8946 } 8947 } 8948 } else { 8949 // calculate and set refresh rate for every frame from second frame onwards 8950 // display will assume the default refresh rate for first frame (which is 60 fps) 8951 if (m_fps_prev) { 8952 if (drv_ctx.frame_rate.fps_denominator) { 8953 refresh_rate = drv_ctx.frame_rate.fps_numerator / 8954 (float) drv_ctx.frame_rate.fps_denominator; 8955 } 8956 } 8957 } 8958 } 8959 if (refresh_rate > 60) { 8960 refresh_rate = 60; 8961 } 8962 DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms); 8963 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8964 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 8965 UPDATE_REFRESH_RATE, (void*)&refresh_rate); 8966 m_fps_prev = refresh_rate; 8967 } 8968 8969 if (buffer->nFilledLen && m_enable_android_native_buffers && m_out_mem_ptr) { 8970 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8971 DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode); 8972 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 8973 S3D_FORMAT, (void*)&stereo_output_mode); 8974 } 8975 8976 if (il_buffer) { 8977 log_output_buffers(il_buffer); 8978 if (dynamic_buf_mode) { 8979 unsigned int nPortIndex = 0; 8980 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 8981 8982 // Since we're passing around handles, adjust nFilledLen and nAllocLen 8983 // to size of the handle. Do it _after_ log_output_buffers which 8984 // requires the respective sizes to be accurate. 8985 8986 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 8987 buffer->nFilledLen = buffer->nFilledLen ? 8988 sizeof(struct VideoDecoderOutputMetaData) : 0; 8989 8990 //Clear graphic buffer handles in dynamic mode 8991 if (nPortIndex < drv_ctx.op_buf.actualcount && 8992 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 8993 native_buffer[nPortIndex].privatehandle = NULL; 8994 native_buffer[nPortIndex].nativehandle = NULL; 8995 } else { 8996 DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex); 8997 return OMX_ErrorBadParameter; 8998 } 8999 } 9000 m_cb.FillBufferDone (hComp,m_app_data,il_buffer); 9001 } else { 9002 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); 9003 return OMX_ErrorBadParameter; 9004 } 9005 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd); 9006 } else { 9007 return OMX_ErrorBadParameter; 9008 } 9009 9010 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 9011 if (m_smoothstreaming_mode && m_out_mem_ptr) { 9012 OMX_U32 buf_index = buffer - m_out_mem_ptr; 9013 BufferDim_t dim; 9014 private_handle_t *private_handle = NULL; 9015 dim.sliceWidth = framesize.nWidth; 9016 dim.sliceHeight = framesize.nHeight; 9017 if (buf_index < drv_ctx.op_buf.actualcount && 9018 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 9019 native_buffer[buf_index].privatehandle) 9020 private_handle = native_buffer[buf_index].privatehandle; 9021 if (private_handle) { 9022 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d", 9023 dim.sliceWidth, dim.sliceHeight); 9024 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim); 9025 } 9026 } 9027 #endif 9028 9029 return OMX_ErrorNone; 9030 } 9031 9032 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 9033 OMX_BUFFERHEADERTYPE* buffer) 9034 { 9035 VIDC_TRACE_NAME_HIGH("EBD"); 9036 int nBufferIndex = buffer - m_inp_mem_ptr; 9037 9038 if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) { 9039 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer); 9040 return OMX_ErrorBadParameter; 9041 } 9042 9043 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x", 9044 buffer, buffer->pBuffer, buffer->nFlags); 9045 pending_input_buffers--; 9046 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 9047 9048 if (arbitrary_bytes) { 9049 if (pdest_frame == NULL && input_flush_progress == false) { 9050 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); 9051 pdest_frame = buffer; 9052 buffer->nFilledLen = 0; 9053 buffer->nTimeStamp = LLONG_MAX; 9054 push_input_buffer (hComp); 9055 } else { 9056 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); 9057 buffer->nFilledLen = 0; 9058 if (!m_input_free_q.insert_entry((unsigned long)buffer, 9059 (unsigned)NULL, (unsigned)NULL)) { 9060 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error"); 9061 } 9062 } 9063 } else if (m_cb.EmptyBufferDone) { 9064 buffer->nFilledLen = 0; 9065 if (input_use_buffer == true) { 9066 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; 9067 } 9068 9069 /* Restore the FD that we over-wrote in ETB */ 9070 if (m_input_pass_buffer_fd) { 9071 buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd; 9072 } 9073 9074 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 9075 } 9076 return OMX_ErrorNone; 9077 } 9078 9079 int omx_vdec::async_message_process (void *context, void* message) 9080 { 9081 omx_vdec* omx = NULL; 9082 struct vdec_msginfo *vdec_msg = NULL; 9083 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 9084 struct v4l2_buffer *v4l2_buf_ptr = NULL; 9085 struct v4l2_plane *plane = NULL; 9086 struct vdec_output_frameinfo *output_respbuf = NULL; 9087 int rc=1; 9088 if (context == NULL || message == NULL) { 9089 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check"); 9090 return -1; 9091 } 9092 vdec_msg = (struct vdec_msginfo *)message; 9093 9094 omx = reinterpret_cast<omx_vdec*>(context); 9095 9096 switch (vdec_msg->msgcode) { 9097 9098 case VDEC_MSG_EVT_HW_ERROR: 9099 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9100 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 9101 break; 9102 9103 case VDEC_MSG_EVT_HW_OVERLOAD: 9104 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9105 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD); 9106 break; 9107 9108 case VDEC_MSG_EVT_HW_UNSUPPORTED: 9109 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9110 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); 9111 break; 9112 9113 case VDEC_MSG_RESP_START_DONE: 9114 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9115 OMX_COMPONENT_GENERATE_START_DONE); 9116 break; 9117 9118 case VDEC_MSG_RESP_STOP_DONE: 9119 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9120 OMX_COMPONENT_GENERATE_STOP_DONE); 9121 break; 9122 9123 case VDEC_MSG_RESP_RESUME_DONE: 9124 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9125 OMX_COMPONENT_GENERATE_RESUME_DONE); 9126 break; 9127 9128 case VDEC_MSG_RESP_PAUSE_DONE: 9129 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9130 OMX_COMPONENT_GENERATE_PAUSE_DONE); 9131 break; 9132 9133 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 9134 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9135 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 9136 break; 9137 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 9138 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9139 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 9140 break; 9141 case VDEC_MSG_RESP_INPUT_FLUSHED: 9142 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 9143 9144 /* omxhdr = (OMX_BUFFERHEADERTYPE* ) 9145 vdec_msg->msgdata.input_frame_clientdata; */ 9146 9147 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; 9148 if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL || 9149 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) { 9150 omxhdr = NULL; 9151 vdec_msg->status_code = VDEC_S_EFATAL; 9152 break; 9153 9154 } 9155 omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index; 9156 9157 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) { 9158 DEBUG_PRINT_HIGH("Unsupported input"); 9159 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 9160 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 9161 } 9162 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 9163 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 9164 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; 9165 } 9166 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 9167 9168 DEBUG_PRINT_LOW("Decrement codec_config buffer counter"); 9169 android_atomic_dec(&omx->m_queued_codec_config_count); 9170 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) && 9171 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) { 9172 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer"); 9173 sem_post(&omx->m_safe_flush); 9174 } 9175 } 9176 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || 9177 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 9178 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 9179 } 9180 omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code, 9181 OMX_COMPONENT_GENERATE_EBD); 9182 break; 9183 case VDEC_MSG_EVT_INFO_FIELD_DROPPED: 9184 int64_t *timestamp; 9185 timestamp = (int64_t *) malloc(sizeof(int64_t)); 9186 if (timestamp) { 9187 *timestamp = vdec_msg->msgdata.output_frame.time_stamp; 9188 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code, 9189 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); 9190 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", 9191 (long long)vdec_msg->msgdata.output_frame.time_stamp); 9192 } 9193 break; 9194 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 9195 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 9196 9197 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; 9198 if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL || 9199 v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) { 9200 omxhdr = NULL; 9201 vdec_msg->status_code = VDEC_S_EFATAL; 9202 break; 9203 } 9204 plane = v4l2_buf_ptr->m.planes; 9205 omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index; 9206 9207 if (omxhdr && omxhdr->pOutputPortPrivate && 9208 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) && 9209 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 9210 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) { 9211 9212 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) { 9213 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 9214 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 9215 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 9216 omxhdr->nFlags = 0; 9217 9218 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) { 9219 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; 9220 //rc = -1; 9221 } 9222 if (omxhdr->nFilledLen) { 9223 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; 9224 } 9225 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 9226 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 9227 } else { 9228 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; 9229 } 9230 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) { 9231 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 9232 } 9233 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) { 9234 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; 9235 } 9236 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) { 9237 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF; 9238 } 9239 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) { 9240 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY; 9241 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d", 9242 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd); 9243 } 9244 9245 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && 9246 !omx->output_flush_progress && 9247 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && 9248 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) { 9249 omx->time_stamp_dts.remove_time_stamp( 9250 omxhdr->nTimeStamp, 9251 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 9252 ?true:false); 9253 9254 omxhdr->nFilledLen = 0; 9255 omx->pending_output_buffers--; 9256 omx->post_event ((unsigned long)NULL,(unsigned long)omx->client_buffers.get_il_buf_hdr(omxhdr), 9257 OMX_COMPONENT_GENERATE_FTB); 9258 break; 9259 } 9260 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 9261 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 9262 } 9263 9264 output_respbuf = (struct vdec_output_frameinfo *)\ 9265 omxhdr->pOutputPortPrivate; 9266 if (!output_respbuf) { 9267 DEBUG_PRINT_ERROR("async_message_process: invalid output buf received"); 9268 return -1; 9269 } 9270 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 9271 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 9272 9273 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) { 9274 output_respbuf->pic_type = PICTURE_TYPE_I; 9275 } 9276 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) { 9277 output_respbuf->pic_type = PICTURE_TYPE_P; 9278 } 9279 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { 9280 output_respbuf->pic_type = PICTURE_TYPE_B; 9281 } 9282 9283 if (vdec_msg->msgdata.output_frame.len) { 9284 if (!omx->output_flush_progress && (omxhdr->nFilledLen > 0)) { 9285 // set the default colorspace advised by client, since the bitstream may be 9286 // devoid of colorspace-info. 9287 if (omx->m_enable_android_native_buffers) { 9288 ColorSpace_t color_space = ITU_R_601; 9289 9290 // Disabled ? 9291 // WA for VP8. Vp8 encoder does not embed color-info (yet!). 9292 // Encoding RGBA results in 601-LR for all resolutions. 9293 // This conflicts with the client't defaults which are based on resolution. 9294 // Eg: 720p will be encoded as 601-LR. Client will say 709. 9295 // Re-enable this code once vp8 encoder generates color-info and hence the 9296 // decoder will be able to override with the correct source color. 9297 #if 0 9298 switch (omx->m_client_color_space.sAspects.mPrimaries) { 9299 case ColorAspects::PrimariesBT601_6_625: 9300 case ColorAspects::PrimariesBT601_6_525: 9301 { 9302 color_space = omx->m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ? 9303 ITU_R_601_FR : ITU_R_601; 9304 break; 9305 } 9306 case ColorAspects::PrimariesBT709_5: 9307 { 9308 color_space = ITU_R_709; 9309 break; 9310 } 9311 default: 9312 { 9313 break; 9314 } 9315 } 9316 #endif 9317 DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)", 9318 color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); 9319 omx->set_colorspace_in_handle(color_space, omxhdr - omx->m_out_mem_ptr); 9320 } 9321 } 9322 9323 DEBUG_PRINT_LOW("Processing extradata"); 9324 omx->handle_extradata(omxhdr); 9325 9326 if (omx->m_extradata_info.output_crop_updated) { 9327 DEBUG_PRINT_LOW("Read FBD crop from output extra data"); 9328 vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft; 9329 vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop; 9330 vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth; 9331 vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight; 9332 vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width; 9333 vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height; 9334 } else { 9335 DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields"); 9336 vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2]; 9337 vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3]; 9338 vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4]; 9339 vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5]; 9340 vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6]; 9341 vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7]; 9342 9343 /* Copy these values back to OMX internal variables to make both handlign same*/ 9344 9345 omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left; 9346 omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top; 9347 omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right; 9348 omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; 9349 omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width; 9350 omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height; 9351 } 9352 } 9353 9354 vdec_msg->msgdata.output_frame.bufferaddr = 9355 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; 9356 9357 if (vdec_msg->msgdata.output_frame.len) 9358 memcpy(&omx->drv_ctx.frame_size, 9359 &vdec_msg->msgdata.output_frame.framesize, 9360 sizeof(struct vdec_framesize)); 9361 9362 DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)" 9363 " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)", 9364 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd, 9365 omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp, 9366 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags, 9367 (unsigned int)vdec_msg->msgdata.output_frame.len, 9368 vdec_msg->msgdata.output_frame.framesize.left, 9369 vdec_msg->msgdata.output_frame.framesize.top, 9370 vdec_msg->msgdata.output_frame.framesize.right, 9371 vdec_msg->msgdata.output_frame.framesize.bottom); 9372 9373 /* Post event if resolution OR crop changed */ 9374 /* filled length will be changed if resolution changed */ 9375 /* Crop parameters can be changed even without resolution change */ 9376 if (omxhdr->nFilledLen 9377 && ((omx->prev_n_filled_len != omxhdr->nFilledLen) 9378 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left) 9379 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top) 9380 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right) 9381 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom) 9382 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width) 9383 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) { 9384 9385 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", 9386 omx->prev_n_filled_len, 9387 omx->drv_ctx.video_resolution.frame_width, 9388 omx->drv_ctx.video_resolution.frame_height, 9389 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top, 9390 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom, 9391 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width, 9392 vdec_msg->msgdata.output_frame.picsize.frame_height, 9393 vdec_msg->msgdata.output_frame.framesize.left, 9394 vdec_msg->msgdata.output_frame.framesize.top, 9395 vdec_msg->msgdata.output_frame.framesize.right, 9396 vdec_msg->msgdata.output_frame.framesize.bottom); 9397 9398 omx->drv_ctx.video_resolution.frame_width = 9399 vdec_msg->msgdata.output_frame.picsize.frame_width; 9400 omx->drv_ctx.video_resolution.frame_height = 9401 vdec_msg->msgdata.output_frame.picsize.frame_height; 9402 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 9403 omx->drv_ctx.video_resolution.stride = 9404 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width); 9405 omx->drv_ctx.video_resolution.scan_lines = 9406 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height); 9407 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 9408 omx->drv_ctx.video_resolution.stride = 9409 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width); 9410 omx->drv_ctx.video_resolution.scan_lines = 9411 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height); 9412 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 9413 omx->drv_ctx.video_resolution.stride = 9414 VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width); 9415 omx->drv_ctx.video_resolution.scan_lines = 9416 VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height); 9417 } 9418 9419 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX, 9420 OMX_IndexConfigCommonOutputCrop, 9421 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 9422 } 9423 9424 if (omxhdr->nFilledLen) 9425 omx->prev_n_filled_len = omxhdr->nFilledLen; 9426 9427 if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) { 9428 omx->request_perf_level(VIDC_NOMINAL); 9429 } 9430 if (omx->output_use_buffer && omxhdr->pBuffer && 9431 vdec_msg->msgdata.output_frame.bufferaddr) 9432 memcpy ( omxhdr->pBuffer, (void *) 9433 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + 9434 (unsigned long)vdec_msg->msgdata.output_frame.offset), 9435 vdec_msg->msgdata.output_frame.len); 9436 } else { 9437 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u", 9438 (unsigned int)vdec_msg->msgdata.output_frame.len, 9439 omxhdr->nAllocLen, omx->prev_n_filled_len); 9440 omxhdr->nFilledLen = 0; 9441 } 9442 9443 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code, 9444 OMX_COMPONENT_GENERATE_FBD); 9445 9446 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) { 9447 omx->post_event ((unsigned long)NULL, vdec_msg->status_code, 9448 OMX_COMPONENT_GENERATE_EOS_DONE); 9449 } else { 9450 omx->post_event ((unsigned int)NULL, vdec_msg->status_code, 9451 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 9452 } 9453 break; 9454 case VDEC_MSG_EVT_CONFIG_CHANGED: 9455 DEBUG_PRINT_HIGH("Port settings changed"); 9456 omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width; 9457 omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height; 9458 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, 9459 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 9460 if (!omx->m_need_turbo) { 9461 omx->request_perf_level(VIDC_NOMINAL); 9462 } 9463 break; 9464 default: 9465 break; 9466 } 9467 return rc; 9468 } 9469 9470 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 9471 OMX_HANDLETYPE hComp, 9472 OMX_BUFFERHEADERTYPE *buffer 9473 ) 9474 { 9475 unsigned address,p2,id; 9476 DEBUG_PRINT_LOW("Empty this arbitrary"); 9477 9478 if (buffer == NULL) { 9479 return OMX_ErrorBadParameter; 9480 } 9481 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 9482 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld", 9483 (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp); 9484 9485 /* return zero length and not an EOS buffer */ 9486 /* return buffer if input flush in progress */ 9487 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && 9488 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) { 9489 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); 9490 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 9491 return OMX_ErrorNone; 9492 } 9493 9494 if (psource_frame == NULL) { 9495 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp); 9496 psource_frame = buffer; 9497 DEBUG_PRINT_LOW("Try to Push One Input Buffer "); 9498 push_input_buffer (hComp); 9499 } else { 9500 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); 9501 if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL, 9502 (unsigned)NULL)) { 9503 return OMX_ErrorBadParameter; 9504 } 9505 } 9506 9507 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 9508 codec_config_flag = false; 9509 } 9510 return OMX_ErrorNone; 9511 } 9512 9513 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 9514 { 9515 unsigned long address,p2,id; 9516 OMX_ERRORTYPE ret = OMX_ErrorNone; 9517 9518 if (pdest_frame == NULL || psource_frame == NULL) { 9519 /*Check if we have a destination buffer*/ 9520 if (pdest_frame == NULL) { 9521 DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); 9522 if (m_input_free_q.m_size) { 9523 m_input_free_q.pop_entry(&address,&p2,&id); 9524 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 9525 pdest_frame->nFilledLen = 0; 9526 pdest_frame->nTimeStamp = LLONG_MAX; 9527 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); 9528 } 9529 } 9530 9531 /*Check if we have a destination buffer*/ 9532 if (psource_frame == NULL) { 9533 DEBUG_PRINT_LOW("Get a source buffer from the queue"); 9534 if (m_input_pending_q.m_size) { 9535 m_input_pending_q.pop_entry(&address,&p2,&id); 9536 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 9537 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 9538 psource_frame->nTimeStamp); 9539 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 9540 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9541 9542 } 9543 } 9544 9545 } 9546 9547 while ((pdest_frame != NULL) && (psource_frame != NULL)) { 9548 switch (codec_type_parse) { 9549 case CODEC_TYPE_MPEG4: 9550 case CODEC_TYPE_H263: 9551 case CODEC_TYPE_MPEG2: 9552 ret = push_input_sc_codec(hComp); 9553 break; 9554 case CODEC_TYPE_H264: 9555 ret = push_input_h264(hComp); 9556 break; 9557 case CODEC_TYPE_HEVC: 9558 ret = push_input_hevc(hComp); 9559 break; 9560 case CODEC_TYPE_VC1: 9561 ret = push_input_vc1(hComp); 9562 break; 9563 default: 9564 break; 9565 } 9566 if (ret != OMX_ErrorNone) { 9567 DEBUG_PRINT_ERROR("Pushing input Buffer Failed"); 9568 omx_report_error (); 9569 break; 9570 } 9571 } 9572 9573 return ret; 9574 } 9575 9576 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 9577 { 9578 OMX_U32 partial_frame = 1; 9579 OMX_BOOL generate_ebd = OMX_TRUE; 9580 unsigned long address = 0, p2 = 0, id = 0; 9581 9582 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld", 9583 psource_frame,psource_frame->nTimeStamp); 9584 if (m_frame_parser.parse_sc_frame(psource_frame, 9585 pdest_frame,&partial_frame) == -1) { 9586 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9587 return OMX_ErrorBadParameter; 9588 } 9589 9590 if (partial_frame == 0) { 9591 DEBUG_PRINT_LOW("Frame size %u source %p frame count %d", 9592 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count); 9593 9594 9595 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp); 9596 /*First Parsed buffer will have only header Hence skip*/ 9597 if (frame_count == 0) { 9598 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); 9599 9600 if (codec_type_parse == CODEC_TYPE_MPEG4 || 9601 codec_type_parse == CODEC_TYPE_DIVX) { 9602 mp4StreamType psBits; 9603 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; 9604 psBits.numBytes = pdest_frame->nFilledLen; 9605 mp4_headerparser.parseHeader(&psBits); 9606 } 9607 9608 frame_count++; 9609 } else { 9610 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9611 if (pdest_frame->nFilledLen) { 9612 /*Push the frame to the Decoder*/ 9613 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9614 return OMX_ErrorBadParameter; 9615 } 9616 frame_count++; 9617 pdest_frame = NULL; 9618 9619 if (m_input_free_q.m_size) { 9620 m_input_free_q.pop_entry(&address,&p2,&id); 9621 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9622 pdest_frame->nFilledLen = 0; 9623 } 9624 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) { 9625 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL"); 9626 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL, 9627 (unsigned)NULL); 9628 pdest_frame = NULL; 9629 } 9630 } 9631 } else { 9632 DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen); 9633 /*Check if Destination Buffer is full*/ 9634 if (pdest_frame->nAllocLen == 9635 pdest_frame->nFilledLen + pdest_frame->nOffset) { 9636 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled"); 9637 return OMX_ErrorStreamCorrupt; 9638 } 9639 } 9640 9641 if (psource_frame->nFilledLen == 0) { 9642 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9643 if (pdest_frame) { 9644 pdest_frame->nFlags |= psource_frame->nFlags; 9645 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 9646 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld", 9647 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9648 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 9649 (unsigned int)pdest_frame->nFilledLen,frame_count++); 9650 /*Push the frame to the Decoder*/ 9651 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9652 return OMX_ErrorBadParameter; 9653 } 9654 frame_count++; 9655 pdest_frame = NULL; 9656 } else { 9657 DEBUG_PRINT_LOW("Last frame in else dest addr") ; 9658 generate_ebd = OMX_FALSE; 9659 } 9660 } 9661 if (generate_ebd) { 9662 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); 9663 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 9664 psource_frame = NULL; 9665 9666 if (m_input_pending_q.m_size) { 9667 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 9668 m_input_pending_q.pop_entry(&address,&p2,&id); 9669 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 9670 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 9671 psource_frame->nTimeStamp); 9672 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 9673 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9674 } 9675 } 9676 } 9677 return OMX_ErrorNone; 9678 } 9679 9680 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 9681 { 9682 OMX_U32 partial_frame = 1; 9683 unsigned long address = 0, p2 = 0, id = 0; 9684 OMX_BOOL isNewFrame = OMX_FALSE; 9685 OMX_BOOL generate_ebd = OMX_TRUE; 9686 9687 if (h264_scratch.pBuffer == NULL) { 9688 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated"); 9689 return OMX_ErrorBadParameter; 9690 } 9691 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u " 9692 "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal); 9693 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen); 9694 if (h264_scratch.nFilledLen && look_ahead_nal) { 9695 look_ahead_nal = false; 9696 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9697 h264_scratch.nFilledLen) { 9698 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9699 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9700 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9701 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); 9702 h264_scratch.nFilledLen = 0; 9703 } else { 9704 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264"); 9705 return OMX_ErrorBadParameter; 9706 } 9707 } 9708 9709 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result 9710 in EOS flag getting associated with the destination 9711 */ 9712 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) && 9713 pdest_frame->nFilledLen) { 9714 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'"); 9715 generate_ebd = OMX_FALSE; 9716 } 9717 9718 if (nal_length == 0) { 9719 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); 9720 if (m_frame_parser.parse_sc_frame(psource_frame, 9721 &h264_scratch,&partial_frame) == -1) { 9722 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9723 return OMX_ErrorBadParameter; 9724 } 9725 } else { 9726 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); 9727 if (m_frame_parser.parse_h264_nallength(psource_frame, 9728 &h264_scratch,&partial_frame) == -1) { 9729 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 9730 return OMX_ErrorBadParameter; 9731 } 9732 } 9733 9734 if (partial_frame == 0) { 9735 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 9736 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 9737 nal_count++; 9738 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 9739 h264_scratch.nFlags = psource_frame->nFlags; 9740 } else { 9741 DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen); 9742 if (h264_scratch.nFilledLen) { 9743 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, 9744 NALU_TYPE_SPS); 9745 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9746 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 9747 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 9748 h264_scratch.nFilledLen, NALU_TYPE_SEI); 9749 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 9750 // If timeinfo is present frame info from SEI is already processed 9751 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 9752 h264_scratch.nFilledLen, NALU_TYPE_SEI); 9753 #endif 9754 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 9755 nal_count++; 9756 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { 9757 pdest_frame->nTimeStamp = h264_last_au_ts; 9758 pdest_frame->nFlags = h264_last_au_flags; 9759 #ifdef PANSCAN_HDLR 9760 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 9761 h264_parser->update_panscan_data(h264_last_au_ts); 9762 #endif 9763 } 9764 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || 9765 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { 9766 h264_last_au_ts = h264_scratch.nTimeStamp; 9767 h264_last_au_flags = h264_scratch.nFlags; 9768 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9769 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 9770 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); 9771 if (!VALID_TS(h264_last_au_ts)) 9772 h264_last_au_ts = ts_in_sei; 9773 } 9774 #endif 9775 } else 9776 h264_last_au_ts = LLONG_MAX; 9777 } 9778 9779 if (!isNewFrame) { 9780 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9781 h264_scratch.nFilledLen) { 9782 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u", 9783 (unsigned int)h264_scratch.nFilledLen); 9784 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9785 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9786 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9787 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) 9788 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 9789 h264_scratch.nFilledLen = 0; 9790 } else { 9791 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264"); 9792 return OMX_ErrorBadParameter; 9793 } 9794 } else if(h264_scratch.nFilledLen) { 9795 look_ahead_nal = true; 9796 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu", 9797 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9798 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 9799 (unsigned int)pdest_frame->nFilledLen,frame_count++); 9800 9801 if (pdest_frame->nFilledLen == 0) { 9802 DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); 9803 look_ahead_nal = false; 9804 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9805 h264_scratch.nFilledLen) { 9806 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9807 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9808 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9809 h264_scratch.nFilledLen = 0; 9810 } else { 9811 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264"); 9812 return OMX_ErrorBadParameter; 9813 } 9814 } else { 9815 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 9816 DEBUG_PRINT_LOW("Reset the EOS Flag"); 9817 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9818 } 9819 /*Push the frame to the Decoder*/ 9820 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9821 return OMX_ErrorBadParameter; 9822 } 9823 //frame_count++; 9824 pdest_frame = NULL; 9825 if (m_input_free_q.m_size) { 9826 m_input_free_q.pop_entry(&address,&p2,&id); 9827 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9828 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); 9829 pdest_frame->nFilledLen = 0; 9830 pdest_frame->nFlags = 0; 9831 pdest_frame->nTimeStamp = LLONG_MAX; 9832 } 9833 } 9834 } 9835 } 9836 } else { 9837 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen); 9838 /*Check if Destination Buffer is full*/ 9839 if (h264_scratch.nAllocLen == 9840 h264_scratch.nFilledLen + h264_scratch.nOffset) { 9841 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 9842 return OMX_ErrorStreamCorrupt; 9843 } 9844 } 9845 9846 if (!psource_frame->nFilledLen) { 9847 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); 9848 9849 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9850 if (pdest_frame) { 9851 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 9852 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9853 h264_scratch.nFilledLen) { 9854 if(pdest_frame->nFilledLen == 0) { 9855 /* No residual frame from before, send whatever 9856 * we have left */ 9857 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9858 h264_scratch.pBuffer, h264_scratch.nFilledLen); 9859 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9860 h264_scratch.nFilledLen = 0; 9861 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 9862 } else { 9863 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 9864 if(!isNewFrame) { 9865 /* Have a residual frame, but we know that the 9866 * AU in this frame is belonging to whatever 9867 * frame we had left over. So append it */ 9868 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9869 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9870 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9871 h264_scratch.nFilledLen = 0; 9872 if (h264_last_au_ts != LLONG_MAX) 9873 pdest_frame->nTimeStamp = h264_last_au_ts; 9874 } else { 9875 /* Completely new frame, let's just push what 9876 * we have now. The resulting EBD would trigger 9877 * another push */ 9878 generate_ebd = OMX_FALSE; 9879 pdest_frame->nTimeStamp = h264_last_au_ts; 9880 h264_last_au_ts = h264_scratch.nTimeStamp; 9881 } 9882 } 9883 } else { 9884 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264"); 9885 return OMX_ErrorBadParameter; 9886 } 9887 9888 /* Iff we coalesced two buffers, inherit the flags of both bufs */ 9889 if(generate_ebd == OMX_TRUE) { 9890 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 9891 } 9892 9893 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu", 9894 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9895 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); 9896 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9897 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 9898 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); 9899 if (!VALID_TS(pdest_frame->nTimeStamp)) 9900 pdest_frame->nTimeStamp = ts_in_sei; 9901 } 9902 #endif 9903 /*Push the frame to the Decoder*/ 9904 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9905 return OMX_ErrorBadParameter; 9906 } 9907 frame_count++; 9908 pdest_frame = NULL; 9909 } else { 9910 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 9911 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 9912 generate_ebd = OMX_FALSE; 9913 } 9914 } 9915 } 9916 if (generate_ebd && !psource_frame->nFilledLen) { 9917 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 9918 psource_frame = NULL; 9919 if (m_input_pending_q.m_size) { 9920 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 9921 m_input_pending_q.pop_entry(&address,&p2,&id); 9922 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 9923 DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u", 9924 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9925 } 9926 } 9927 return OMX_ErrorNone; 9928 } 9929 9930 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) 9931 { 9932 OMX_ERRORTYPE rc = OMX_ErrorNone; 9933 if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) { 9934 memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); 9935 if (pDst->nTimeStamp == LLONG_MAX) { 9936 pDst->nTimeStamp = pSrc->nTimeStamp; 9937 DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp); 9938 } 9939 pDst->nFilledLen += pSrc->nFilledLen; 9940 pSrc->nFilledLen = 0; 9941 } else { 9942 DEBUG_PRINT_ERROR("Error: Destination buffer overflow"); 9943 rc = OMX_ErrorBadParameter; 9944 } 9945 return rc; 9946 } 9947 9948 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp) 9949 { 9950 OMX_U32 partial_frame = 1; 9951 unsigned long address,p2,id; 9952 OMX_BOOL isNewFrame = OMX_FALSE; 9953 OMX_BOOL generate_ebd = OMX_TRUE; 9954 OMX_ERRORTYPE rc = OMX_ErrorNone; 9955 if (h264_scratch.pBuffer == NULL) { 9956 DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated"); 9957 return OMX_ErrorBadParameter; 9958 } 9959 9960 DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \ 9961 pdest_frame nFilledLen %u nTimeStamp %lld", 9962 (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9963 9964 if (h264_scratch.nFilledLen && look_ahead_nal) { 9965 look_ahead_nal = false; 9966 rc = copy_buffer(pdest_frame, &h264_scratch); 9967 if (rc != OMX_ErrorNone) { 9968 return rc; 9969 } 9970 } 9971 9972 if (nal_length == 0) { 9973 if (m_frame_parser.parse_sc_frame(psource_frame, 9974 &h264_scratch,&partial_frame) == -1) { 9975 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9976 return OMX_ErrorBadParameter; 9977 } 9978 } else { 9979 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length); 9980 if (m_frame_parser.parse_h264_nallength(psource_frame, 9981 &h264_scratch,&partial_frame) == -1) { 9982 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 9983 return OMX_ErrorBadParameter; 9984 } 9985 } 9986 9987 if (partial_frame == 0) { 9988 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 9989 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 9990 nal_count++; 9991 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 9992 h264_scratch.nFlags = psource_frame->nFlags; 9993 } else { 9994 DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen); 9995 if (h264_scratch.nFilledLen) { 9996 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame); 9997 nal_count++; 9998 } 9999 10000 if (!isNewFrame) { 10001 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \ 10002 nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld", 10003 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp, 10004 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 10005 rc = copy_buffer(pdest_frame, &h264_scratch); 10006 if (rc != OMX_ErrorNone) { 10007 return rc; 10008 } 10009 } else { 10010 look_ahead_nal = true; 10011 if (pdest_frame->nFilledLen == 0) { 10012 look_ahead_nal = false; 10013 DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer"); 10014 rc = copy_buffer(pdest_frame, &h264_scratch); 10015 if (rc != OMX_ErrorNone) { 10016 return OMX_ErrorBadParameter; 10017 } 10018 } else { 10019 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 10020 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 10021 } 10022 DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \ 10023 nTimeStamp %lld, look_ahead_nal in h264_scratch \ 10024 nFilledLen %u nTimeStamp %lld", 10025 frame_count++, (unsigned int)pdest_frame->nFilledLen, 10026 pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen, 10027 h264_scratch.nTimeStamp); 10028 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 10029 return OMX_ErrorBadParameter; 10030 } 10031 pdest_frame = NULL; 10032 if (m_input_free_q.m_size) { 10033 m_input_free_q.pop_entry(&address, &p2, &id); 10034 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 10035 DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame); 10036 pdest_frame->nFilledLen = 0; 10037 pdest_frame->nFlags = 0; 10038 pdest_frame->nTimeStamp = LLONG_MAX; 10039 } 10040 } 10041 } 10042 } 10043 } else { 10044 DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \ 10045 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \ 10046 nFilledLen %u nTimeStamp %lld", 10047 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp, 10048 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp, 10049 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp); 10050 10051 if (h264_scratch.nAllocLen == 10052 h264_scratch.nFilledLen + h264_scratch.nOffset) { 10053 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 10054 return OMX_ErrorStreamCorrupt; 10055 } 10056 } 10057 10058 if (!psource_frame->nFilledLen) { 10059 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame); 10060 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 10061 if (pdest_frame) { 10062 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 10063 rc = copy_buffer(pdest_frame, &h264_scratch); 10064 if ( rc != OMX_ErrorNone ) { 10065 return rc; 10066 } 10067 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 10068 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 10069 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld", 10070 frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 10071 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 10072 return OMX_ErrorBadParameter; 10073 } 10074 frame_count++; 10075 pdest_frame = NULL; 10076 } else { 10077 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 10078 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 10079 generate_ebd = OMX_FALSE; 10080 } 10081 } 10082 } 10083 10084 if (generate_ebd && !psource_frame->nFilledLen) { 10085 m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame); 10086 psource_frame = NULL; 10087 if (m_input_pending_q.m_size) { 10088 m_input_pending_q.pop_entry(&address, &p2, &id); 10089 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 10090 DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld", 10091 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp); 10092 } 10093 } 10094 return OMX_ErrorNone; 10095 } 10096 10097 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp) 10098 { 10099 OMX_U8 *buf, *pdest; 10100 OMX_U32 partial_frame = 1; 10101 OMX_U32 buf_len, dest_len; 10102 10103 if (first_frame == 0) { 10104 first_frame = 1; 10105 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); 10106 if (!m_vendor_config.pData) { 10107 DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); 10108 buf = psource_frame->pBuffer; 10109 buf_len = psource_frame->nFilledLen; 10110 10111 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 10112 VC1_SP_MP_START_CODE) { 10113 m_vc1_profile = VC1_SP_MP_RCV; 10114 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) { 10115 m_vc1_profile = VC1_AP; 10116 } else { 10117 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer"); 10118 return OMX_ErrorStreamCorrupt; 10119 } 10120 } else { 10121 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 10122 pdest_frame->nOffset; 10123 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 10124 pdest_frame->nOffset); 10125 10126 if (dest_len < m_vendor_config.nDataSize) { 10127 DEBUG_PRINT_ERROR("Destination buffer full"); 10128 return OMX_ErrorBadParameter; 10129 } else { 10130 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 10131 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 10132 } 10133 } 10134 } 10135 10136 switch (m_vc1_profile) { 10137 case VC1_AP: 10138 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); 10139 if (push_input_sc_codec(hComp) != OMX_ErrorNone) { 10140 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code"); 10141 return OMX_ErrorBadParameter; 10142 } 10143 break; 10144 10145 case VC1_SP_MP_RCV: 10146 default: 10147 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode"); 10148 return OMX_ErrorBadParameter; 10149 } 10150 return OMX_ErrorNone; 10151 } 10152 10153 #ifndef USE_ION 10154 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 10155 OMX_U32 alignment) 10156 { 10157 struct pmem_allocation allocation; 10158 allocation.size = buffer_size; 10159 allocation.align = clip2(alignment); 10160 if (allocation.align < 4096) { 10161 allocation.align = 4096; 10162 } 10163 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) { 10164 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)", 10165 allocation.align, allocation.size); 10166 return false; 10167 } 10168 return true; 10169 } 10170 #endif 10171 #ifdef USE_ION 10172 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, 10173 OMX_U32 alignment, struct ion_allocation_data *alloc_data, 10174 struct ion_fd_data *fd_data, int flag) 10175 { 10176 int fd = -EINVAL; 10177 int rc = -EINVAL; 10178 int ion_dev_flag; 10179 struct vdec_ion ion_buf_info; 10180 if (!alloc_data || buffer_size <= 0 || !fd_data) { 10181 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory"); 10182 return -EINVAL; 10183 } 10184 ion_dev_flag = O_RDONLY; 10185 fd = open (MEM_DEVICE, ion_dev_flag); 10186 if (fd < 0) { 10187 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd); 10188 return fd; 10189 } 10190 10191 alloc_data->flags = flag; 10192 alloc_data->len = buffer_size; 10193 alloc_data->align = clip2(alignment); 10194 if (alloc_data->align < 4096) { 10195 alloc_data->align = 4096; 10196 } 10197 10198 alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID); 10199 if (secure_mode && (alloc_data->flags & ION_SECURE)) { 10200 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 10201 } 10202 10203 /* Use secure display cma heap for obvious reasons. */ 10204 if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) { 10205 alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID); 10206 } 10207 10208 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); 10209 if (rc || !alloc_data->handle) { 10210 DEBUG_PRINT_ERROR("ION ALLOC memory failed"); 10211 alloc_data->handle = 0; 10212 close(fd); 10213 fd = -ENOMEM; 10214 return fd; 10215 } 10216 fd_data->handle = alloc_data->handle; 10217 rc = ioctl(fd,ION_IOC_MAP,fd_data); 10218 if (rc) { 10219 DEBUG_PRINT_ERROR("ION MAP failed "); 10220 ion_buf_info.ion_alloc_data = *alloc_data; 10221 ion_buf_info.ion_device_fd = fd; 10222 ion_buf_info.fd_ion_data = *fd_data; 10223 free_ion_memory(&ion_buf_info); 10224 fd_data->fd =-1; 10225 fd = -ENOMEM; 10226 } 10227 10228 return fd; 10229 } 10230 10231 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) 10232 { 10233 10234 if (!buf_ion_info) { 10235 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata"); 10236 return; 10237 } 10238 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 10239 &buf_ion_info->ion_alloc_data.handle)) { 10240 DEBUG_PRINT_ERROR("ION: free failed" ); 10241 } 10242 close(buf_ion_info->ion_device_fd); 10243 buf_ion_info->ion_device_fd = -1; 10244 buf_ion_info->ion_alloc_data.handle = 0; 10245 buf_ion_info->fd_ion_data.fd = -1; 10246 } 10247 #endif 10248 void omx_vdec::free_output_buffer_header() 10249 { 10250 DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); 10251 output_use_buffer = false; 10252 ouput_egl_buffers = false; 10253 10254 if (m_out_mem_ptr) { 10255 free (m_out_mem_ptr); 10256 m_out_mem_ptr = NULL; 10257 } 10258 10259 if (m_platform_list) { 10260 free(m_platform_list); 10261 m_platform_list = NULL; 10262 } 10263 10264 if (drv_ctx.ptr_respbuffer) { 10265 free (drv_ctx.ptr_respbuffer); 10266 drv_ctx.ptr_respbuffer = NULL; 10267 } 10268 if (drv_ctx.ptr_outputbuffer) { 10269 free (drv_ctx.ptr_outputbuffer); 10270 drv_ctx.ptr_outputbuffer = NULL; 10271 } 10272 #ifdef USE_ION 10273 if (drv_ctx.op_buf_ion_info) { 10274 DEBUG_PRINT_LOW("Free o/p ion context"); 10275 free(drv_ctx.op_buf_ion_info); 10276 drv_ctx.op_buf_ion_info = NULL; 10277 } 10278 #endif 10279 free(drv_ctx.op_buf_map_info); 10280 drv_ctx.op_buf_map_info = NULL; 10281 buf_ref_remove(); 10282 } 10283 10284 void omx_vdec::free_input_buffer_header() 10285 { 10286 input_use_buffer = false; 10287 if (arbitrary_bytes) { 10288 if (m_inp_heap_ptr) { 10289 DEBUG_PRINT_LOW("Free input Heap Pointer"); 10290 free (m_inp_heap_ptr); 10291 m_inp_heap_ptr = NULL; 10292 } 10293 10294 if (m_phdr_pmem_ptr) { 10295 DEBUG_PRINT_LOW("Free input pmem header Pointer"); 10296 free (m_phdr_pmem_ptr); 10297 m_phdr_pmem_ptr = NULL; 10298 } 10299 } 10300 if (m_inp_mem_ptr) { 10301 DEBUG_PRINT_LOW("Free input pmem Pointer area"); 10302 free (m_inp_mem_ptr); 10303 m_inp_mem_ptr = NULL; 10304 } 10305 /* We just freed all the buffer headers, every thing in m_input_free_q, 10306 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */ 10307 while (m_input_free_q.m_size) { 10308 unsigned long address, p2, id; 10309 m_input_free_q.pop_entry(&address, &p2, &id); 10310 } 10311 while (m_input_pending_q.m_size) { 10312 unsigned long address, p2, id; 10313 m_input_pending_q.pop_entry(&address, &p2, &id); 10314 } 10315 pdest_frame = NULL; 10316 psource_frame = NULL; 10317 if (drv_ctx.ptr_inputbuffer) { 10318 DEBUG_PRINT_LOW("Free Driver Context pointer"); 10319 free (drv_ctx.ptr_inputbuffer); 10320 drv_ctx.ptr_inputbuffer = NULL; 10321 } 10322 #ifdef USE_ION 10323 if (drv_ctx.ip_buf_ion_info) { 10324 DEBUG_PRINT_LOW("Free ion context"); 10325 free(drv_ctx.ip_buf_ion_info); 10326 drv_ctx.ip_buf_ion_info = NULL; 10327 } 10328 #endif 10329 } 10330 10331 void omx_vdec::free_output_extradata_buffer_header() { 10332 client_extradata = false; 10333 if (m_client_output_extradata_mem_ptr) { 10334 DEBUG_PRINT_LOW("Free extradata pmem Pointer area"); 10335 free(m_client_output_extradata_mem_ptr); 10336 m_client_output_extradata_mem_ptr = NULL; 10337 } 10338 } 10339 10340 int omx_vdec::stream_off(OMX_U32 port) 10341 { 10342 enum v4l2_buf_type btype; 10343 int rc = 0; 10344 enum v4l2_ports v4l2_port = OUTPUT_PORT; 10345 10346 if (port == OMX_CORE_INPUT_PORT_INDEX) { 10347 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10348 v4l2_port = OUTPUT_PORT; 10349 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 10350 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10351 v4l2_port = CAPTURE_PORT; 10352 } else if (port == OMX_ALL) { 10353 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); 10354 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 10355 10356 if (!rc_input) 10357 return rc_input; 10358 else 10359 return rc_output; 10360 } 10361 10362 if (!streaming[v4l2_port]) { 10363 // already streamed off, warn and move on 10364 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," 10365 " which is already streamed off", v4l2_port); 10366 return 0; 10367 } 10368 10369 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); 10370 10371 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); 10372 if (rc) { 10373 /*TODO: How to handle this case */ 10374 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port); 10375 } else { 10376 streaming[v4l2_port] = false; 10377 } 10378 10379 return rc; 10380 } 10381 10382 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) 10383 { 10384 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10385 struct v4l2_requestbuffers bufreq; 10386 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0; 10387 unsigned int final_extra_data_size = 0; 10388 struct v4l2_format fmt; 10389 int ret = 0; 10390 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 10391 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10392 bufreq.memory = V4L2_MEMORY_USERPTR; 10393 bufreq.count = 1; 10394 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10395 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10396 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10397 fmt.fmt.pix_mp.pixelformat = output_capability; 10398 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10399 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10400 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10401 fmt.fmt.pix_mp.pixelformat = capture_capability; 10402 } else { 10403 eRet = OMX_ErrorBadParameter; 10404 } 10405 if (eRet==OMX_ErrorNone) { 10406 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10407 } 10408 if (ret) { 10409 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 10410 /*TODO: How to handle this case */ 10411 eRet = OMX_ErrorInsufficientResources; 10412 return eRet; 10413 } else { 10414 bool is_res_1080p_or_below = (drv_ctx.video_resolution.frame_width <= 1920 && 10415 drv_ctx.video_resolution.frame_height <= 1088) || 10416 (drv_ctx.video_resolution.frame_height <= 1088 && 10417 drv_ctx.video_resolution.frame_width <= 1920); 10418 10419 int fps = drv_ctx.frame_rate.fps_numerator / (float)drv_ctx.frame_rate.fps_denominator; 10420 bool fps_above_180 = (fps >= 180 || operating_frame_rate >= 180) ? true : false; 10421 bool increase_output = (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) && (bufreq.count >= 16); 10422 10423 if (increase_output && fps_above_180 && 10424 output_capability == V4L2_PIX_FMT_H264 && 10425 is_res_1080p_or_below) { 10426 m_need_turbo |= TURBO_MODE_HIGH_FPS; 10427 DEBUG_PRINT_LOW("High fps - fps = %d operating_rate = %d", fps, operating_frame_rate); 10428 DEBUG_PRINT_LOW("getbufreq[output]: Increase buffer count (%d) to (%d) to support high fps", 10429 bufreq.count, bufreq.count + 10); 10430 bufreq.count += 10; 10431 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10432 if (ret) { 10433 DEBUG_PRINT_ERROR("(Failed to set updated buffer count to driver"); 10434 eRet = OMX_ErrorInsufficientResources; 10435 return eRet; 10436 } 10437 DEBUG_PRINT_LOW("new buf count = %d set to driver", bufreq.count); 10438 request_perf_level(VIDC_TURBO); 10439 } 10440 10441 buffer_prop->actualcount = bufreq.count; 10442 buffer_prop->mincount = bufreq.count; 10443 DEBUG_PRINT_HIGH("Count = %d",bufreq.count); 10444 } 10445 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 10446 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10447 10448 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10449 10450 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 10451 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; 10452 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); 10453 10454 if (ret) { 10455 /*TODO: How to handle this case */ 10456 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 10457 eRet = OMX_ErrorInsufficientResources; 10458 } else { 10459 int extra_idx = 0; 10460 10461 eRet = is_video_session_supported(); 10462 if (eRet) 10463 return eRet; 10464 10465 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 10466 buf_size = buffer_prop->buffer_size; 10467 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 10468 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 10469 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 10470 } else if (extra_idx >= VIDEO_MAX_PLANES) { 10471 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 10472 return OMX_ErrorBadParameter; 10473 } 10474 10475 default_extra_data_size = VENUS_EXTRADATA_SIZE( 10476 drv_ctx.video_resolution.frame_height, 10477 drv_ctx.video_resolution.frame_width); 10478 final_extra_data_size = extra_data_size > default_extra_data_size ? 10479 extra_data_size : default_extra_data_size; 10480 10481 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) & 10482 (~(buffer_prop->alignment - 1)); 10483 10484 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size; 10485 drv_ctx.extradata_info.count = buffer_prop->actualcount; 10486 drv_ctx.extradata_info.buffer_size = final_extra_data_size; 10487 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 10488 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)", 10489 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size); 10490 if (extra_data_size) 10491 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)", 10492 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size); 10493 10494 if (in_reconfig) // BufReq will be set to driver when port is disabled 10495 buffer_prop->buffer_size = buf_size; 10496 else if (buf_size != buffer_prop->buffer_size) { 10497 buffer_prop->buffer_size = buf_size; 10498 eRet = set_buffer_req(buffer_prop); 10499 } 10500 } 10501 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)", 10502 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10503 return eRet; 10504 } 10505 10506 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) 10507 { 10508 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10509 unsigned buf_size = 0; 10510 struct v4l2_format fmt, c_fmt; 10511 struct v4l2_requestbuffers bufreq; 10512 int ret = 0; 10513 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)", 10514 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10515 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 10516 if (buf_size != buffer_prop->buffer_size) { 10517 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)", 10518 (unsigned int)buffer_prop->buffer_size, buf_size); 10519 eRet = OMX_ErrorBadParameter; 10520 } else { 10521 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 10522 memset(&c_fmt, 0x0, sizeof(struct v4l2_format)); 10523 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 10524 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 10525 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size; 10526 10527 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10528 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10529 fmt.fmt.pix_mp.pixelformat = output_capability; 10530 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 10531 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10532 c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10533 c_fmt.fmt.pix_mp.pixelformat = capture_capability; 10534 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt); 10535 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size; 10536 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt); 10537 } else { 10538 eRet = OMX_ErrorBadParameter; 10539 } 10540 10541 if (ret) { 10542 /*TODO: How to handle this case */ 10543 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); 10544 eRet = OMX_ErrorInsufficientResources; 10545 } 10546 10547 bufreq.memory = V4L2_MEMORY_USERPTR; 10548 bufreq.count = buffer_prop->actualcount; 10549 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10550 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10551 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10552 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10553 } else { 10554 eRet = OMX_ErrorBadParameter; 10555 } 10556 10557 if (eRet==OMX_ErrorNone) { 10558 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10559 } 10560 10561 if (ret) { 10562 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); 10563 /*TODO: How to handle this case */ 10564 eRet = OMX_ErrorInsufficientResources; 10565 } else if (bufreq.count < buffer_prop->actualcount) { 10566 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" 10567 " on v4l2 port %d to %d (prefers %d)", bufreq.type, 10568 buffer_prop->actualcount, bufreq.count); 10569 eRet = OMX_ErrorInsufficientResources; 10570 } else { 10571 if (!client_buffers.update_buffer_req()) { 10572 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); 10573 eRet = OMX_ErrorInsufficientResources; 10574 } 10575 } 10576 } 10577 return eRet; 10578 } 10579 10580 OMX_ERRORTYPE omx_vdec::update_picture_resolution() 10581 { 10582 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10583 return eRet; 10584 } 10585 10586 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 10587 { 10588 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10589 struct v4l2_format fmt; 10590 if (!portDefn) { 10591 return OMX_ErrorBadParameter; 10592 } 10593 DEBUG_PRINT_LOW("omx_vdec::update_portdef"); 10594 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 10595 portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 10596 portDefn->eDomain = OMX_PortDomainVideo; 10597 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 10598 if (0 == portDefn->nPortIndex) { 10599 portDefn->eDir = OMX_DirInput; 10600 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; 10601 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; 10602 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; 10603 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 10604 portDefn->format.video.eCompressionFormat = eCompressionFormat; 10605 //for input port, always report the fps value set by client, 10606 //to distinguish whether client got valid fps from parser. 10607 portDefn->format.video.xFramerate = m_fps_received; 10608 portDefn->bEnabled = m_inp_bEnabled; 10609 portDefn->bPopulated = m_inp_bPopulated; 10610 10611 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10612 fmt.fmt.pix_mp.pixelformat = output_capability; 10613 ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10614 } else if (1 == portDefn->nPortIndex) { 10615 unsigned int buf_size = 0; 10616 int ret = 0; 10617 if (in_reconfig && !is_down_scalar_enabled) { 10618 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10619 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10620 fmt.fmt.pix_mp.pixelformat = capture_capability; 10621 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10622 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 10623 } 10624 10625 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10626 fmt.fmt.pix_mp.pixelformat = capture_capability; 10627 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10628 if (ret) { 10629 DEBUG_PRINT_ERROR("Get Resolution failed"); 10630 return OMX_ErrorHardware; 10631 } 10632 drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 10633 if (!client_buffers.update_buffer_req()) { 10634 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed"); 10635 return OMX_ErrorHardware; 10636 } 10637 10638 if (!client_buffers.get_buffer_req(buf_size)) { 10639 DEBUG_PRINT_ERROR("update buffer requirements"); 10640 return OMX_ErrorHardware; 10641 } 10642 portDefn->nBufferSize = buf_size; 10643 portDefn->eDir = OMX_DirOutput; 10644 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; 10645 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; 10646 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 10647 if (drv_ctx.frame_rate.fps_denominator > 0) 10648 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator / 10649 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format 10650 else { 10651 DEBUG_PRINT_ERROR("Error: Divide by zero"); 10652 return OMX_ErrorBadParameter; 10653 } 10654 portDefn->bEnabled = m_out_bEnabled; 10655 portDefn->bPopulated = m_out_bPopulated; 10656 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { 10657 DEBUG_PRINT_ERROR("Error in getting color format"); 10658 return OMX_ErrorHardware; 10659 } 10660 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10661 fmt.fmt.pix_mp.pixelformat = capture_capability; 10662 } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) { 10663 portDefn->nBufferSize = m_client_out_extradata_info.getSize(); 10664 portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS; 10665 portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS; 10666 portDefn->eDir = OMX_DirOutput; 10667 } else { 10668 portDefn->eDir = OMX_DirMax; 10669 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 10670 (int)portDefn->nPortIndex); 10671 eRet = OMX_ErrorBadPortIndex; 10672 } 10673 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, 10674 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); 10675 10676 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; 10677 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; 10678 portDefn->format.video.nStride = drv_ctx.video_resolution.stride; 10679 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; 10680 10681 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) || 10682 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) { 10683 portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16); 10684 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height; 10685 } 10686 DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d " 10687 "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u", 10688 (unsigned int)portDefn->nPortIndex, 10689 (unsigned int)portDefn->format.video.nFrameWidth, 10690 (unsigned int)portDefn->format.video.nFrameHeight, 10691 (int)portDefn->format.video.nStride, 10692 (unsigned int)portDefn->format.video.nSliceHeight, 10693 (unsigned int)portDefn->format.video.eColorFormat, 10694 (unsigned int)portDefn->nBufferSize, 10695 (unsigned int)portDefn->nBufferCountActual); 10696 10697 return eRet; 10698 } 10699 10700 OMX_ERRORTYPE omx_vdec::allocate_output_headers() 10701 { 10702 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10703 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 10704 unsigned i = 0; 10705 10706 if (!m_out_mem_ptr) { 10707 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); 10708 int nBufHdrSize = 0; 10709 int nPlatformEntrySize = 0; 10710 int nPlatformListSize = 0; 10711 int nPMEMInfoSize = 0; 10712 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 10713 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 10714 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 10715 10716 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", 10717 drv_ctx.op_buf.actualcount); 10718 nBufHdrSize = drv_ctx.op_buf.actualcount * 10719 sizeof(OMX_BUFFERHEADERTYPE); 10720 10721 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 10722 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 10723 nPlatformListSize = drv_ctx.op_buf.actualcount * 10724 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 10725 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 10726 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 10727 10728 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 10729 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 10730 nPMEMInfoSize, 10731 nPlatformListSize); 10732 DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize, 10733 m_out_bm_count); 10734 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 10735 // Alloc mem for platform specific info 10736 char *pPtr=NULL; 10737 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 10738 nPMEMInfoSize,1); 10739 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 10740 calloc (sizeof(struct vdec_bufferpayload), 10741 drv_ctx.op_buf.actualcount); 10742 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 10743 calloc (sizeof (struct vdec_output_frameinfo), 10744 drv_ctx.op_buf.actualcount); 10745 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 10746 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer"); 10747 return OMX_ErrorInsufficientResources; 10748 } 10749 10750 #ifdef USE_ION 10751 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ 10752 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); 10753 if (!drv_ctx.op_buf_ion_info) { 10754 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 10755 return OMX_ErrorInsufficientResources; 10756 } 10757 #endif 10758 if (dynamic_buf_mode) { 10759 out_dynamic_list = (struct dynamic_buf_list *) \ 10760 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount); 10761 if (out_dynamic_list) { 10762 for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++) 10763 out_dynamic_list[i].dup_fd = -1; 10764 } 10765 } 10766 10767 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 10768 && drv_ctx.ptr_respbuffer) { 10769 bufHdr = m_out_mem_ptr; 10770 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 10771 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 10772 (((char *) m_platform_list) + nPlatformListSize); 10773 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 10774 (((char *) m_platform_entry) + nPlatformEntrySize); 10775 pPlatformList = m_platform_list; 10776 pPlatformEntry = m_platform_entry; 10777 pPMEMInfo = m_pmem_info; 10778 10779 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 10780 10781 // Settting the entire storage nicely 10782 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, 10783 m_out_mem_ptr,pPlatformEntry); 10784 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 10785 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 10786 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 10787 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 10788 // Set the values when we determine the right HxW param 10789 bufHdr->nAllocLen = 0; 10790 bufHdr->nFilledLen = 0; 10791 bufHdr->pAppPrivate = NULL; 10792 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10793 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 10794 pPlatformEntry->entry = pPMEMInfo; 10795 // Initialize the Platform List 10796 pPlatformList->nEntries = 1; 10797 pPlatformList->entryList = pPlatformEntry; 10798 // Keep pBuffer NULL till vdec is opened 10799 bufHdr->pBuffer = NULL; 10800 pPMEMInfo->offset = 0; 10801 pPMEMInfo->pmem_fd = -1; 10802 bufHdr->pPlatformPrivate = pPlatformList; 10803 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 10804 #ifdef USE_ION 10805 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 10806 #endif 10807 /*Create a mapping between buffers*/ 10808 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 10809 drv_ctx.ptr_respbuffer[i].client_data = (void *) \ 10810 &drv_ctx.ptr_outputbuffer[i]; 10811 // Move the buffer and buffer header pointers 10812 bufHdr++; 10813 pPMEMInfo++; 10814 pPlatformEntry++; 10815 pPlatformList++; 10816 } 10817 } else { 10818 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 10819 m_out_mem_ptr, pPtr); 10820 if (m_out_mem_ptr) { 10821 free(m_out_mem_ptr); 10822 m_out_mem_ptr = NULL; 10823 } 10824 if (pPtr) { 10825 free(pPtr); 10826 pPtr = NULL; 10827 } 10828 if (drv_ctx.ptr_outputbuffer) { 10829 free(drv_ctx.ptr_outputbuffer); 10830 drv_ctx.ptr_outputbuffer = NULL; 10831 } 10832 if (drv_ctx.ptr_respbuffer) { 10833 free(drv_ctx.ptr_respbuffer); 10834 drv_ctx.ptr_respbuffer = NULL; 10835 } 10836 #ifdef USE_ION 10837 if (drv_ctx.op_buf_ion_info) { 10838 DEBUG_PRINT_LOW("Free o/p ion context"); 10839 free(drv_ctx.op_buf_ion_info); 10840 drv_ctx.op_buf_ion_info = NULL; 10841 } 10842 #endif 10843 free(drv_ctx.op_buf_map_info); 10844 drv_ctx.op_buf_map_info = NULL; 10845 eRet = OMX_ErrorInsufficientResources; 10846 } 10847 } else { 10848 eRet = OMX_ErrorInsufficientResources; 10849 } 10850 return eRet; 10851 } 10852 10853 void omx_vdec::complete_pending_buffer_done_cbs() 10854 { 10855 unsigned long p1, p2, ident; 10856 omx_cmd_queue tmp_q, pending_bd_q; 10857 pthread_mutex_lock(&m_lock); 10858 // pop all pending GENERATE FDB from ftb queue 10859 while (m_ftb_q.m_size) { 10860 m_ftb_q.pop_entry(&p1,&p2,&ident); 10861 if (ident == OMX_COMPONENT_GENERATE_FBD) { 10862 pending_bd_q.insert_entry(p1,p2,ident); 10863 } else { 10864 tmp_q.insert_entry(p1,p2,ident); 10865 } 10866 } 10867 //return all non GENERATE FDB to ftb queue 10868 while (tmp_q.m_size) { 10869 tmp_q.pop_entry(&p1,&p2,&ident); 10870 m_ftb_q.insert_entry(p1,p2,ident); 10871 } 10872 // pop all pending GENERATE EDB from etb queue 10873 while (m_etb_q.m_size) { 10874 m_etb_q.pop_entry(&p1,&p2,&ident); 10875 if (ident == OMX_COMPONENT_GENERATE_EBD) { 10876 pending_bd_q.insert_entry(p1,p2,ident); 10877 } else { 10878 tmp_q.insert_entry(p1,p2,ident); 10879 } 10880 } 10881 //return all non GENERATE FDB to etb queue 10882 while (tmp_q.m_size) { 10883 tmp_q.pop_entry(&p1,&p2,&ident); 10884 m_etb_q.insert_entry(p1,p2,ident); 10885 } 10886 pthread_mutex_unlock(&m_lock); 10887 // process all pending buffer dones 10888 while (pending_bd_q.m_size) { 10889 pending_bd_q.pop_entry(&p1,&p2,&ident); 10890 switch (ident) { 10891 case OMX_COMPONENT_GENERATE_EBD: 10892 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 10893 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); 10894 omx_report_error (); 10895 } 10896 break; 10897 10898 case OMX_COMPONENT_GENERATE_FBD: 10899 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 10900 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); 10901 omx_report_error (); 10902 } 10903 break; 10904 } 10905 } 10906 } 10907 10908 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) 10909 { 10910 OMX_U32 new_frame_interval = 0; 10911 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts 10912 && llabs(act_timestamp - prev_ts) > 2000) { 10913 new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ? 10914 llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual); 10915 if (new_frame_interval != frm_int || frm_int == 0) { 10916 frm_int = new_frame_interval; 10917 if (frm_int) { 10918 drv_ctx.frame_rate.fps_numerator = 1e6; 10919 drv_ctx.frame_rate.fps_denominator = frm_int; 10920 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", 10921 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 10922 (float)drv_ctx.frame_rate.fps_denominator); 10923 m_perf_control.request_cores(frm_int); 10924 /* We need to report the difference between this FBD and the previous FBD 10925 * back to the driver for clock scaling purposes. */ 10926 struct v4l2_outputparm oparm; 10927 /*XXX: we're providing timing info as seconds per frame rather than frames 10928 * per second.*/ 10929 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 10930 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 10931 10932 struct v4l2_streamparm sparm; 10933 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10934 sparm.parm.output = oparm; 10935 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 10936 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 10937 performance might be affected"); 10938 } 10939 10940 } 10941 } 10942 } 10943 prev_ts = act_timestamp; 10944 } 10945 10946 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) 10947 { 10948 if (rst_prev_ts && VALID_TS(act_timestamp)) { 10949 prev_ts = act_timestamp; 10950 prev_ts_actual = act_timestamp; 10951 rst_prev_ts = false; 10952 } else if (VALID_TS(prev_ts)) { 10953 bool codec_cond = (drv_ctx.timestamp_adjust)? 10954 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) : 10955 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual); 10956 prev_ts_actual = act_timestamp; //unadjusted previous timestamp 10957 if (frm_int > 0 && codec_cond) { 10958 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); 10959 act_timestamp = prev_ts + frm_int; 10960 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); 10961 prev_ts = act_timestamp; 10962 } else { 10963 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) { 10964 // ensure that timestamps can never step backwards when in display order 10965 act_timestamp = prev_ts; 10966 } 10967 set_frame_rate(act_timestamp); 10968 } 10969 } else if (frm_int > 0) // In this case the frame rate was set along 10970 { // with the port definition, start ts with 0 10971 act_timestamp = prev_ts = 0; // and correct if a valid ts is received. 10972 rst_prev_ts = true; 10973 } 10974 } 10975 10976 OMX_BUFFERHEADERTYPE* omx_vdec::get_omx_output_buffer_header(int index) 10977 { 10978 return m_out_mem_ptr + index; 10979 } 10980 10981 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range, 10982 OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects) 10983 { 10984 switch (primaries) { 10985 case MSM_VIDC_BT709_5: 10986 *color_space = ITU_R_709; 10987 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 10988 break; 10989 case MSM_VIDC_BT470_6_M: 10990 aspects->mPrimaries = ColorAspects::PrimariesBT470_6M; 10991 break; 10992 case MSM_VIDC_BT601_6_625: 10993 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 10994 break; 10995 case MSM_VIDC_BT601_6_525: 10996 *color_space = range ? ITU_R_601_FR : ITU_R_601; 10997 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525; 10998 break; 10999 case MSM_VIDC_GENERIC_FILM: 11000 aspects->mPrimaries = ColorAspects::PrimariesGenericFilm; 11001 break; 11002 case MSM_VIDC_BT2020: 11003 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 11004 break; 11005 case MSM_VIDC_UNSPECIFIED: 11006 //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default 11007 default: 11008 //aspects->mPrimaries = ColorAspects::PrimariesOther; 11009 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 11010 break; 11011 } 11012 11013 aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited; 11014 11015 switch (transfer) { 11016 case MSM_VIDC_TRANSFER_BT709_5: 11017 case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625: 11018 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11019 break; 11020 case MSM_VIDC_TRANSFER_BT_470_6_M: 11021 aspects->mTransfer = ColorAspects::TransferGamma22; 11022 break; 11023 case MSM_VIDC_TRANSFER_BT_470_6_BG: 11024 aspects->mTransfer = ColorAspects::TransferGamma28; 11025 break; 11026 case MSM_VIDC_TRANSFER_SMPTE_240M: 11027 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 11028 break; 11029 case MSM_VIDC_TRANSFER_LINEAR: 11030 aspects->mTransfer = ColorAspects::TransferLinear; 11031 break; 11032 case MSM_VIDC_TRANSFER_IEC_61966: 11033 aspects->mTransfer = ColorAspects::TransferXvYCC; 11034 break; 11035 case MSM_VIDC_TRANSFER_BT_1361: 11036 aspects->mTransfer = ColorAspects::TransferBT1361; 11037 break; 11038 case MSM_VIDC_TRANSFER_SRGB: 11039 aspects->mTransfer = ColorAspects::TransferSRGB; 11040 break; 11041 case MSM_VIDC_TRANSFER_SMPTE_ST2084: 11042 aspects->mTransfer = ColorAspects::TransferST2084; 11043 break; 11044 case MSM_VIDC_TRANSFER_HLG: 11045 aspects->mTransfer = ColorAspects::TransferHLG; 11046 break; 11047 default: 11048 //aspects->mTransfer = ColorAspects::TransferOther; 11049 aspects->mTransfer = m_client_color_space.sAspects.mTransfer; 11050 break; 11051 } 11052 11053 switch (matrix) { 11054 case MSM_VIDC_MATRIX_BT_709_5: 11055 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 11056 break; 11057 case MSM_VIDC_MATRIX_FCC_47: 11058 aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M; 11059 break; 11060 case MSM_VIDC_MATRIX_601_6_625: 11061 case MSM_VIDC_MATRIX_601_6_525: 11062 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 11063 break; 11064 case MSM_VIDC_MATRIX_SMPTE_240M: 11065 aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M; 11066 break; 11067 case MSM_VIDC_MATRIX_BT_2020: 11068 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 11069 break; 11070 case MSM_VIDC_MATRIX_BT_2020_CONST: 11071 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant; 11072 break; 11073 default: 11074 //aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 11075 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 11076 break; 11077 } 11078 } 11079 11080 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) { 11081 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)", 11082 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange), 11083 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs)); 11084 } 11085 11086 void omx_vdec::prepare_color_aspects_metadata(OMX_U32 primaries, OMX_U32 range, 11087 OMX_U32 transfer, OMX_U32 matrix, 11088 ColorMetaData *color_mdata) 11089 { 11090 11091 /* ColorAspects in qdMetaData */ 11092 color_mdata->colorPrimaries = (enum ColorPrimaries) primaries; 11093 color_mdata->range = (enum ColorRange)range; 11094 color_mdata->transfer = (enum GammaTransfer)transfer; 11095 color_mdata->matrixCoefficients = (enum MatrixCoEfficients)matrix; 11096 } 11097 11098 bool omx_vdec::handle_color_space_info(void *data, 11099 ColorSpace_t *color_space, 11100 ColorMetaData *color_mdata, 11101 bool& set_color_aspects_only) 11102 { 11103 ColorAspects tempAspects; 11104 memset(&tempAspects, 0x0, sizeof(ColorAspects)); 11105 ColorAspects *aspects = &tempAspects; 11106 11107 /* Set default ColorAspects */ 11108 prepare_color_aspects_metadata(ColorPrimaries_BT601_6_625, Range_Full, 11109 Transfer_SMPTE_170M, MatrixCoEff_BT601_6_625, 11110 color_mdata); 11111 11112 switch(output_capability) { 11113 case V4L2_PIX_FMT_MPEG2: 11114 { 11115 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload; 11116 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data; 11117 11118 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to 11119 * understand this code */ 11120 11121 if (seqdisp_payload && seqdisp_payload->color_descp) { 11122 11123 convert_color_space_info(seqdisp_payload->color_primaries, 1, 11124 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs, 11125 color_space,aspects); 11126 m_disp_hor_size = seqdisp_payload->disp_width; 11127 m_disp_vert_size = seqdisp_payload->disp_height; 11128 set_color_aspects_only = true; 11129 prepare_color_aspects_metadata(seqdisp_payload->color_primaries, 1, 11130 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs, 11131 color_mdata); 11132 } 11133 } 11134 break; 11135 case V4L2_PIX_FMT_H264: 11136 case V4L2_PIX_FMT_HEVC: 11137 { 11138 struct msm_vidc_vui_display_info_payload *display_info_payload; 11139 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data; 11140 11141 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */ 11142 11143 if (display_info_payload->video_signal_present_flag && 11144 display_info_payload->color_description_present_flag) { 11145 convert_color_space_info(display_info_payload->color_primaries, 11146 display_info_payload->video_full_range_flag, 11147 display_info_payload->transfer_characteristics, 11148 display_info_payload->matrix_coefficients, 11149 color_space,aspects); 11150 set_color_aspects_only = true; 11151 prepare_color_aspects_metadata(display_info_payload->color_primaries, 11152 display_info_payload->video_full_range_flag, 11153 display_info_payload->transfer_characteristics, 11154 display_info_payload->matrix_coefficients, 11155 color_mdata); 11156 } 11157 } 11158 break; 11159 case V4L2_PIX_FMT_VC1_ANNEX_G: 11160 case V4L2_PIX_FMT_VC1_ANNEX_L: 11161 { 11162 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload; 11163 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data; 11164 11165 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23 11166 * SMPTE 421M to understand this code */ 11167 11168 if (m_enable_android_native_buffers && 11169 vc1_seq_disp_payload->color_primaries) { 11170 11171 convert_color_space_info(vc1_seq_disp_payload->color_primaries, 11172 1, 11173 vc1_seq_disp_payload->transfer_char, 11174 vc1_seq_disp_payload->matrix_coeffs, 11175 color_space,aspects); 11176 set_color_aspects_only = true; 11177 prepare_color_aspects_metadata(vc1_seq_disp_payload->color_primaries, 11178 1, 11179 vc1_seq_disp_payload->transfer_char, 11180 vc1_seq_disp_payload->matrix_coeffs, 11181 color_mdata); 11182 } 11183 } 11184 break; 11185 case V4L2_PIX_FMT_VP8: 11186 { 11187 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 11188 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 11189 set_color_aspects_only = false; 11190 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011 11191 * to understand this code */ 11192 11193 if (vpx_color_space_payload->color_space == 0) { 11194 *color_space = ITU_R_601; 11195 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525; 11196 aspects->mRange = ColorAspects::RangeLimited; 11197 } else { 11198 DEBUG_PRINT_ERROR("Unsupported Color space for VP8"); 11199 break; 11200 } 11201 } 11202 break; 11203 case V4L2_PIX_FMT_VP9: 11204 { 11205 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 11206 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 11207 set_color_aspects_only = false; 11208 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016 11209 * to understand this code */ 11210 11211 switch(vpx_color_space_payload->color_space) { 11212 case MSM_VIDC_CS_BT_601: 11213 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 11214 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11215 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 11216 aspects->mRange = m_client_color_space.sAspects.mRange; 11217 break; 11218 case MSM_VIDC_CS_BT_709: 11219 *color_space = ITU_R_709; 11220 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 11221 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11222 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 11223 aspects->mRange = m_client_color_space.sAspects.mRange; 11224 break; 11225 case MSM_VIDC_CS_SMPTE_170: 11226 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 11227 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11228 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 11229 aspects->mRange = m_client_color_space.sAspects.mRange; 11230 break; 11231 case MSM_VIDC_CS_SMPTE_240: 11232 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 11233 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 11234 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 11235 aspects->mRange = m_client_color_space.sAspects.mRange; 11236 break; 11237 case MSM_VIDC_CS_BT_2020: 11238 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 11239 aspects->mTransfer = ColorAspects:: TransferSMPTE170M; 11240 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 11241 aspects->mRange = m_client_color_space.sAspects.mRange; 11242 break; 11243 case MSM_VIDC_CS_RESERVED: 11244 aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 11245 aspects->mTransfer = ColorAspects::TransferOther; 11246 aspects->mPrimaries = ColorAspects::PrimariesOther; 11247 aspects->mRange = m_client_color_space.sAspects.mRange; 11248 break; 11249 case MSM_VIDC_CS_RGB: 11250 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 11251 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11252 aspects->mPrimaries = ColorAspects::PrimariesOther; 11253 aspects->mRange = m_client_color_space.sAspects.mRange; 11254 break; 11255 default: 11256 break; 11257 } 11258 } 11259 break; 11260 default: 11261 break; 11262 } 11263 11264 print_debug_color_aspects(aspects, "Bitstream"); 11265 11266 if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries || 11267 m_internal_color_space.sAspects.mTransfer != aspects->mTransfer || 11268 m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs || 11269 m_internal_color_space.sAspects.mRange != aspects->mRange) { 11270 memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects)); 11271 11272 m_color_mdata.colorPrimaries = color_mdata->colorPrimaries; 11273 m_color_mdata.range = color_mdata->range; 11274 m_color_mdata.transfer = color_mdata->transfer; 11275 m_color_mdata.matrixCoefficients = color_mdata->matrixCoefficients; 11276 11277 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change"); 11278 print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal"); 11279 print_debug_color_aspects(&(m_client_color_space.sAspects), "Client"); 11280 11281 post_event(OMX_CORE_OUTPUT_PORT_INDEX, 11282 OMX_QTIIndexConfigDescribeColorAspects, 11283 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 11284 return true; 11285 } 11286 return false; 11287 } 11288 11289 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) { 11290 private_handle_t *private_handle = NULL; 11291 if (buf_index < drv_ctx.op_buf.actualcount && 11292 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 11293 native_buffer[buf_index].privatehandle) { 11294 private_handle = native_buffer[buf_index].privatehandle; 11295 } 11296 if (private_handle) { 11297 setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space); 11298 } 11299 } 11300 11301 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix) 11302 { 11303 if (!hdr_info->mID) { 11304 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix, 11305 hdr_info->sType1.mR.x, hdr_info->sType1.mR.y); 11306 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix, 11307 hdr_info->sType1.mG.x, hdr_info->sType1.mG.y); 11308 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix, 11309 hdr_info->sType1.mB.x, hdr_info->sType1.mB.y); 11310 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix, 11311 hdr_info->sType1.mW.x, hdr_info->sType1.mW.y); 11312 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix, 11313 hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance); 11314 DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix, 11315 hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel); 11316 } 11317 11318 } 11319 11320 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata) 11321 { 11322 DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u", 11323 color_mdata->colorPrimaries, color_mdata->range, 11324 color_mdata->transfer, color_mdata->matrixCoefficients); 11325 11326 for(uint8_t i = 0; i < 3; i++) { 11327 for(uint8_t j = 0; j < 2; j++) { 11328 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]); 11329 } 11330 } 11331 11332 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d", 11333 color_mdata->masteringDisplayInfo.primaries.whitePoint[0], 11334 color_mdata->masteringDisplayInfo.primaries.whitePoint[1]); 11335 11336 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d", 11337 color_mdata->masteringDisplayInfo.maxDisplayLuminance, 11338 color_mdata->masteringDisplayInfo.minDisplayLuminance); 11339 11340 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d", 11341 color_mdata->contentLightLevel.maxContentLightLevel, 11342 color_mdata->contentLightLevel.minPicAverageLightLevel); 11343 11344 11345 } 11346 11347 bool omx_vdec::handle_content_light_level_info(void* data, ContentLightLevel* light_level_mdata) 11348 { 11349 struct msm_vidc_content_light_level_sei_payload *light_level_payload = 11350 (msm_vidc_content_light_level_sei_payload*)(data); 11351 11352 light_level_mdata->lightLevelSEIEnabled = true; 11353 light_level_mdata->maxContentLightLevel = light_level_payload->nMaxContentLight; 11354 light_level_mdata->minPicAverageLightLevel = light_level_payload->nMaxPicAverageLight; 11355 11356 if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) || 11357 (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) { 11358 m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight; 11359 m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight; 11360 return true; 11361 } 11362 return false; 11363 } 11364 11365 bool omx_vdec::handle_mastering_display_color_info(void* data, MasteringDisplay* mastering_display_mdata) 11366 { 11367 struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload = 11368 (msm_vidc_mastering_display_colour_sei_payload*)(data); 11369 HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo; 11370 bool internal_disp_changed_flag = false; 11371 11372 mastering_display_mdata->colorVolumeSEIEnabled = true; 11373 for (uint8_t i = 0; i < 3; i++) { 11374 mastering_display_mdata->primaries.rgbPrimaries[i][0] = mastering_display_payload->nDisplayPrimariesX[i]; 11375 mastering_display_mdata->primaries.rgbPrimaries[i][1] = mastering_display_payload->nDisplayPrimariesY[i]; 11376 } 11377 mastering_display_mdata->primaries.whitePoint[0] = mastering_display_payload->nWhitePointX; 11378 mastering_display_mdata->primaries.whitePoint[1] = mastering_display_payload->nWhitePointY; 11379 mastering_display_mdata->maxDisplayLuminance = mastering_display_payload->nMaxDisplayMasteringLuminance; 11380 mastering_display_mdata->minDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance; 11381 11382 internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[0]) || 11383 (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[0]); 11384 internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[1]) || 11385 (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[1]); 11386 internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[2]) || 11387 (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[2]); 11388 11389 internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) || 11390 (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY); 11391 11392 /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension 11393 requires it in cd/m2, so dividing by 10000 and rounding the value after division 11394 */ 11395 uint16_t max_display_luminance_cd_m2 = 11396 static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5); 11397 internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) || 11398 (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance); 11399 11400 if (internal_disp_changed_flag) { 11401 hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[0]; 11402 hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[0]; 11403 hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[1]; 11404 hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[1]; 11405 hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[2]; 11406 hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[2]; 11407 hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX; 11408 hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY; 11409 11410 hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2; 11411 hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance; 11412 } 11413 11414 return internal_disp_changed_flag; 11415 } 11416 11417 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index) 11418 { 11419 private_handle_t *private_handle = NULL; 11420 if (buf_index < drv_ctx.op_buf.actualcount && 11421 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 11422 native_buffer[buf_index].privatehandle) { 11423 private_handle = native_buffer[buf_index].privatehandle; 11424 } 11425 if (private_handle) { 11426 setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata); 11427 } 11428 } 11429 11430 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) 11431 { 11432 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL; 11433 OMX_U8 *pBuffer = NULL; 11434 OMX_U32 num_conceal_MB = 0; 11435 OMX_TICKS time_stamp = 0; 11436 OMX_U32 frame_rate = 0; 11437 unsigned long consumed_len = 0; 11438 OMX_U32 num_MB_in_frame; 11439 OMX_U32 recovery_sei_flags = 1; 11440 int enable = OMX_InterlaceFrameProgressive; 11441 bool internal_hdr_info_changed_flag = false; 11442 bool color_event = false; 11443 ColorMetaData color_mdata; 11444 memset(&color_mdata, 0x0, sizeof(ColorMetaData)); 11445 bool set_disp_color_aspects_only = false; 11446 ColorSpace_t color_space = ITU_R_601; 11447 11448 int buf_index = p_buf_hdr - m_out_mem_ptr; 11449 if (buf_index >= drv_ctx.extradata_info.count) { 11450 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)", 11451 buf_index, drv_ctx.extradata_info.count); 11452 return; 11453 } 11454 struct msm_vidc_panscan_window_payload *panscan_payload = NULL; 11455 11456 if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) { 11457 DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL"); 11458 return; 11459 } 11460 11461 if (!drv_ctx.extradata_info.uaddr) { 11462 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr"); 11463 return; 11464 } 11465 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) { 11466 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data"); 11467 p_extra = NULL; 11468 return; 11469 } 11470 if (!secure_mode) { 11471 pBuffer = (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len, 11472 PROT_READ|PROT_WRITE, MAP_SHARED, drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0); 11473 if (pBuffer == MAP_FAILED) { 11474 DEBUG_PRINT_ERROR("handle_extradata output buffer mmap failed - errno: %d", errno); 11475 return; 11476 } 11477 p_extra = (OMX_OTHER_EXTRADATATYPE *) 11478 ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); 11479 } else 11480 p_extra = m_other_extradata; 11481 11482 AutoUnmap autounmap(pBuffer, drv_ctx.ptr_outputbuffer[buf_index].buffer_len); 11483 if (m_client_output_extradata_mem_ptr && 11484 m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) { 11485 p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer); 11486 } 11487 11488 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; 11489 11490 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 11491 p_extra = NULL; 11492 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 11493 return; 11494 } 11495 m_extradata_info.output_crop_updated = OMX_FALSE; 11496 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; 11497 if (data && p_extra) { 11498 while ((consumed_len < drv_ctx.extradata_info.buffer_size) 11499 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) { 11500 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) { 11501 DEBUG_PRINT_LOW("Invalid extra data size"); 11502 break; 11503 } 11504 11505 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 11506 p_extra = NULL; 11507 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 11508 return; 11509 } 11510 11511 DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType); 11512 switch ((unsigned long)data->eType) { 11513 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO: 11514 struct msm_vidc_interlace_payload *payload; 11515 OMX_U32 interlace_color_format; 11516 payload = (struct msm_vidc_interlace_payload *)(void *)data->data; 11517 if (payload) { 11518 enable = OMX_InterlaceFrameProgressive; 11519 switch (payload->format) { 11520 case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE: 11521 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11522 break; 11523 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST: 11524 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 11525 enable = OMX_InterlaceInterleaveFrameTopFieldFirst; 11526 break; 11527 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST: 11528 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst; 11529 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst; 11530 break; 11531 default: 11532 DEBUG_PRINT_LOW("default case - set to progressive"); 11533 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11534 } 11535 switch (payload->color_format) { 11536 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12: 11537 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11538 break; 11539 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC: 11540 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 11541 break; 11542 default: 11543 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11544 DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame"); 11545 } 11546 } 11547 11548 if (m_enable_android_native_buffers) { 11549 DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d", 11550 payload->format, interlace_color_format ,enable, 11551 (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false); 11552 11553 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11554 PP_PARAM_INTERLACED, (void*)&enable); 11555 11556 if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 11557 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11558 LINEAR_FORMAT, (void*)&interlace_color_format); 11559 } else if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 11560 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11561 LINEAR_FORMAT, NULL); 11562 } 11563 } 11564 if (client_extradata & OMX_INTERLACE_EXTRADATA) { 11565 append_interlace_extradata(p_extra, payload->format); 11566 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11567 if (p_client_extra) { 11568 append_interlace_extradata(p_client_extra, payload->format); 11569 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) 11570 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11571 } 11572 } 11573 break; 11574 case MSM_VIDC_EXTRADATA_FRAME_RATE: 11575 struct msm_vidc_framerate_payload *frame_rate_payload; 11576 frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data; 11577 frame_rate = frame_rate_payload->frame_rate; 11578 break; 11579 case MSM_VIDC_EXTRADATA_TIMESTAMP: 11580 struct msm_vidc_ts_payload *time_stamp_payload; 11581 time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data; 11582 time_stamp = time_stamp_payload->timestamp_lo; 11583 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); 11584 p_buf_hdr->nTimeStamp = time_stamp; 11585 break; 11586 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB: 11587 struct msm_vidc_concealmb_payload *conceal_mb_payload; 11588 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data; 11589 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 11590 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 11591 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); 11592 break; 11593 case MSM_VIDC_EXTRADATA_INDEX: 11594 int *etype; 11595 etype = (int *)(void *)data->data; 11596 if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) { 11597 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; 11598 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype); 11599 if (aspect_ratio_payload) { 11600 ((struct vdec_output_frameinfo *) 11601 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; 11602 ((struct vdec_output_frameinfo *) 11603 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; 11604 } 11605 } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) { 11606 struct msm_vidc_output_crop_payload *output_crop_payload; 11607 output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype); 11608 if (output_crop_payload) { 11609 m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left; 11610 m_extradata_info.output_crop_rect.nTop = output_crop_payload->top; 11611 m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width; 11612 m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height; 11613 m_extradata_info.output_width = output_crop_payload->width; 11614 m_extradata_info.output_height = output_crop_payload->height; 11615 m_extradata_info.output_crop_updated = OMX_TRUE; 11616 } 11617 } 11618 break; 11619 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI: 11620 struct msm_vidc_recoverysei_payload *recovery_sei_payload; 11621 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data; 11622 recovery_sei_flags = recovery_sei_payload->flags; 11623 if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) { 11624 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 11625 DEBUG_PRINT_HIGH("***************************************************"); 11626 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 11627 DEBUG_PRINT_HIGH("***************************************************"); 11628 } 11629 break; 11630 case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW: 11631 panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data; 11632 if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) { 11633 DEBUG_PRINT_ERROR("Panscan windows are more than supported\n"); 11634 DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n", 11635 MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows); 11636 return; 11637 } 11638 break; 11639 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP: 11640 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO: 11641 case MSM_VIDC_EXTRADATA_VC1_SEQDISP: 11642 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO: 11643 color_event = handle_color_space_info((void *)data->data, &color_space, &color_mdata, set_disp_color_aspects_only); 11644 break; 11645 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING: 11646 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload; 11647 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data; 11648 switch (s3d_frame_packing_payload->fpa_type) { 11649 case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE: 11650 if (s3d_frame_packing_payload->content_interprtation_type == 1) 11651 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R; 11652 else if (s3d_frame_packing_payload->content_interprtation_type == 2) 11653 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L; 11654 else { 11655 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type"); 11656 stereo_output_mode = HAL_NO_3D; 11657 } 11658 break; 11659 case MSM_VIDC_FRAMEPACK_TOP_BOTTOM: 11660 stereo_output_mode = HAL_3D_TOP_BOTTOM; 11661 break; 11662 default: 11663 DEBUG_PRINT_ERROR("Unsupported framepacking type"); 11664 stereo_output_mode = HAL_NO_3D; 11665 } 11666 DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d", 11667 s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode); 11668 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) { 11669 append_framepack_extradata(p_extra, s3d_frame_packing_payload); 11670 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11671 if (p_client_extra) { 11672 append_framepack_extradata(p_client_extra, s3d_frame_packing_payload); 11673 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11674 } 11675 } 11676 break; 11677 case MSM_VIDC_EXTRADATA_FRAME_QP: 11678 struct msm_vidc_frame_qp_payload *qp_payload; 11679 qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data; 11680 if (client_extradata & OMX_QP_EXTRADATA) { 11681 append_qp_extradata(p_extra, qp_payload); 11682 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11683 if (p_client_extra) { 11684 append_qp_extradata(p_client_extra, qp_payload); 11685 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11686 } 11687 } 11688 break; 11689 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO: 11690 struct msm_vidc_frame_bits_info_payload *bits_info_payload; 11691 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data; 11692 if (client_extradata & OMX_BITSINFO_EXTRADATA) { 11693 append_bitsinfo_extradata(p_extra, bits_info_payload); 11694 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11695 if (p_client_extra) { 11696 append_bitsinfo_extradata(p_client_extra, bits_info_payload); 11697 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11698 } 11699 } 11700 break; 11701 case MSM_VIDC_EXTRADATA_STREAM_USERDATA: 11702 if (client_extradata & OMX_EXTNUSER_EXTRADATA) { 11703 append_user_extradata(p_extra, data); 11704 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11705 if (p_client_extra) { 11706 append_user_extradata(p_client_extra, data); 11707 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11708 } 11709 } 11710 break; 11711 case MSM_VIDC_EXTRADATA_VQZIP_SEI: 11712 struct msm_vidc_vqzip_sei_payload *vqzip_payload; 11713 vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data; 11714 if (client_extradata & OMX_VQZIPSEI_EXTRADATA) { 11715 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11716 append_vqzip_extradata(p_extra, vqzip_payload); 11717 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11718 if (p_client_extra) { 11719 append_vqzip_extradata(p_client_extra, vqzip_payload); 11720 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11721 } 11722 } 11723 break; 11724 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: 11725 11726 internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data, 11727 &(color_mdata.contentLightLevel)); 11728 break; 11729 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI: 11730 internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data, 11731 &(color_mdata.masteringDisplayInfo)); 11732 break; 11733 default: 11734 DEBUG_PRINT_LOW("Unrecognized extradata"); 11735 goto unrecognized_extradata; 11736 } 11737 consumed_len += data->nSize; 11738 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 11739 } 11740 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) { 11741 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11742 append_frame_info_extradata(p_extra, 11743 num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 11744 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *) 11745 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 11746 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11747 if (p_client_extra) { 11748 append_frame_info_extradata(p_client_extra, 11749 num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 11750 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *) 11751 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 11752 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11753 } 11754 } 11755 if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) { 11756 append_frame_dimension_extradata(p_extra); 11757 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11758 if (p_client_extra) { 11759 append_frame_dimension_extradata(p_client_extra); 11760 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11761 } 11762 } 11763 11764 if(internal_hdr_info_changed_flag) { 11765 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal"); 11766 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client"); 11767 memcpy(&m_color_mdata, &color_mdata, sizeof(ColorMetaData)); 11768 auto_lock lock(m_hdr_info_client_lock); 11769 m_change_client_hdr_info = true; 11770 if(!color_event) { 11771 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change"); 11772 post_event(OMX_CORE_OUTPUT_PORT_INDEX, 11773 OMX_QTIIndexConfigDescribeHDRColorInfo, 11774 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 11775 } 11776 } 11777 11778 if (m_enable_android_native_buffers) { 11779 if (set_disp_color_aspects_only) { 11780 print_debug_hdr_color_info_mdata(&m_color_mdata); 11781 set_colormetadata_in_handle(&m_color_mdata, buf_index); 11782 } else { 11783 DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x (601=%u FR=%u 709=%u)", color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); 11784 set_colorspace_in_handle(color_space, buf_index); 11785 } 11786 } 11787 11788 } 11789 unrecognized_extradata: 11790 if (client_extradata && p_extra) { 11791 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11792 append_terminator_extradata(p_extra); 11793 if (p_client_extra) { 11794 append_terminator_extradata(p_client_extra); 11795 } 11796 } 11797 if (secure_mode && p_extradata && m_other_extradata) { 11798 struct vdec_output_frameinfo *ptr_extradatabuff = NULL; 11799 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size); 11800 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate; 11801 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata; 11802 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size; 11803 ptr_extradatabuff->metadata_info.fd = drv_ctx.extradata_info.ion.fd_ion_data.fd; 11804 ptr_extradatabuff->metadata_info.offset = buf_index * drv_ctx.extradata_info.buffer_size; 11805 ptr_extradatabuff->metadata_info.buffer_size = drv_ctx.extradata_info.size; 11806 } 11807 return; 11808 } 11809 11810 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata, 11811 bool is_internal, bool enable) 11812 { 11813 OMX_ERRORTYPE ret = OMX_ErrorNone; 11814 struct v4l2_control control; 11815 if (m_state != OMX_StateLoaded) { 11816 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); 11817 return OMX_ErrorIncorrectStateOperation; 11818 } 11819 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d", 11820 (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal); 11821 11822 if (!is_internal) { 11823 if (enable) 11824 client_extradata |= requested_extradata; 11825 else 11826 client_extradata = client_extradata & ~requested_extradata; 11827 } 11828 11829 if (enable) { 11830 if (requested_extradata & OMX_INTERLACE_EXTRADATA) { 11831 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11832 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; 11833 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11834 DEBUG_PRINT_HIGH("Failed to set interlaced extradata." 11835 " Quality of interlaced clips might be impacted."); 11836 } 11837 } 11838 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) { 11839 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11840 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; 11841 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11842 DEBUG_PRINT_HIGH("Failed to set framerate extradata"); 11843 } 11844 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11845 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; 11846 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11847 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata"); 11848 } 11849 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11850 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; 11851 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11852 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata"); 11853 } 11854 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11855 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; 11856 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11857 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11858 } 11859 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11860 control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO; 11861 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11862 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11863 } 11864 if (output_capability == V4L2_PIX_FMT_MPEG2) { 11865 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11866 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 11867 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11868 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11869 } 11870 } 11871 } 11872 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) { 11873 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11874 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; 11875 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11876 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata"); 11877 } 11878 } 11879 if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) { 11880 if (output_capability == V4L2_PIX_FMT_H264) { 11881 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA"); 11882 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11883 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING; 11884 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11885 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata"); 11886 } 11887 } else { 11888 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only"); 11889 } 11890 } 11891 if (requested_extradata & OMX_QP_EXTRADATA) { 11892 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11893 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 11894 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11895 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 11896 } 11897 } 11898 if (requested_extradata & OMX_BITSINFO_EXTRADATA) { 11899 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11900 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO; 11901 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11902 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata"); 11903 } 11904 } 11905 if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) { 11906 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11907 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA; 11908 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11909 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata"); 11910 } 11911 } 11912 if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) { 11913 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11914 control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI; 11915 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11916 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata"); 11917 } 11918 client_extradata |= OMX_VQZIPSEI_EXTRADATA; 11919 11920 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11921 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 11922 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11923 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 11924 } 11925 client_extradata |= OMX_QP_EXTRADATA; 11926 } 11927 if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) { 11928 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11929 control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP; 11930 DEBUG_PRINT_LOW("Enable output crop extra data"); 11931 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11932 DEBUG_PRINT_HIGH("Failed to set output crop extradata"); 11933 } 11934 } 11935 if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) { 11936 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11937 switch(output_capability) { 11938 case V4L2_PIX_FMT_H264: 11939 case V4L2_PIX_FMT_HEVC: 11940 control.value = V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY; 11941 break; 11942 case CODEC_TYPE_MPEG2: 11943 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 11944 break; 11945 case V4L2_PIX_FMT_VP8: 11946 case V4L2_PIX_FMT_VP9: 11947 control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE; 11948 break; 11949 case V4L2_PIX_FMT_VC1_ANNEX_G: 11950 case V4L2_PIX_FMT_VC1_ANNEX_L: 11951 control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP; 11952 break; 11953 default: 11954 DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind); 11955 return ret; 11956 } 11957 11958 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11959 DEBUG_PRINT_HIGH("Failed to set Display info extradata"); 11960 } 11961 } 11962 if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) { 11963 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11964 if (output_capability == V4L2_PIX_FMT_H264 || 11965 output_capability == V4L2_PIX_FMT_HEVC) { 11966 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI; 11967 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11968 DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata"); 11969 } 11970 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI; 11971 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11972 DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata"); 11973 } 11974 } 11975 } 11976 } 11977 ret = get_buffer_req(&drv_ctx.op_buf); 11978 return ret; 11979 } 11980 11981 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11982 { 11983 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; 11984 OMX_U8 *data_ptr = extra->data, data = 0; 11985 while (byte_count < extra->nDataSize) { 11986 data = *data_ptr; 11987 while (data) { 11988 num_MB += (data&0x01); 11989 data >>= 1; 11990 } 11991 data_ptr++; 11992 byte_count++; 11993 } 11994 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 11995 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 11996 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); 11997 } 11998 11999 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12000 { 12001 if (!m_debug_extradata || !extra) 12002 return; 12003 12004 12005 DEBUG_PRINT_HIGH( 12006 "============== Extra Data ==============\n" 12007 " Size: %u\n" 12008 " Version: %u\n" 12009 " PortIndex: %u\n" 12010 " Type: %x\n" 12011 " DataSize: %u", 12012 (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion, 12013 (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize); 12014 12015 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) { 12016 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 12017 DEBUG_PRINT_HIGH( 12018 "------ Interlace Format ------\n" 12019 " Size: %u\n" 12020 " Version: %u\n" 12021 " PortIndex: %u\n" 12022 " Is Interlace Format: %d\n" 12023 " Interlace Formats: %u\n" 12024 "=========== End of Interlace ===========", 12025 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex, 12026 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats); 12027 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) { 12028 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 12029 12030 DEBUG_PRINT_HIGH( 12031 "-------- Frame Format --------\n" 12032 " Picture Type: %d\n" 12033 " Interlace Type: %d\n" 12034 " Pan Scan Total Frame Num: %u\n" 12035 " Concealed Macro Blocks: %u\n" 12036 " Recovery SEI Flag: %u\n" 12037 " frame rate: %u\n" 12038 " Time Stamp: %llu\n" 12039 " Aspect Ratio X: %u\n" 12040 " Aspect Ratio Y: %u", 12041 fminfo->ePicType, 12042 fminfo->interlaceType, 12043 (unsigned int)fminfo->panScan.numWindows, 12044 (unsigned int)fminfo->nConcealedMacroblocks, 12045 (unsigned int)fminfo->nRecoverySeiFlag, 12046 (unsigned int)fminfo->nFrameRate, 12047 fminfo->nTimeStamp, 12048 (unsigned int)fminfo->aspectRatio.aspectRatioX, 12049 (unsigned int)fminfo->aspectRatio.aspectRatioY); 12050 12051 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) { 12052 DEBUG_PRINT_HIGH( 12053 "------------------------------" 12054 " Pan Scan Frame Num: %u\n" 12055 " Rectangle x: %d\n" 12056 " Rectangle y: %d\n" 12057 " Rectangle dx: %d\n" 12058 " Rectangle dy: %d", 12059 (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y, 12060 (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy); 12061 } 12062 12063 DEBUG_PRINT_HIGH("========= End of Frame Format =========="); 12064 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) { 12065 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 12066 DEBUG_PRINT_HIGH( 12067 "------------------ Framepack Format ----------\n" 12068 " id: %u \n" 12069 " cancel_flag: %u \n" 12070 " type: %u \n" 12071 " quincunx_sampling_flagFormat: %u \n" 12072 " content_interpretation_type: %u \n" 12073 " spatial_flipping_flag: %u \n" 12074 " frame0_flipped_flag: %u \n" 12075 " field_views_flag: %u \n" 12076 " current_frame_is_frame0_flag: %u \n" 12077 " frame0_self_contained_flag: %u \n" 12078 " frame1_self_contained_flag: %u \n" 12079 " frame0_grid_position_x: %u \n" 12080 " frame0_grid_position_y: %u \n" 12081 " frame1_grid_position_x: %u \n" 12082 " frame1_grid_position_y: %u \n" 12083 " reserved_byte: %u \n" 12084 " repetition_period: %u \n" 12085 " extension_flag: %u \n" 12086 "================== End of Framepack ===========", 12087 (unsigned int)framepack->id, 12088 (unsigned int)framepack->cancel_flag, 12089 (unsigned int)framepack->type, 12090 (unsigned int)framepack->quincunx_sampling_flag, 12091 (unsigned int)framepack->content_interpretation_type, 12092 (unsigned int)framepack->spatial_flipping_flag, 12093 (unsigned int)framepack->frame0_flipped_flag, 12094 (unsigned int)framepack->field_views_flag, 12095 (unsigned int)framepack->current_frame_is_frame0_flag, 12096 (unsigned int)framepack->frame0_self_contained_flag, 12097 (unsigned int)framepack->frame1_self_contained_flag, 12098 (unsigned int)framepack->frame0_grid_position_x, 12099 (unsigned int)framepack->frame0_grid_position_y, 12100 (unsigned int)framepack->frame1_grid_position_x, 12101 (unsigned int)framepack->frame1_grid_position_y, 12102 (unsigned int)framepack->reserved_byte, 12103 (unsigned int)framepack->repetition_period, 12104 (unsigned int)framepack->extension_flag); 12105 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) { 12106 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 12107 DEBUG_PRINT_HIGH( 12108 "---- QP (Frame quantization parameter) ----\n" 12109 " Frame QP: %u \n" 12110 "================ End of QP ================\n", 12111 (unsigned int)qp->nQP); 12112 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) { 12113 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data; 12114 DEBUG_PRINT_HIGH( 12115 "--------- Input bits information --------\n" 12116 " Header bits: %u \n" 12117 " Frame bits: %u \n" 12118 "===== End of Input bits information =====\n", 12119 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits); 12120 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) { 12121 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data; 12122 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data; 12123 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type); 12124 OMX_U32 i = 0; 12125 DEBUG_PRINT_HIGH( 12126 "-------------- Userdata -------------\n" 12127 " Stream userdata type: %u\n" 12128 " userdata size: %u\n" 12129 " STREAM_USERDATA:", 12130 (unsigned int)userdata->type, (unsigned int)userdata_size); 12131 for (i = 0; i < userdata_size; i+=4) { 12132 DEBUG_PRINT_HIGH(" %x %x %x %x", 12133 data_ptr[i], data_ptr[i+1], 12134 data_ptr[i+2], data_ptr[i+3]); 12135 } 12136 DEBUG_PRINT_HIGH( 12137 "=========== End of Userdata ==========="); 12138 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) { 12139 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 12140 DEBUG_PRINT_HIGH( 12141 "-------------- VQZip -------------\n" 12142 " Size: %u\n", 12143 (unsigned int)vq->nSize); 12144 DEBUG_PRINT_HIGH( "=========== End of VQZip ==========="); 12145 } else if (extra->eType == OMX_ExtraDataNone) { 12146 DEBUG_PRINT_HIGH("========== End of Terminator ==========="); 12147 } else { 12148 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); 12149 } 12150 } 12151 12152 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12153 OMX_U32 interlaced_format_type) 12154 { 12155 OMX_STREAMINTERLACEFORMAT *interlace_format; 12156 12157 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { 12158 return; 12159 } 12160 if (!extra) { 12161 DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input"); 12162 return; 12163 } 12164 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; 12165 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12166 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12167 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; 12168 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); 12169 interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 12170 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); 12171 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; 12172 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12173 12174 if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) { 12175 interlace_format->bInterlaceFormat = OMX_FALSE; 12176 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 12177 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 12178 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) { 12179 interlace_format->bInterlaceFormat = OMX_TRUE; 12180 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 12181 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 12182 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) { 12183 interlace_format->bInterlaceFormat = OMX_TRUE; 12184 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst; 12185 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst; 12186 } else { 12187 //default case - set to progressive 12188 interlace_format->bInterlaceFormat = OMX_FALSE; 12189 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 12190 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 12191 } 12192 print_debug_extradata(extra); 12193 } 12194 12195 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12196 { 12197 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension; 12198 if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) { 12199 return; 12200 } 12201 extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE; 12202 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12203 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12204 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension; 12205 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION); 12206 frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data; 12207 frame_dimension->nDecWidth = rectangle.nLeft; 12208 frame_dimension->nDecHeight = rectangle.nTop; 12209 frame_dimension->nActualWidth = rectangle.nWidth; 12210 frame_dimension->nActualHeight = rectangle.nHeight; 12211 } 12212 12213 void omx_vdec::fill_aspect_ratio_info( 12214 struct vdec_aspectratioinfo *aspect_ratio_info, 12215 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 12216 { 12217 m_extradata = frame_info; 12218 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; 12219 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; 12220 DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX, 12221 (unsigned int)m_extradata->aspectRatio.aspectRatioY); 12222 } 12223 12224 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12225 OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate, 12226 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload, 12227 struct vdec_aspectratioinfo *aspect_ratio_info) 12228 { 12229 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; 12230 struct msm_vidc_panscan_window *panscan_window; 12231 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { 12232 return; 12233 } 12234 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; 12235 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12236 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12237 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; 12238 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); 12239 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 12240 switch (picture_type) { 12241 case PICTURE_TYPE_I: 12242 frame_info->ePicType = OMX_VIDEO_PictureTypeI; 12243 break; 12244 case PICTURE_TYPE_P: 12245 frame_info->ePicType = OMX_VIDEO_PictureTypeP; 12246 break; 12247 case PICTURE_TYPE_B: 12248 frame_info->ePicType = OMX_VIDEO_PictureTypeB; 12249 break; 12250 default: 12251 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; 12252 } 12253 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 12254 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 12255 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 12256 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 12257 else 12258 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; 12259 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); 12260 frame_info->nConcealedMacroblocks = num_conceal_mb; 12261 frame_info->nRecoverySeiFlag = recovery_sei_flag; 12262 frame_info->nFrameRate = frame_rate; 12263 frame_info->nTimeStamp = time_stamp; 12264 frame_info->panScan.numWindows = 0; 12265 if (output_capability == V4L2_PIX_FMT_MPEG2) { 12266 if (m_disp_hor_size && m_disp_vert_size) { 12267 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; 12268 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; 12269 } else { 12270 frame_info->displayAspectRatio.displayHorizontalSize = 0; 12271 frame_info->displayAspectRatio.displayVerticalSize = 0; 12272 } 12273 } 12274 12275 if (panscan_payload) { 12276 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; 12277 panscan_window = &panscan_payload->wnd[0]; 12278 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) { 12279 frame_info->panScan.window[i].x = panscan_window->panscan_window_width; 12280 frame_info->panScan.window[i].y = panscan_window->panscan_window_height; 12281 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; 12282 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; 12283 panscan_window++; 12284 } 12285 } 12286 fill_aspect_ratio_info(aspect_ratio_info, frame_info); 12287 print_debug_extradata(extra); 12288 } 12289 12290 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12291 { 12292 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; 12293 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; 12294 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12295 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12296 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; 12297 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 12298 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data; 12299 *portDefn = m_port_def; 12300 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u " 12301 "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight, 12302 (unsigned int)portDefn->format.video.nFrameWidth, 12303 (unsigned int)portDefn->format.video.nStride, 12304 (unsigned int)portDefn->format.video.nSliceHeight); 12305 } 12306 12307 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12308 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload) 12309 { 12310 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack; 12311 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) { 12312 DEBUG_PRINT_ERROR("frame packing size mismatch"); 12313 return; 12314 } 12315 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE; 12316 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12317 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12318 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement; 12319 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 12320 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 12321 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 12322 framepack->nVersion.nVersion = OMX_SPEC_VERSION; 12323 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12324 memcpy(&framepack->id, s3d_frame_packing_payload, 12325 sizeof(struct msm_vidc_s3d_frame_packing_payload)); 12326 memcpy(&m_frame_pack_arrangement, framepack, 12327 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 12328 print_debug_extradata(extra); 12329 } 12330 12331 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12332 struct msm_vidc_frame_qp_payload *qp_payload) 12333 { 12334 OMX_QCOM_EXTRADATA_QP * qp = NULL; 12335 if (!qp_payload) { 12336 DEBUG_PRINT_ERROR("QP payload is NULL"); 12337 return; 12338 } 12339 extra->nSize = OMX_QP_EXTRADATA_SIZE; 12340 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12341 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12342 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP; 12343 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP); 12344 qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 12345 qp->nQP = qp_payload->frame_qp; 12346 print_debug_extradata(extra); 12347 } 12348 12349 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12350 struct msm_vidc_frame_bits_info_payload *bits_payload) 12351 { 12352 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL; 12353 if (!bits_payload) { 12354 DEBUG_PRINT_ERROR("bits info payload is NULL"); 12355 return; 12356 } 12357 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE; 12358 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12359 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12360 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo; 12361 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO); 12362 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data; 12363 bits->frame_bits = bits_payload->frame_bits; 12364 bits->header_bits = bits_payload->header_bits; 12365 print_debug_extradata(extra); 12366 } 12367 12368 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12369 OMX_OTHER_EXTRADATATYPE *p_user) 12370 { 12371 int userdata_size = 0; 12372 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL; 12373 userdata_payload = 12374 (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data; 12375 userdata_size = p_user->nDataSize; 12376 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size; 12377 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12378 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12379 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData; 12380 extra->nDataSize = userdata_size; 12381 if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize)) 12382 memcpy(extra->data, p_user->data, extra->nDataSize); 12383 print_debug_extradata(extra); 12384 } 12385 12386 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12387 { 12388 if (!client_extradata) { 12389 return; 12390 } 12391 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 12392 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12393 extra->eType = OMX_ExtraDataNone; 12394 extra->nDataSize = 0; 12395 extra->data[0] = 0; 12396 12397 print_debug_extradata(extra); 12398 } 12399 12400 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12401 struct msm_vidc_vqzip_sei_payload *vqzip_payload) 12402 { 12403 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL; 12404 12405 extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size; 12406 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12407 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12408 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI; 12409 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size; 12410 12411 vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 12412 vq->nSize = vqzip_payload->size; 12413 memcpy(vq->data, vqzip_payload->data, vqzip_payload->size); 12414 12415 print_debug_extradata(extra); 12416 } 12417 12418 OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) 12419 { 12420 OMX_ERRORTYPE eRet = OMX_ErrorNone; 12421 if (index >= drv_ctx.ip_buf.actualcount) { 12422 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found"); 12423 return OMX_ErrorInsufficientResources; 12424 } 12425 if (m_desc_buffer_ptr == NULL) { 12426 m_desc_buffer_ptr = (desc_buffer_hdr*) \ 12427 calloc( (sizeof(desc_buffer_hdr)), 12428 drv_ctx.ip_buf.actualcount); 12429 if (m_desc_buffer_ptr == NULL) { 12430 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed "); 12431 return OMX_ErrorInsufficientResources; 12432 } 12433 } 12434 12435 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); 12436 if (m_desc_buffer_ptr[index].buf_addr == NULL) { 12437 DEBUG_PRINT_ERROR("desc buffer Allocation failed "); 12438 return OMX_ErrorInsufficientResources; 12439 } 12440 12441 return eRet; 12442 } 12443 12444 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) 12445 { 12446 DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries); 12447 if (m_demux_entries < 8192) { 12448 m_demux_offsets[m_demux_entries++] = address_offset; 12449 } 12450 return; 12451 } 12452 12453 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) 12454 { 12455 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; 12456 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; 12457 OMX_U32 index = 0; 12458 12459 m_demux_entries = 0; 12460 12461 while (index < bytes_to_parse) { 12462 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 12463 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || 12464 ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 12465 (buf[index+2] == 0x01)) ) { 12466 //Found start code, insert address offset 12467 insert_demux_addr_offset(index); 12468 if (buf[index+2] == 0x01) // 3 byte start code 12469 index += 3; 12470 else //4 byte start code 12471 index += 4; 12472 } else 12473 index++; 12474 } 12475 DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries); 12476 return; 12477 } 12478 12479 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) 12480 { 12481 //fix this, handle 3 byte start code, vc1 terminator entry 12482 OMX_U8 *p_demux_data = NULL; 12483 OMX_U32 desc_data = 0; 12484 OMX_U32 start_addr = 0; 12485 OMX_U32 nal_size = 0; 12486 OMX_U32 suffix_byte = 0; 12487 OMX_U32 demux_index = 0; 12488 OMX_U32 buffer_index = 0; 12489 12490 if (m_desc_buffer_ptr == NULL) { 12491 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); 12492 return OMX_ErrorBadParameter; 12493 } 12494 12495 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 12496 if (buffer_index > drv_ctx.ip_buf.actualcount) { 12497 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index); 12498 return OMX_ErrorBadParameter; 12499 } 12500 12501 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; 12502 12503 if ( ((OMX_U8*)p_demux_data == NULL) || 12504 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) { 12505 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); 12506 return OMX_ErrorBadParameter; 12507 } else { 12508 for (; demux_index < m_demux_entries; demux_index++) { 12509 desc_data = 0; 12510 start_addr = m_demux_offsets[demux_index]; 12511 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) { 12512 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; 12513 } else { 12514 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; 12515 } 12516 if (demux_index < (m_demux_entries - 1)) { 12517 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; 12518 } else { 12519 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; 12520 } 12521 DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)", 12522 (unsigned int)start_addr, 12523 (unsigned int)suffix_byte, 12524 (unsigned int)nal_size, 12525 (unsigned int)demux_index); 12526 desc_data = (start_addr >> 3) << 1; 12527 desc_data |= (start_addr & 7) << 21; 12528 desc_data |= suffix_byte << 24; 12529 12530 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 12531 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); 12532 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 12533 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 12534 12535 p_demux_data += 16; 12536 } 12537 if (codec_type_parse == CODEC_TYPE_VC1) { 12538 DEBUG_PRINT_LOW("VC1 terminator entry"); 12539 desc_data = 0; 12540 desc_data = 0x82 << 24; 12541 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 12542 memset(p_demux_data + 4, 0, sizeof(OMX_U32)); 12543 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 12544 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 12545 p_demux_data += 16; 12546 m_demux_entries++; 12547 } 12548 //Add zero word to indicate end of descriptors 12549 memset(p_demux_data, 0, sizeof(OMX_U32)); 12550 12551 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); 12552 DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size); 12553 } 12554 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 12555 m_demux_entries = 0; 12556 DEBUG_PRINT_LOW("Demux table complete!"); 12557 return OMX_ErrorNone; 12558 } 12559 12560 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level) 12561 { 12562 struct v4l2_control control; 12563 char property_value[PROPERTY_VALUE_MAX] = {0}; 12564 12565 property_get("vendor.vidc.debug.turbo", property_value, "0"); 12566 memset(&control, 0, sizeof(v4l2_control)); 12567 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 12568 switch (perf_level) { 12569 case VIDC_NOMINAL: 12570 if (atoi(property_value)) 12571 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 12572 else 12573 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 12574 break; 12575 case VIDC_TURBO: 12576 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 12577 break; 12578 default: 12579 DEBUG_PRINT_ERROR("Requested PERF level not supported"); 12580 break; 12581 } 12582 if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig) 12583 return; 12584 12585 DEBUG_PRINT_HIGH("changing performance level to %d", control.value); 12586 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 12587 current_perf_level = control.value; 12588 } else { 12589 DEBUG_PRINT_ERROR("Failed to set PERF level"); 12590 } 12591 } 12592 12593 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() 12594 { 12595 enabled = false; 12596 omx = NULL; 12597 init_members(); 12598 ColorFormat = OMX_COLOR_FormatMax; 12599 dest_format = YCbCr420P; 12600 m_c2d_width = 0; 12601 m_c2d_height = 0; 12602 } 12603 12604 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) 12605 { 12606 omx = reinterpret_cast<omx_vdec*>(client); 12607 } 12608 12609 void omx_vdec::allocate_color_convert_buf::init_members() 12610 { 12611 allocated_count = 0; 12612 buffer_size_req = 0; 12613 buffer_alignment_req = 0; 12614 m_c2d_width = m_c2d_height = 0; 12615 memset(m_platform_list_client,0,sizeof(m_platform_list_client)); 12616 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); 12617 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); 12618 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); 12619 #ifdef USE_ION 12620 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); 12621 #endif 12622 for (int i = 0; i < MAX_COUNT; i++) 12623 pmem_fd[i] = -1; 12624 } 12625 12626 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() 12627 { 12628 c2d.destroy(); 12629 } 12630 12631 bool omx_vdec::allocate_color_convert_buf::update_buffer_req() 12632 { 12633 bool status = true; 12634 unsigned int src_size = 0, destination_size = 0; 12635 unsigned int height, width; 12636 struct v4l2_format fmt; 12637 OMX_COLOR_FORMATTYPE drv_color_format; 12638 12639 if (!omx) { 12640 DEBUG_PRINT_ERROR("Invalid client in color convert"); 12641 return false; 12642 } 12643 if (!enabled) { 12644 DEBUG_PRINT_HIGH("No color conversion required"); 12645 return status; 12646 } 12647 pthread_mutex_lock(&omx->c_lock); 12648 12649 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 12650 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 12651 fmt.fmt.pix_mp.pixelformat = omx->capture_capability; 12652 ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 12653 width = fmt.fmt.pix_mp.width; 12654 height = fmt.fmt.pix_mp.height; 12655 12656 bool resolution_upgrade = (height > m_c2d_height || 12657 width > m_c2d_width); 12658 if (resolution_upgrade) { 12659 // resolution upgraded ? ensure we are yet to allocate; 12660 // failing which, c2d buffers will never be reallocated and bad things will happen 12661 if (allocated_count > 0) { 12662 DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations", 12663 allocated_count); 12664 status = false; 12665 goto fail_update_buf_req; 12666 } 12667 } 12668 12669 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && 12670 ColorFormat != OMX_COLOR_FormatYUV420Planar) { 12671 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion"); 12672 status = false; 12673 goto fail_update_buf_req; 12674 } 12675 c2d.close(); 12676 status = c2d.open(height, 12677 width, 12678 NV12_128m,dest_format); 12679 if (status) { 12680 status = c2d.get_buffer_size(C2D_INPUT,src_size); 12681 if (status) 12682 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); 12683 } 12684 if (status) { 12685 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || 12686 !destination_size) { 12687 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d" 12688 "driver size %u destination size %d", 12689 src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size, 12690 destination_size); 12691 status = false; 12692 c2d.close(); 12693 buffer_size_req = 0; 12694 // TODO: make this fatal. Driver is not supposed to quote size 12695 // smaller than what C2D needs !! 12696 } else { 12697 buffer_size_req = destination_size; 12698 m_c2d_height = height; 12699 m_c2d_width = width; 12700 } 12701 } 12702 fail_update_buf_req: 12703 pthread_mutex_unlock(&omx->c_lock); 12704 return status; 12705 } 12706 12707 bool omx_vdec::allocate_color_convert_buf::set_color_format( 12708 OMX_COLOR_FORMATTYPE dest_color_format) 12709 { 12710 bool status = true, drv_colorformat_c2d_enable = false; 12711 bool dest_color_format_c2d_enable = false; 12712 OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused; 12713 if (!omx) { 12714 DEBUG_PRINT_ERROR("Invalid client in color convert"); 12715 return false; 12716 } 12717 pthread_mutex_lock(&omx->c_lock); 12718 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 12719 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 12720 drv_color_format = (OMX_COLOR_FORMATTYPE) 12721 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 12722 else 12723 drv_color_format = (OMX_COLOR_FORMATTYPE) 12724 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 12725 else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 12726 drv_color_format = (OMX_COLOR_FORMATTYPE) 12727 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 12728 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 12729 drv_color_format = (OMX_COLOR_FORMATTYPE) 12730 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed; 12731 } else { 12732 DEBUG_PRINT_ERROR("Incorrect color format"); 12733 status = false; 12734 } 12735 drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) && 12736 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12737 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) && 12738 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12739 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) && 12740 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12741 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed); 12742 12743 dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE) 12744 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) && 12745 (dest_color_format != (OMX_COLOR_FORMATTYPE) 12746 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed); 12747 12748 if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) { 12749 DEBUG_PRINT_LOW("Enabling C2D"); 12750 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) && 12751 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) { 12752 DEBUG_PRINT_ERROR("Unsupported color format for c2d"); 12753 status = false; 12754 } else { 12755 ColorFormat = dest_color_format; 12756 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ? 12757 YCbCr420P : YCbCr420SP; 12758 if (enabled) 12759 c2d.destroy(); 12760 enabled = false; 12761 if (!c2d.init()) { 12762 DEBUG_PRINT_ERROR("open failed for c2d"); 12763 status = false; 12764 } else 12765 enabled = true; 12766 } 12767 } else { 12768 if (enabled) 12769 c2d.destroy(); 12770 enabled = false; 12771 } 12772 pthread_mutex_unlock(&omx->c_lock); 12773 return status; 12774 } 12775 12776 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() 12777 { 12778 if (!omx) { 12779 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12780 return NULL; 12781 } 12782 if (!enabled) 12783 return omx->m_out_mem_ptr; 12784 return m_out_mem_ptr_client; 12785 } 12786 12787 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr 12788 (OMX_BUFFERHEADERTYPE *bufadd) 12789 { 12790 if (!omx) { 12791 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12792 return NULL; 12793 } 12794 if (!enabled) 12795 return bufadd; 12796 12797 unsigned index = 0; 12798 index = bufadd - omx->m_out_mem_ptr; 12799 if (index < omx->drv_ctx.op_buf.actualcount) { 12800 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); 12801 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; 12802 bool status; 12803 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { 12804 pthread_mutex_lock(&omx->c_lock); 12805 cache_clean_buffer(index); 12806 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, 12807 omx->drv_ctx.op_buf_map_info[index].base_address, bufadd->pBuffer, pmem_fd[index], 12808 pmem_baseaddress[index], pmem_baseaddress[index]); 12809 if (!status) { 12810 DEBUG_PRINT_ERROR("Failed color conversion %d", status); 12811 m_out_mem_ptr_client[index].nFilledLen = 0; 12812 pthread_mutex_unlock(&omx->c_lock); 12813 return &m_out_mem_ptr_client[index]; 12814 } else { 12815 unsigned int filledLen = 0; 12816 c2d.get_output_filled_length(filledLen); 12817 m_out_mem_ptr_client[index].nFilledLen = filledLen; 12818 cache_clean_invalidate_buffer(index); 12819 } 12820 pthread_mutex_unlock(&omx->c_lock); 12821 } else 12822 m_out_mem_ptr_client[index].nFilledLen = 0; 12823 return &m_out_mem_ptr_client[index]; 12824 } 12825 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr"); 12826 return NULL; 12827 } 12828 12829 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr 12830 (OMX_BUFFERHEADERTYPE *bufadd) 12831 { 12832 if (!omx) { 12833 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12834 return NULL; 12835 } 12836 if (!enabled) 12837 return bufadd; 12838 unsigned index = 0; 12839 index = bufadd - m_out_mem_ptr_client; 12840 if (index < omx->drv_ctx.op_buf.actualcount) { 12841 return &omx->m_out_mem_ptr[index]; 12842 } 12843 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr"); 12844 return NULL; 12845 } 12846 bool omx_vdec::allocate_color_convert_buf::get_buffer_req 12847 (unsigned int &buffer_size) 12848 { 12849 bool status = true; 12850 pthread_mutex_lock(&omx->c_lock); 12851 if (!enabled) 12852 buffer_size = omx->drv_ctx.op_buf.buffer_size; 12853 else { 12854 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { 12855 DEBUG_PRINT_ERROR("Get buffer size failed"); 12856 status = false; 12857 goto fail_get_buffer_size; 12858 } 12859 } 12860 fail_get_buffer_size: 12861 pthread_mutex_unlock(&omx->c_lock); 12862 return status; 12863 } 12864 12865 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req( 12866 OMX_U32 buffer_size, OMX_U32 actual_count) { 12867 OMX_U32 expectedSize = enabled ? buffer_size_req : omx->drv_ctx.op_buf.buffer_size; 12868 12869 if (buffer_size < expectedSize) { 12870 DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)", 12871 buffer_size, expectedSize); 12872 return OMX_ErrorBadParameter; 12873 } 12874 if (actual_count < omx->drv_ctx.op_buf.actualcount) { 12875 DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)", 12876 actual_count, omx->drv_ctx.op_buf.actualcount); 12877 return OMX_ErrorBadParameter; 12878 } 12879 12880 bool reqs_updated = false; 12881 if (enabled) { 12882 // disallow changing buffer size/count while we have active allocated buffers 12883 if (allocated_count > 0) { 12884 DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations", 12885 buffer_size_req, buffer_size, allocated_count); 12886 return OMX_ErrorInvalidState; 12887 } 12888 12889 buffer_size_req = buffer_size; 12890 } else { 12891 if (buffer_size > omx->drv_ctx.op_buf.buffer_size) { 12892 omx->drv_ctx.op_buf.buffer_size = buffer_size; 12893 reqs_updated = true; 12894 } 12895 } 12896 12897 if (actual_count > omx->drv_ctx.op_buf.actualcount) { 12898 omx->drv_ctx.op_buf.actualcount = actual_count; 12899 reqs_updated = true; 12900 } 12901 12902 if (reqs_updated) { 12903 omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount; 12904 omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count * 12905 omx->drv_ctx.extradata_info.buffer_size; 12906 return omx->set_buffer_req(&(omx->drv_ctx.op_buf)); 12907 } 12908 return OMX_ErrorNone; 12909 } 12910 12911 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( 12912 OMX_BUFFERHEADERTYPE *bufhdr) 12913 { 12914 unsigned int index = 0; 12915 12916 if (!enabled) 12917 return omx->free_output_buffer(bufhdr); 12918 if (enabled && omx->is_component_secure()) 12919 return OMX_ErrorNone; 12920 if (!allocated_count || !bufhdr) { 12921 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); 12922 return OMX_ErrorBadParameter; 12923 } 12924 index = bufhdr - m_out_mem_ptr_client; 12925 if (index >= omx->drv_ctx.op_buf.actualcount) { 12926 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer"); 12927 return OMX_ErrorBadParameter; 12928 } 12929 if (pmem_fd[index] >= 0) { 12930 munmap(pmem_baseaddress[index], buffer_size_req); 12931 close(pmem_fd[index]); 12932 } 12933 pmem_fd[index] = -1; 12934 #ifdef USE_ION 12935 omx->free_ion_memory(&op_buf_ion_info[index]); 12936 #endif 12937 if (allocated_count > 0) 12938 allocated_count--; 12939 else 12940 allocated_count = 0; 12941 if (!allocated_count) { 12942 pthread_mutex_lock(&omx->c_lock); 12943 c2d.close(); 12944 init_members(); 12945 pthread_mutex_unlock(&omx->c_lock); 12946 } 12947 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); 12948 } 12949 12950 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, 12951 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) 12952 { 12953 OMX_ERRORTYPE eRet = OMX_ErrorNone; 12954 if (!enabled) { 12955 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 12956 return eRet; 12957 } 12958 if (enabled && omx->is_component_secure()) { 12959 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d", 12960 omx->is_component_secure()); 12961 return OMX_ErrorUnsupportedSetting; 12962 } 12963 if (!bufferHdr || bytes > buffer_size_req) { 12964 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr); 12965 DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u", 12966 (unsigned int)buffer_size_req, (unsigned int)bytes); 12967 return OMX_ErrorBadParameter; 12968 } 12969 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { 12970 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert"); 12971 return OMX_ErrorInsufficientResources; 12972 } 12973 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; 12974 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, 12975 port,appData,omx->drv_ctx.op_buf.buffer_size); 12976 if (eRet != OMX_ErrorNone || !temp_bufferHdr) { 12977 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert"); 12978 return eRet; 12979 } 12980 if ((temp_bufferHdr - omx->m_out_mem_ptr) >= 12981 (int)omx->drv_ctx.op_buf.actualcount) { 12982 DEBUG_PRINT_ERROR("Invalid header index %ld", 12983 (long int)(temp_bufferHdr - omx->m_out_mem_ptr)); 12984 return OMX_ErrorUndefined; 12985 } 12986 unsigned int i = allocated_count; 12987 #ifdef USE_ION 12988 // Allocate color-conversion buffers as cached to improve software-reading 12989 // performance of YUV (thumbnails). NOTE: These buffers will need an explicit 12990 // cache invalidation. 12991 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( 12992 buffer_size_req,buffer_alignment_req, 12993 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, 12994 ION_FLAG_CACHED); 12995 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; 12996 if (op_buf_ion_info[i].ion_device_fd < 0) { 12997 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert"); 12998 return OMX_ErrorInsufficientResources; 12999 } 13000 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, 13001 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); 13002 13003 if (pmem_baseaddress[i] == MAP_FAILED) { 13004 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req); 13005 close(pmem_fd[i]); 13006 omx->free_ion_memory(&op_buf_ion_info[i]); 13007 return OMX_ErrorInsufficientResources; 13008 } 13009 #endif 13010 m_pmem_info_client[i].offset = 0; 13011 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; 13012 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 13013 m_platform_list_client[i].nEntries = 1; 13014 m_platform_list_client[i].entryList = &m_platform_entry_client[i]; 13015 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; 13016 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; 13017 m_out_mem_ptr_client[i].nFilledLen = 0; 13018 m_out_mem_ptr_client[i].nFlags = 0; 13019 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 13020 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); 13021 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; 13022 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; 13023 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; 13024 m_out_mem_ptr_client[i].pAppPrivate = appData; 13025 *bufferHdr = &m_out_mem_ptr_client[i]; 13026 DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr); 13027 allocated_count++; 13028 return eRet; 13029 } 13030 13031 bool omx_vdec::is_component_secure() 13032 { 13033 return secure_mode; 13034 } 13035 13036 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) 13037 { 13038 bool status = true; 13039 if (!enabled) { 13040 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 13041 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 13042 dest_color_format = (OMX_COLOR_FORMATTYPE) 13043 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 13044 else 13045 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 13046 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){ 13047 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 13048 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC){ 13049 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed; 13050 } else 13051 status = false; 13052 } else { 13053 if (ColorFormat == OMX_COLOR_FormatYUV420Planar || 13054 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 13055 dest_color_format = ColorFormat; 13056 } else 13057 status = false; 13058 } 13059 return status; 13060 } 13061 13062 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops( 13063 unsigned int index, unsigned int cmd) 13064 { 13065 if (!enabled) { 13066 return OMX_ErrorNone; 13067 } 13068 13069 if (!omx || index >= omx->drv_ctx.op_buf.actualcount) { 13070 DEBUG_PRINT_ERROR("%s: Invalid param", __func__); 13071 return OMX_ErrorBadParameter; 13072 } 13073 13074 struct ion_flush_data flush_data; 13075 struct ion_custom_data custom_data; 13076 13077 memset(&flush_data, 0x0, sizeof(flush_data)); 13078 memset(&custom_data, 0x0, sizeof(custom_data)); 13079 13080 flush_data.vaddr = pmem_baseaddress[index]; 13081 flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd; 13082 flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle; 13083 flush_data.length = buffer_size_req; 13084 custom_data.cmd = cmd; 13085 custom_data.arg = (unsigned long)&flush_data; 13086 13087 DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d", 13088 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 13089 flush_data.fd, flush_data.handle, flush_data.vaddr, 13090 flush_data.length); 13091 int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data); 13092 if (ret < 0) { 13093 DEBUG_PRINT_ERROR("Cache %s failed: %s\n", 13094 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 13095 strerror(errno)); 13096 return OMX_ErrorUndefined; 13097 } 13098 return OMX_ErrorNone; 13099 } 13100 13101 void omx_vdec::buf_ref_add(int nPortIndex) 13102 { 13103 unsigned long i = 0; 13104 bool buf_present = false; 13105 long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 13106 OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 13107 13108 if (!dynamic_buf_mode || !out_dynamic_list) { 13109 return; 13110 } 13111 13112 pthread_mutex_lock(&m_lock); 13113 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 13114 //check the buffer fd, offset, uv addr with list contents 13115 //If present increment reference. 13116 if ((out_dynamic_list[i].fd == fd) && 13117 (out_dynamic_list[i].offset == offset)) { 13118 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u", 13119 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 13120 if (!secure_mode) { 13121 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr; 13122 } 13123 buf_present = true; 13124 break; 13125 } 13126 } 13127 if (!buf_present) { 13128 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 13129 //search for a entry to insert details of the new buffer 13130 if (out_dynamic_list[i].dup_fd < 0) { 13131 out_dynamic_list[i].fd = fd; 13132 out_dynamic_list[i].offset = offset; 13133 out_dynamic_list[i].dup_fd = dup(fd); 13134 out_dynamic_list[i].ref_count++; 13135 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u", 13136 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 13137 13138 if (!secure_mode) { 13139 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = 13140 (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len, 13141 PROT_READ|PROT_WRITE, MAP_SHARED, 13142 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0); 13143 //mmap returns (void *)-1 on failure and sets error code in errno. 13144 if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) { 13145 DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno); 13146 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL; 13147 break; 13148 } 13149 out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr; 13150 out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len; 13151 DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 13152 } 13153 break; 13154 } 13155 } 13156 } 13157 pthread_mutex_unlock(&m_lock); 13158 } 13159 13160 void omx_vdec::buf_ref_remove() 13161 { 13162 unsigned long i = 0; 13163 13164 if (!dynamic_buf_mode || !out_dynamic_list) { 13165 return; 13166 } 13167 13168 pthread_mutex_lock(&m_lock); 13169 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 13170 if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) { 13171 DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 13172 munmap(out_dynamic_list[i].buffaddr, 13173 out_dynamic_list[i].mapped_size); 13174 } 13175 13176 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u", 13177 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 13178 close(out_dynamic_list[i].dup_fd); 13179 out_dynamic_list[i].dup_fd = -1; 13180 } 13181 pthread_mutex_unlock(&m_lock); 13182 13183 if (out_dynamic_list) { 13184 free(out_dynamic_list); 13185 out_dynamic_list = NULL; 13186 } 13187 } 13188 13189 #ifdef _MSM8974_ 13190 void omx_vdec::send_codec_config() { 13191 if (codec_config_flag) { 13192 unsigned long p1 = 0; // Parameter - 1 13193 unsigned long p2 = 0; // Parameter - 2 13194 unsigned long ident = 0; 13195 pthread_mutex_lock(&m_lock); 13196 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n"); 13197 while (m_etb_q.m_size) { 13198 m_etb_q.pop_entry(&p1,&p2,&ident); 13199 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 13200 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 13201 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 13202 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 13203 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); 13204 omx_report_error(); 13205 } 13206 } else { 13207 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 13208 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 13209 } 13210 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 13211 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 13212 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 13213 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 13214 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); 13215 omx_report_error (); 13216 } 13217 } else { 13218 pending_input_buffers++; 13219 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 13220 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 13221 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 13222 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 13223 } 13224 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 13225 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", 13226 (OMX_BUFFERHEADERTYPE *)p1); 13227 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 13228 } 13229 } 13230 pthread_mutex_unlock(&m_lock); 13231 } 13232 } 13233 #endif 13234 13235 omx_vdec::perf_control::perf_control() 13236 { 13237 m_perf_lib = NULL; 13238 m_perf_handle = 0; 13239 m_perf_lock_acquire = NULL; 13240 m_perf_lock_release = NULL; 13241 } 13242 13243 omx_vdec::perf_control::~perf_control() 13244 { 13245 if (m_perf_handle != 0 && m_perf_lock_release) { 13246 DEBUG_PRINT_LOW("NOTE2: release perf lock"); 13247 m_perf_lock_release(m_perf_handle); 13248 } 13249 if (m_perf_lib) { 13250 dlclose(m_perf_lib); 13251 } 13252 } 13253 13254 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0}; 13255 13256 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock; 13257 13258 void omx_vdec::perf_control::send_hint_to_mpctl(bool state) 13259 { 13260 if (load_lib() == false) { 13261 return; 13262 } 13263 m_perf_lock.lock(); 13264 /* 0x4401 maps to video decode playback hint 13265 * in perflock, enum number is 44 and state 13266 * being sent on perflock acquire is 01 (true) 13267 */ 13268 int arg = 0x4401; 13269 13270 if (state == true) { 13271 mpctl_obj.vid_inst_count++; 13272 } else if (state == false) { 13273 mpctl_obj.vid_inst_count--; 13274 } 13275 13276 if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) { 13277 mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int)); 13278 mpctl_obj.vid_acquired = true; 13279 DEBUG_PRINT_INFO("Video slvp perflock acquired"); 13280 } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) { 13281 m_perf_lock_release(mpctl_obj.vid_disp_handle); 13282 mpctl_obj.vid_acquired = false; 13283 DEBUG_PRINT_INFO("Video slvp perflock released"); 13284 } 13285 m_perf_lock.unlock(); 13286 } 13287 13288 void omx_vdec::perf_control::request_cores(int frame_duration_us) 13289 { 13290 if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) { 13291 return; 13292 } 13293 bool retVal = load_lib(); 13294 if (retVal && m_perf_lock_acquire && m_perf_handle == 0) { 13295 int arg = 0x700 /*base value*/ + 2 /*cores*/; 13296 m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int)); 13297 if (m_perf_handle) { 13298 DEBUG_PRINT_HIGH("perf lock acquired"); 13299 } 13300 } 13301 } 13302 13303 bool omx_vdec::perf_control::load_lib() 13304 { 13305 char perf_lib_path[PROPERTY_VALUE_MAX] = {0}; 13306 if (m_perf_lib) 13307 return true; 13308 13309 if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) { 13310 DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library"); 13311 goto handle_err; 13312 } 13313 13314 if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) { 13315 DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror()); 13316 goto handle_err; 13317 } else { 13318 m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq"); 13319 if (m_perf_lock_acquire == NULL) { 13320 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq"); 13321 goto handle_err; 13322 } 13323 m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel"); 13324 if (m_perf_lock_release == NULL) { 13325 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel"); 13326 goto handle_err; 13327 } 13328 } 13329 return true; 13330 13331 handle_err: 13332 if (m_perf_lib) { 13333 dlclose(m_perf_lib); 13334 } 13335 m_perf_lib = NULL; 13336 return false; 13337 } 13338 13339 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth, 13340 unsigned long nMaxFrameHeight) 13341 { 13342 13343 OMX_ERRORTYPE eRet = OMX_ErrorNone; 13344 int ret = 0; 13345 unsigned long min_res_buf_count = 0; 13346 13347 eRet = enable_smoothstreaming(); 13348 if (eRet != OMX_ErrorNone) { 13349 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver"); 13350 return eRet; 13351 } 13352 13353 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu", 13354 nMaxFrameWidth, 13355 nMaxFrameHeight); 13356 m_smoothstreaming_mode = true; 13357 m_smoothstreaming_width = nMaxFrameWidth; 13358 m_smoothstreaming_height = nMaxFrameHeight; 13359 13360 //Get upper limit buffer count for min supported resolution 13361 struct v4l2_format fmt; 13362 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 13363 fmt.fmt.pix_mp.height = m_decoder_capability.min_height; 13364 fmt.fmt.pix_mp.width = m_decoder_capability.min_width; 13365 fmt.fmt.pix_mp.pixelformat = output_capability; 13366 13367 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 13368 if (ret) { 13369 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u", 13370 m_decoder_capability.min_height, 13371 m_decoder_capability.min_width); 13372 return OMX_ErrorUnsupportedSetting; 13373 } 13374 13375 eRet = get_buffer_req(&drv_ctx.op_buf); 13376 if (eRet != OMX_ErrorNone) { 13377 DEBUG_PRINT_ERROR("failed to get_buffer_req"); 13378 return eRet; 13379 } 13380 13381 min_res_buf_count = drv_ctx.op_buf.mincount; 13382 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u", 13383 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width); 13384 13385 m_extradata_info.output_crop_rect.nLeft = 0; 13386 m_extradata_info.output_crop_rect.nTop = 0; 13387 m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width; 13388 m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height; 13389 13390 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height, 13391 m_smoothstreaming_width, m_smoothstreaming_height); 13392 eRet = is_video_session_supported(); 13393 if (eRet != OMX_ErrorNone) { 13394 DEBUG_PRINT_ERROR("video session is not supported"); 13395 return eRet; 13396 } 13397 13398 //Get upper limit buffer size for max smooth streaming resolution set 13399 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 13400 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 13401 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 13402 fmt.fmt.pix_mp.pixelformat = output_capability; 13403 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 13404 if (ret) { 13405 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback"); 13406 return OMX_ErrorUnsupportedSetting; 13407 } 13408 13409 eRet = get_buffer_req(&drv_ctx.op_buf); 13410 if (eRet != OMX_ErrorNone) { 13411 DEBUG_PRINT_ERROR("failed to get_buffer_req!!"); 13412 return eRet; 13413 } 13414 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u", 13415 (unsigned int)drv_ctx.op_buf.buffer_size); 13416 13417 drv_ctx.op_buf.mincount = min_res_buf_count; 13418 drv_ctx.op_buf.actualcount = min_res_buf_count; 13419 drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size; 13420 eRet = set_buffer_req(&drv_ctx.op_buf); 13421 if (eRet != OMX_ErrorNone) { 13422 DEBUG_PRINT_ERROR("failed to set_buffer_req"); 13423 return eRet; 13424 } 13425 13426 eRet = get_buffer_req(&drv_ctx.op_buf); 13427 if (eRet != OMX_ErrorNone) { 13428 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!"); 13429 return eRet; 13430 } 13431 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u", 13432 drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size); 13433 return eRet; 13434 } 13435 13436 //static 13437 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) { 13438 13439 #ifndef FLEXYUV_SUPPORTED 13440 return OMX_ErrorUndefined; 13441 #else 13442 13443 if (pParam == NULL) { 13444 DEBUG_PRINT_ERROR("describeColorFormat: invalid params"); 13445 return OMX_ErrorBadParameter; 13446 } 13447 13448 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam; 13449 13450 MediaImage *img = &(params->sMediaImage); 13451 switch(params->eColorFormat) { 13452 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: 13453 { 13454 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 13455 img->mNumPlanes = 3; 13456 // mWidth and mHeight represent the W x H of the largest plane 13457 // In our case, this happens to be the Stride x Scanlines of Y plane 13458 img->mWidth = params->nFrameWidth; 13459 img->mHeight = params->nFrameHeight; 13460 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13461 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight); 13462 img->mBitDepth = 8; 13463 //Plane 0 (Y) 13464 img->mPlane[MediaImage::Y].mOffset = 0; 13465 img->mPlane[MediaImage::Y].mColInc = 1; 13466 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride 13467 img->mPlane[MediaImage::Y].mHorizSubsampling = 1; 13468 img->mPlane[MediaImage::Y].mVertSubsampling = 1; 13469 //Plane 1 (U) 13470 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight; 13471 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV 13472 img->mPlane[MediaImage::U].mRowInc = 13473 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13474 img->mPlane[MediaImage::U].mHorizSubsampling = 2; 13475 img->mPlane[MediaImage::U].mVertSubsampling = 2; 13476 //Plane 2 (V) 13477 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1; 13478 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV 13479 img->mPlane[MediaImage::V].mRowInc = 13480 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13481 img->mPlane[MediaImage::V].mHorizSubsampling = 2; 13482 img->mPlane[MediaImage::V].mVertSubsampling = 2; 13483 break; 13484 } 13485 13486 case OMX_COLOR_FormatYUV420Planar: 13487 case OMX_COLOR_FormatYUV420SemiPlanar: 13488 // We need not describe the standard OMX linear formats as these are 13489 // understood by client. Fail this deliberately to let client fill-in 13490 return OMX_ErrorUnsupportedSetting; 13491 13492 default: 13493 // Rest all formats which are non-linear cannot be described 13494 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat); 13495 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 13496 return OMX_ErrorNone; 13497 }; 13498 13499 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat); 13500 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight); 13501 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight); 13502 for (size_t i = 0; i < img->mNumPlanes; ++i) { 13503 DEBUG_PRINT_LOW(" Plane[%zu] : offset=%d / xStep=%d / yStep = %d", 13504 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc); 13505 } 13506 return OMX_ErrorNone; 13507 #endif //FLEXYUV_SUPPORTED 13508 } 13509 13510 void omx_vdec::prefetchNewBuffers() { 13511 13512 struct v4l2_decoder_cmd dec; 13513 uint32_t prefetch_count; 13514 uint32_t prefetch_size; 13515 uint32_t want_size; 13516 uint32_t have_size; 13517 int color_fmt, rc; 13518 uint32_t new_calculated_size; 13519 uint32_t new_buffer_size; 13520 uint32_t new_buffer_count; 13521 uint32_t old_buffer_size; 13522 uint32_t old_buffer_count; 13523 13524 memset((void *)&dec, 0 , sizeof(dec)); 13525 DEBUG_PRINT_LOW("Old size : %zu, count : %d, width : %u, height : %u\n", 13526 drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount, 13527 drv_ctx.video_resolution.frame_width, 13528 drv_ctx.video_resolution.frame_height); 13529 dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT; 13530 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 13531 DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno); 13532 } else { 13533 DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n", 13534 dec.raw.data[0], dec.raw.data[1]); 13535 } 13536 13537 switch ((int)drv_ctx.output_format) { 13538 case VDEC_YUV_FORMAT_NV12: 13539 color_fmt = COLOR_FMT_NV12; 13540 break; 13541 case VDEC_YUV_FORMAT_NV12_UBWC: 13542 color_fmt = COLOR_FMT_NV12_UBWC; 13543 break; 13544 case VDEC_YUV_FORMAT_NV12_TP10_UBWC: 13545 color_fmt = COLOR_FMT_NV12_BPP10_UBWC; 13546 break; 13547 default: 13548 color_fmt = -1; 13549 DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format); 13550 return; 13551 } 13552 13553 new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height); 13554 DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n", 13555 m_reconfig_width, m_reconfig_height, new_calculated_size); 13556 new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size; 13557 new_buffer_count = dec.raw.data[1]; 13558 old_buffer_size = drv_ctx.op_buf.buffer_size; 13559 old_buffer_count = drv_ctx.op_buf.actualcount; 13560 13561 new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count; 13562 13563 prefetch_count = new_buffer_count; 13564 prefetch_size = new_buffer_size - old_buffer_size; 13565 want_size = new_buffer_size * new_buffer_count; 13566 have_size = old_buffer_size * old_buffer_count; 13567 13568 if (want_size > have_size) { 13569 DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size); 13570 DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size); 13571 13572 int ion_fd = open(MEM_DEVICE, O_RDONLY); 13573 if (ion_fd < 0) { 13574 DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd); 13575 return; 13576 } 13577 13578 struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data)); 13579 struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data)); 13580 struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions)); 13581 size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count); 13582 13583 if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) { 13584 DEBUG_PRINT_ERROR("prefetch data allocation failed"); 13585 goto prefetch_exit; 13586 } 13587 13588 for (uint32_t i = 0; i < prefetch_count; i++) { 13589 sizes[i] = prefetch_size; 13590 } 13591 13592 regions[0].nr_sizes = prefetch_count; 13593 regions[0].sizes = sizes; 13594 regions[0].vmid = ION_FLAG_CP_PIXEL; 13595 13596 prefetch_data->nr_regions = 1; 13597 prefetch_data->regions = regions; 13598 prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID); 13599 13600 custom_data->cmd = ION_IOC_PREFETCH; 13601 custom_data->arg = (unsigned long )prefetch_data; 13602 13603 rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data); 13604 if (rc) { 13605 DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno); 13606 } 13607 13608 prefetch_exit: 13609 close(ion_fd); 13610 free(sizes); 13611 free(regions); 13612 free(prefetch_data); 13613 free(custom_data); 13614 } 13615 } 13616 13617 13618 // No code beyond this ! 13619 13620 // inline import of vendor-extensions implementation 13621 #include "omx_vdec_extensions.hpp" 13622