1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010 - 2016, 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 <media/msm_media_info.h> 56 #include <sys/eventfd.h> 57 58 #ifndef _ANDROID_ 59 #include <sys/ioctl.h> 60 #include <sys/mman.h> 61 #endif //_ANDROID_ 62 63 #ifdef _ANDROID_ 64 #include <cutils/properties.h> 65 #undef USE_EGL_IMAGE_GPU 66 #endif 67 68 #include <qdMetaData.h> 69 70 #ifdef ANDROID_JELLYBEAN_MR2 71 #include "QComOMXMetadata.h" 72 #endif 73 74 #ifdef USE_EGL_IMAGE_GPU 75 #include <EGL/egl.h> 76 #include <EGL/eglQCOM.h> 77 #define EGL_BUFFER_HANDLE 0x4F00 78 #define EGL_BUFFER_OFFSET 0x4F01 79 #endif 80 81 #define BUFFER_LOG_LOC "/data/misc/media" 82 83 #ifdef OUTPUT_EXTRADATA_LOG 84 FILE *outputExtradataFile; 85 char output_extradata_filename [] = "/data/misc/media/extradata"; 86 #endif 87 88 #define DEFAULT_FPS 30 89 #define MAX_SUPPORTED_FPS 120 90 #define DEFAULT_WIDTH_ALIGNMENT 128 91 #define DEFAULT_HEIGHT_ALIGNMENT 32 92 93 #define VC1_SP_MP_START_CODE 0xC5000000 94 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 95 #define VC1_AP_SEQ_START_CODE 0x0F010000 96 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 97 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 98 #define VC1_SIMPLE_PROFILE 0 99 #define VC1_MAIN_PROFILE 1 100 #define VC1_ADVANCE_PROFILE 3 101 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 102 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 103 #define VC1_STRUCT_C_LEN 4 104 #define VC1_STRUCT_C_POS 8 105 #define VC1_STRUCT_A_POS 12 106 #define VC1_STRUCT_B_POS 24 107 #define VC1_SEQ_LAYER_SIZE 36 108 #define POLL_TIMEOUT 0x7fffffff 109 110 #define MEM_DEVICE "/dev/ion" 111 112 #ifdef _ANDROID_ 113 extern "C" { 114 #include<utils/Log.h> 115 } 116 #endif//_ANDROID_ 117 118 #define SZ_4K 0x1000 119 #define SZ_1M 0x100000 120 121 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 122 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 123 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0) 124 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1)) 125 126 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_DISPLAY_INFO_EXTRADATA) 127 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default 128 129 #ifndef ION_FLAG_CP_BITSTREAM 130 #define ION_FLAG_CP_BITSTREAM 0 131 #endif 132 133 #ifndef ION_FLAG_CP_PIXEL 134 #define ION_FLAG_CP_PIXEL 0 135 #endif 136 137 #ifdef MASTER_SIDE_CP 138 #define MEM_HEAP_ID ION_SECURE_HEAP_ID 139 #define SECURE_ALIGN SZ_4K 140 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM) 141 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL) 142 #else //SLAVE_SIDE_CP 143 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID 144 #define SECURE_ALIGN SZ_1M 145 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE 146 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE 147 #endif 148 149 static OMX_U32 maxSmoothStreamingWidth = 1920; 150 static OMX_U32 maxSmoothStreamingHeight = 1088; 151 152 void* async_message_thread (void *input) 153 { 154 OMX_BUFFERHEADERTYPE *buffer; 155 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 156 struct pollfd pfds[2]; 157 struct v4l2_buffer v4l2_buf; 158 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 159 struct v4l2_event dqevent; 160 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 161 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 162 pfds[1].events = POLLIN | POLLERR; 163 pfds[0].fd = omx->drv_ctx.video_driver_fd; 164 pfds[1].fd = omx->m_poll_efd; 165 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; 166 DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); 167 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); 168 while (!omx->async_thread_force_stop) { 169 rc = poll(pfds, 2, POLL_TIMEOUT); 170 if (!rc) { 171 DEBUG_PRINT_ERROR("Poll timedout"); 172 break; 173 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) { 174 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno); 175 break; 176 } 177 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) { 178 DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited"); 179 break; 180 } 181 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) { 182 struct vdec_msginfo vdec_msg; 183 memset(&vdec_msg, 0, sizeof(vdec_msg)); 184 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 185 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 186 v4l2_buf.length = omx->drv_ctx.num_planes; 187 v4l2_buf.m.planes = plane; 188 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 189 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 190 vdec_msg.status_code=VDEC_S_SUCCESS; 191 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; 192 vdec_msg.msgdata.output_frame.len=plane[0].bytesused; 193 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; 194 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + 195 (uint64_t)v4l2_buf.timestamp.tv_usec; 196 if (vdec_msg.msgdata.output_frame.len) { 197 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; 198 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; 199 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; 200 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; 201 vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6]; 202 vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7]; 203 } 204 if (omx->async_message_process(input,&vdec_msg) < 0) { 205 DEBUG_PRINT_HIGH("async_message_thread Exited"); 206 break; 207 } 208 } 209 } 210 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) { 211 struct vdec_msginfo vdec_msg; 212 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 213 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 214 v4l2_buf.length = 1; 215 v4l2_buf.m.planes = plane; 216 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 217 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; 218 vdec_msg.status_code=VDEC_S_SUCCESS; 219 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; 220 if (omx->async_message_process(input,&vdec_msg) < 0) { 221 DEBUG_PRINT_HIGH("async_message_thread Exited"); 222 break; 223 } 224 } 225 } 226 if (pfds[0].revents & POLLPRI) { 227 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent); 228 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { 229 struct vdec_msginfo vdec_msg; 230 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 231 232 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; 233 vdec_msg.status_code=VDEC_S_SUCCESS; 234 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0]; 235 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1]; 236 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient"); 237 if (omx->async_message_process(input,&vdec_msg) < 0) { 238 DEBUG_PRINT_HIGH("async_message_thread Exited"); 239 break; 240 } 241 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT ) { 242 struct vdec_msginfo vdec_msg; 243 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; 244 vdec_msg.status_code=VDEC_S_SUCCESS; 245 omx->dpb_bit_depth = dqevent.u.data[0]; 246 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", dqevent.u.data[0]); 247 if (omx->async_message_process(input,&vdec_msg) < 0) { 248 DEBUG_PRINT_HIGH("async_message_thread Exited"); 249 break; 250 } 251 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 252 struct vdec_msginfo vdec_msg; 253 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; 254 vdec_msg.status_code=VDEC_S_SUCCESS; 255 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved"); 256 if (omx->async_message_process(input,&vdec_msg) < 0) { 257 DEBUG_PRINT_HIGH("async_message_thread Exited"); 258 break; 259 } 260 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; 261 vdec_msg.status_code=VDEC_S_SUCCESS; 262 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved"); 263 if (omx->async_message_process(input,&vdec_msg) < 0) { 264 DEBUG_PRINT_HIGH("async_message_thread Exited"); 265 break; 266 } 267 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) { 268 struct vdec_msginfo vdec_msg; 269 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD; 270 vdec_msg.status_code=VDEC_S_SUCCESS; 271 DEBUG_PRINT_ERROR("HW Overload received"); 272 if (omx->async_message_process(input,&vdec_msg) < 0) { 273 DEBUG_PRINT_HIGH("async_message_thread Exited"); 274 break; 275 } 276 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) { 277 struct vdec_msginfo vdec_msg; 278 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED; 279 vdec_msg.status_code=VDEC_S_SUCCESS; 280 DEBUG_PRINT_ERROR("HW Unsupported received"); 281 if (omx->async_message_process(input,&vdec_msg) < 0) { 282 DEBUG_PRINT_HIGH("async_message_thread Exited"); 283 break; 284 } 285 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 286 struct vdec_msginfo vdec_msg; 287 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR; 288 vdec_msg.status_code = VDEC_S_SUCCESS; 289 DEBUG_PRINT_HIGH("SYS Error Recieved"); 290 if (omx->async_message_process(input,&vdec_msg) < 0) { 291 DEBUG_PRINT_HIGH("async_message_thread Exited"); 292 break; 293 } 294 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) { 295 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 296 297 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]); 298 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) { 299 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 300 struct vdec_msginfo vdec_msg; 301 302 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]); 303 304 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 305 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 306 v4l2_buf.length = omx->drv_ctx.num_planes; 307 v4l2_buf.m.planes = plane; 308 v4l2_buf.index = ptr[5]; 309 v4l2_buf.flags = 0; 310 311 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 312 vdec_msg.status_code = VDEC_S_SUCCESS; 313 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf; 314 vdec_msg.msgdata.output_frame.len = 0; 315 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2]; 316 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) + 317 (uint64_t)ptr[4]; 318 if (omx->async_message_process(input,&vdec_msg) < 0) { 319 DEBUG_PRINT_HIGH("async_message_thread Exitedn"); 320 break; 321 } 322 } else { 323 DEBUG_PRINT_HIGH("VIDC Some Event recieved"); 324 continue; 325 } 326 } 327 } 328 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); 329 return NULL; 330 } 331 332 void* message_thread(void *input) 333 { 334 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 335 unsigned char id; 336 int n; 337 338 fd_set readFds; 339 int res = 0; 340 struct timeval tv; 341 342 DEBUG_PRINT_HIGH("omx_vdec: message thread start"); 343 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); 344 while (!omx->message_thread_stop) { 345 346 tv.tv_sec = 2; 347 tv.tv_usec = 0; 348 349 FD_ZERO(&readFds); 350 FD_SET(omx->m_pipe_in, &readFds); 351 352 res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv); 353 if (res < 0) { 354 DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno)); 355 continue; 356 } else if (res == 0 /*timeout*/ || omx->message_thread_stop) { 357 continue; 358 } 359 360 n = read(omx->m_pipe_in, &id, 1); 361 362 if (0 == n) { 363 break; 364 } 365 366 if (1 == n) { 367 omx->process_event_cb(omx, id); 368 } 369 370 if ((n < 0) && (errno != EINTR)) { 371 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno); 372 break; 373 } 374 } 375 DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); 376 return 0; 377 } 378 379 void post_message(omx_vdec *omx, unsigned char id) 380 { 381 int ret_value; 382 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); 383 ret_value = write(omx->m_pipe_out, &id, 1); 384 if (ret_value <= 0) { 385 DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno)); 386 } else { 387 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); 388 } 389 } 390 391 // omx_cmd_queue destructor 392 omx_vdec::omx_cmd_queue::~omx_cmd_queue() 393 { 394 // Nothing to do 395 } 396 397 // omx cmd queue constructor 398 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 399 { 400 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 401 } 402 403 // omx cmd queue insert 404 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id) 405 { 406 bool ret = true; 407 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) { 408 m_q[m_write].id = id; 409 m_q[m_write].param1 = p1; 410 m_q[m_write].param2 = p2; 411 m_write++; 412 m_size ++; 413 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) { 414 m_write = 0; 415 } 416 } else { 417 ret = false; 418 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__); 419 } 420 return ret; 421 } 422 423 // omx cmd queue pop 424 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id) 425 { 426 bool ret = true; 427 if (m_size > 0) { 428 *id = m_q[m_read].id; 429 *p1 = m_q[m_read].param1; 430 *p2 = m_q[m_read].param2; 431 // Move the read pointer ahead 432 ++m_read; 433 --m_size; 434 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) { 435 m_read = 0; 436 } 437 } else { 438 ret = false; 439 } 440 return ret; 441 } 442 443 // Retrieve the first mesg type in the queue 444 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 445 { 446 return m_q[m_read].id; 447 } 448 449 #ifdef _ANDROID_ 450 omx_vdec::ts_arr_list::ts_arr_list() 451 { 452 //initialize timestamps array 453 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); 454 } 455 omx_vdec::ts_arr_list::~ts_arr_list() 456 { 457 //free m_ts_arr_list? 458 } 459 460 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) 461 { 462 bool ret = true; 463 bool duplicate_ts = false; 464 int idx = 0; 465 466 //insert at the first available empty location 467 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 468 if (!m_ts_arr_list[idx].valid) { 469 //found invalid or empty entry, save timestamp 470 m_ts_arr_list[idx].valid = true; 471 m_ts_arr_list[idx].timestamp = ts; 472 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", 473 ts, idx); 474 break; 475 } 476 } 477 478 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) { 479 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); 480 ret = false; 481 } 482 return ret; 483 } 484 485 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) 486 { 487 bool ret = true; 488 int min_idx = -1; 489 OMX_TICKS min_ts = 0; 490 int idx = 0; 491 492 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 493 494 if (m_ts_arr_list[idx].valid) { 495 //found valid entry, save index 496 if (min_idx < 0) { 497 //first valid entry 498 min_ts = m_ts_arr_list[idx].timestamp; 499 min_idx = idx; 500 } else if (m_ts_arr_list[idx].timestamp < min_ts) { 501 min_ts = m_ts_arr_list[idx].timestamp; 502 min_idx = idx; 503 } 504 } 505 506 } 507 508 if (min_idx < 0) { 509 //no valid entries found 510 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); 511 ts = 0; 512 ret = false; 513 } else { 514 ts = m_ts_arr_list[min_idx].timestamp; 515 m_ts_arr_list[min_idx].valid = false; 516 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", 517 ts, min_idx); 518 } 519 520 return ret; 521 522 } 523 524 525 bool omx_vdec::ts_arr_list::reset_ts_list() 526 { 527 bool ret = true; 528 int idx = 0; 529 530 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); 531 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 532 m_ts_arr_list[idx].valid = false; 533 } 534 return ret; 535 } 536 #endif 537 538 // factory function executed by the core to create instances 539 void *get_omx_component_factory_fn(void) 540 { 541 return (new omx_vdec); 542 } 543 544 #ifdef _ANDROID_ 545 #ifdef USE_ION 546 VideoHeap::VideoHeap(int devicefd, size_t size, void* base, 547 ion_user_handle_t handle, int ionMapfd) 548 { 549 (void) devicefd; 550 (void) size; 551 (void) base; 552 (void) handle; 553 (void) ionMapfd; 554 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); 555 } 556 #else 557 VideoHeap::VideoHeap(int fd, size_t size, void* base) 558 { 559 // dup file descriptor, map once, use pmem 560 init(dup(fd), base, size, 0 , MEM_DEVICE); 561 } 562 #endif 563 #endif // _ANDROID_ 564 /* ====================================================================== 565 FUNCTION 566 omx_vdec::omx_vdec 567 568 DESCRIPTION 569 Constructor 570 571 PARAMETERS 572 None 573 574 RETURN VALUE 575 None. 576 ========================================================================== */ 577 omx_vdec::omx_vdec(): m_error_propogated(false), 578 m_state(OMX_StateInvalid), 579 m_app_data(NULL), 580 m_inp_mem_ptr(NULL), 581 m_out_mem_ptr(NULL), 582 input_flush_progress (false), 583 output_flush_progress (false), 584 input_use_buffer (false), 585 output_use_buffer (false), 586 ouput_egl_buffers(false), 587 m_use_output_pmem(OMX_FALSE), 588 m_out_mem_region_smi(OMX_FALSE), 589 m_out_pvt_entry_pmem(OMX_FALSE), 590 pending_input_buffers(0), 591 pending_output_buffers(0), 592 m_out_bm_count(0), 593 m_inp_bm_count(0), 594 m_inp_bPopulated(OMX_FALSE), 595 m_out_bPopulated(OMX_FALSE), 596 m_flags(0), 597 #ifdef _ANDROID_ 598 m_heap_ptr(NULL), 599 #endif 600 m_inp_bEnabled(OMX_TRUE), 601 m_out_bEnabled(OMX_TRUE), 602 m_in_alloc_cnt(0), 603 m_platform_list(NULL), 604 m_platform_entry(NULL), 605 m_pmem_info(NULL), 606 h264_parser(NULL), 607 arbitrary_bytes (true), 608 psource_frame (NULL), 609 pdest_frame (NULL), 610 m_inp_heap_ptr (NULL), 611 m_phdr_pmem_ptr(NULL), 612 m_heap_inp_bm_count (0), 613 codec_type_parse ((codec_type)0), 614 first_frame_meta (true), 615 frame_count (0), 616 nal_count (0), 617 nal_length(0), 618 look_ahead_nal (false), 619 first_frame(0), 620 first_buffer(NULL), 621 first_frame_size (0), 622 m_device_file_ptr(NULL), 623 m_vc1_profile((vc1_profile_type)0), 624 h264_last_au_ts(LLONG_MAX), 625 h264_last_au_flags(0), 626 m_disp_hor_size(0), 627 m_disp_vert_size(0), 628 prev_ts(LLONG_MAX), 629 prev_ts_actual(LLONG_MAX), 630 rst_prev_ts(true), 631 frm_int(0), 632 in_reconfig(false), 633 m_display_id(NULL), 634 client_extradata(0), 635 m_reject_avc_1080p_mp (0), 636 #ifdef _ANDROID_ 637 m_enable_android_native_buffers(OMX_FALSE), 638 m_use_android_native_buffers(OMX_FALSE), 639 #endif 640 m_desc_buffer_ptr(NULL), 641 secure_mode(false), 642 allocate_native_handle(false), 643 m_other_extradata(NULL), 644 m_profile(0), 645 client_set_fps(false), 646 m_last_rendered_TS(-1), 647 m_queued_codec_config_count(0), 648 current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL), 649 secure_scaling_to_non_secure_opb(false), 650 m_force_compressed_for_dpb(false) 651 { 652 m_pipe_in = -1; 653 m_pipe_out = -1; 654 m_poll_efd = -1; 655 drv_ctx.video_driver_fd = -1; 656 drv_ctx.extradata_info.ion.fd_ion_data.fd = -1; 657 /* Assumption is that , to begin with , we have all the frames with decoder */ 658 DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8); 659 memset(&m_debug,0,sizeof(m_debug)); 660 #ifdef _ANDROID_ 661 char property_value[PROPERTY_VALUE_MAX] = {0}; 662 property_get("vidc.debug.level", property_value, "1"); 663 debug_level = atoi(property_value); 664 property_value[0] = '\0'; 665 666 DEBUG_PRINT_HIGH("In OMX vdec Constructor"); 667 668 property_get("vidc.dec.debug.perf", property_value, "0"); 669 perf_flag = atoi(property_value); 670 if (perf_flag) { 671 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); 672 dec_time.start(); 673 proc_frms = latency = 0; 674 } 675 prev_n_filled_len = 0; 676 property_value[0] = '\0'; 677 property_get("vidc.dec.debug.ts", property_value, "0"); 678 m_debug_timestamp = atoi(property_value); 679 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); 680 if (m_debug_timestamp) { 681 time_stamp_dts.set_timestamp_reorder_mode(true); 682 time_stamp_dts.enable_debug_print(true); 683 } 684 685 property_value[0] = '\0'; 686 property_get("vidc.dec.debug.concealedmb", property_value, "0"); 687 m_debug_concealedmb = atoi(property_value); 688 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); 689 690 property_value[0] = '\0'; 691 property_get("vidc.dec.profile.check", property_value, "0"); 692 m_reject_avc_1080p_mp = atoi(property_value); 693 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp); 694 695 property_value[0] = '\0'; 696 property_get("vidc.dec.log.in", property_value, "0"); 697 m_debug.in_buffer_log = atoi(property_value); 698 699 property_value[0] = '\0'; 700 property_get("vidc.dec.log.out", property_value, "0"); 701 m_debug.out_buffer_log = atoi(property_value); 702 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 703 704 property_value[0] = '\0'; 705 property_get("vidc.dec.meta.log.out", property_value, "0"); 706 m_debug.out_meta_buffer_log = atoi(property_value); 707 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 708 709 property_value[0] = '\0'; 710 property_get("vidc.log.loc", property_value, ""); 711 if (*property_value) 712 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX); 713 714 property_value[0] = '\0'; 715 property_get("vidc.dec.120fps.enabled", property_value, "0"); 716 717 //if this feature is not enabled then reset this value -ve 718 if(atoi(property_value)) { 719 DEBUG_PRINT_LOW("feature 120 FPS decode enabled"); 720 m_last_rendered_TS = 0; 721 } 722 723 property_value[0] = '\0'; 724 property_get("vidc.dec.debug.dyn.disabled", property_value, "0"); 725 m_disable_dynamic_buf_mode = atoi(property_value); 726 DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode); 727 728 #ifdef _UBWC_ 729 property_value[0] = '\0'; 730 property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0"); 731 m_disable_ubwc_mode = atoi(property_value); 732 DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled"); 733 #else 734 m_disable_ubwc_mode = true; 735 #endif 736 #endif 737 memset(&m_cmp,0,sizeof(m_cmp)); 738 memset(&m_cb,0,sizeof(m_cb)); 739 memset (&drv_ctx,0,sizeof(drv_ctx)); 740 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 741 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 742 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 743 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize)); 744 memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams)); 745 memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams)); 746 m_demux_entries = 0; 747 msg_thread_id = 0; 748 async_thread_id = 0; 749 msg_thread_created = false; 750 async_thread_created = false; 751 async_thread_force_stop = false; 752 message_thread_stop = false; 753 #ifdef _ANDROID_ICS_ 754 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 755 #endif 756 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 757 758 /* invalidate m_frame_pack_arrangement */ 759 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 760 m_frame_pack_arrangement.cancel_flag = 1; 761 762 drv_ctx.timestamp_adjust = false; 763 m_vendor_config.pData = NULL; 764 pthread_mutex_init(&m_lock, NULL); 765 pthread_mutex_init(&c_lock, NULL); 766 pthread_mutex_init(&buf_lock, NULL); 767 sem_init(&m_cmd_lock,0,0); 768 sem_init(&m_safe_flush, 0, 0); 769 streaming[CAPTURE_PORT] = 770 streaming[OUTPUT_PORT] = false; 771 #ifdef _ANDROID_ 772 char extradata_value[PROPERTY_VALUE_MAX] = {0}; 773 property_get("vidc.dec.debug.extradata", extradata_value, "0"); 774 m_debug_extradata = atoi(extradata_value); 775 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); 776 #endif 777 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; 778 client_buffers.set_vdec_client(this); 779 dynamic_buf_mode = false; 780 out_dynamic_list = NULL; 781 is_down_scalar_enabled = false; 782 m_downscalar_width = 0; 783 m_downscalar_height = 0; 784 m_force_down_scalar = 0; 785 m_reconfig_height = 0; 786 m_reconfig_width = 0; 787 m_smoothstreaming_mode = false; 788 m_smoothstreaming_width = 0; 789 m_smoothstreaming_height = 0; 790 is_q6_platform = false; 791 m_perf_control.send_hint_to_mpctl(true); 792 m_input_pass_buffer_fd = false; 793 m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 794 m_client_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 795 m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 796 m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 797 m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 798 799 m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 800 m_internal_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 801 m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 802 m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 803 m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 804 m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams); 805 } 806 807 static const int event_type[] = { 808 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 809 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, 810 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, 811 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT, 812 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE, 813 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER, 814 V4L2_EVENT_MSM_VIDC_SYS_ERROR, 815 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD, 816 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED 817 }; 818 819 static OMX_ERRORTYPE subscribe_to_events(int fd) 820 { 821 OMX_ERRORTYPE eRet = OMX_ErrorNone; 822 struct v4l2_event_subscription sub; 823 int array_sz = sizeof(event_type)/sizeof(int); 824 int i,rc; 825 if (fd < 0) { 826 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 827 return OMX_ErrorBadParameter; 828 } 829 830 for (i = 0; i < array_sz; ++i) { 831 memset(&sub, 0, sizeof(sub)); 832 sub.type = event_type[i]; 833 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 834 if (rc) { 835 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 836 break; 837 } 838 } 839 if (i < array_sz) { 840 for (--i; i >=0 ; i--) { 841 memset(&sub, 0, sizeof(sub)); 842 sub.type = event_type[i]; 843 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 844 if (rc) 845 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 846 } 847 eRet = OMX_ErrorNotImplemented; 848 } 849 return eRet; 850 } 851 852 853 static OMX_ERRORTYPE unsubscribe_to_events(int fd) 854 { 855 OMX_ERRORTYPE eRet = OMX_ErrorNone; 856 struct v4l2_event_subscription sub; 857 int array_sz = sizeof(event_type)/sizeof(int); 858 int i,rc; 859 if (fd < 0) { 860 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 861 return OMX_ErrorBadParameter; 862 } 863 864 for (i = 0; i < array_sz; ++i) { 865 memset(&sub, 0, sizeof(sub)); 866 sub.type = event_type[i]; 867 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 868 if (rc) { 869 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 870 break; 871 } 872 } 873 return eRet; 874 } 875 876 /* ====================================================================== 877 FUNCTION 878 omx_vdec::~omx_vdec 879 880 DESCRIPTION 881 Destructor 882 883 PARAMETERS 884 None 885 886 RETURN VALUE 887 None. 888 ========================================================================== */ 889 omx_vdec::~omx_vdec() 890 { 891 m_pmem_info = NULL; 892 DEBUG_PRINT_HIGH("In OMX vdec Destructor"); 893 if (msg_thread_created) { 894 DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread"); 895 message_thread_stop = true; 896 post_message(this, OMX_COMPONENT_CLOSE_MSG); 897 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); 898 pthread_join(msg_thread_id,NULL); 899 } 900 close(m_pipe_in); 901 close(m_pipe_out); 902 m_pipe_in = -1; 903 m_pipe_out = -1; 904 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); 905 if(eventfd_write(m_poll_efd, 1)) { 906 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno); 907 async_thread_force_stop = true; 908 } 909 910 if (async_thread_created) 911 pthread_join(async_thread_id,NULL); 912 unsubscribe_to_events(drv_ctx.video_driver_fd); 913 close(m_poll_efd); 914 close(drv_ctx.video_driver_fd); 915 pthread_mutex_destroy(&m_lock); 916 pthread_mutex_destroy(&c_lock); 917 pthread_mutex_destroy(&buf_lock); 918 sem_destroy(&m_cmd_lock); 919 if (perf_flag) { 920 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); 921 dec_time.end(); 922 } 923 DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd); 924 m_perf_control.send_hint_to_mpctl(false); 925 } 926 927 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) 928 { 929 struct v4l2_requestbuffers bufreq; 930 int rc = 0; 931 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 932 bufreq.memory = V4L2_MEMORY_USERPTR; 933 bufreq.count = 0; 934 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 935 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 936 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) { 937 bufreq.memory = V4L2_MEMORY_USERPTR; 938 bufreq.count = 0; 939 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 940 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 941 } 942 return rc; 943 } 944 945 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format) 946 { 947 int rc = 0; 948 struct v4l2_ext_control ctrl[2]; 949 struct v4l2_ext_controls controls; 950 951 DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s", 952 is_split_mode ? "split" : "combined", 953 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc": 954 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc": 955 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb": 956 "unknown", 957 capture_capability == V4L2_PIX_FMT_NV12 ? "nv12": 958 capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc": 959 "unknown"); 960 961 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE; 962 if (is_split_mode) { 963 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY; 964 } else { 965 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY; 966 } 967 968 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT; 969 ctrl[1].value = dpb_color_format; 970 971 controls.count = 2; 972 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 973 controls.controls = ctrl; 974 975 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls); 976 if (rc) { 977 DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc); 978 return OMX_ErrorUnsupportedSetting; 979 } 980 return OMX_ErrorNone; 981 } 982 983 984 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool force_split_mode) 985 { 986 OMX_ERRORTYPE eRet = OMX_ErrorNone; 987 988 bool cpu_access = capture_capability != V4L2_PIX_FMT_NV12_UBWC; 989 990 bool is_res_above_1080p = (drv_ctx.video_resolution.frame_width > 1920 && 991 drv_ctx.video_resolution.frame_height > 1088) || 992 (drv_ctx.video_resolution.frame_height > 1088 && 993 drv_ctx.video_resolution.frame_width > 1920); 994 995 if (cpu_access) { 996 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 997 if ((m_force_compressed_for_dpb || is_res_above_1080p) && 998 !force_split_mode) { 999 //split DPB-OPB 1000 //DPB -> UBWC , OPB -> Linear 1001 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1002 } else if (force_split_mode) { 1003 //DPB -> Linear, OPB -> Linear 1004 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1005 } else { 1006 //DPB-OPB combined linear 1007 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1008 } 1009 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1010 //split DPB-OPB 1011 //DPB -> UBWC, OPB -> Linear 1012 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1013 } 1014 } else { //no cpu access 1015 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 1016 if (force_split_mode) { 1017 //split DPB-OPB 1018 //DPB -> UBWC, OPB -> UBWC 1019 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1020 } else { 1021 //DPB-OPB combined UBWC 1022 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1023 } 1024 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1025 //split DPB-OPB 1026 //DPB -> UBWC, OPB -> UBWC 1027 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1028 } 1029 } 1030 if (eRet) { 1031 DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet); 1032 } 1033 return eRet; 1034 } 1035 1036 int omx_vdec::enable_downscalar() 1037 { 1038 int rc = 0; 1039 struct v4l2_control control; 1040 struct v4l2_format fmt; 1041 1042 if (is_down_scalar_enabled) { 1043 DEBUG_PRINT_LOW("%s: already enabled", __func__); 1044 return 0; 1045 } 1046 1047 DEBUG_PRINT_LOW("omx_vdec::enable_downscalar"); 1048 rc = decide_dpb_buffer_mode(true); 1049 if (rc) { 1050 DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__); 1051 return rc; 1052 } 1053 is_down_scalar_enabled = true; 1054 1055 memset(&control, 0x0, sizeof(struct v4l2_control)); 1056 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO; 1057 control.value = 1; 1058 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 1059 if (rc) { 1060 DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__); 1061 return rc; 1062 } 1063 1064 return 0; 1065 } 1066 1067 int omx_vdec::disable_downscalar() 1068 { 1069 int rc = 0; 1070 struct v4l2_control control; 1071 1072 if (!is_down_scalar_enabled) { 1073 DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled"); 1074 return 0; 1075 } 1076 1077 rc = decide_dpb_buffer_mode(false); 1078 if (rc < 0) { 1079 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__); 1080 return rc; 1081 } 1082 is_down_scalar_enabled = false; 1083 1084 return rc; 1085 } 1086 1087 int omx_vdec::decide_downscalar() 1088 { 1089 int rc = 0; 1090 struct v4l2_format fmt; 1091 enum color_fmts color_format; 1092 1093 if (!m_downscalar_width || !m_downscalar_height) { 1094 DEBUG_PRINT_LOW("%s: downscalar not supported", __func__); 1095 return 0; 1096 } 1097 1098 if (m_force_down_scalar) { 1099 DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar); 1100 return 0; 1101 } 1102 1103 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1104 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1105 fmt.fmt.pix_mp.pixelformat = capture_capability; 1106 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1107 if (rc < 0) { 1108 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 1109 return rc; 1110 } 1111 1112 DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d", __func__, 1113 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height); 1114 1115 if (fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) { 1116 rc = enable_downscalar(); 1117 if (rc < 0) { 1118 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 1119 return rc; 1120 } 1121 1122 OMX_U32 width = m_downscalar_width > fmt.fmt.pix_mp.width ? 1123 fmt.fmt.pix_mp.width : m_downscalar_width; 1124 OMX_U32 height = m_downscalar_height > fmt.fmt.pix_mp.height ? 1125 fmt.fmt.pix_mp.height : m_downscalar_height; 1126 switch (capture_capability) { 1127 case V4L2_PIX_FMT_NV12: 1128 color_format = COLOR_FMT_NV12; 1129 break; 1130 case V4L2_PIX_FMT_NV12_UBWC: 1131 color_format = COLOR_FMT_NV12_UBWC; 1132 break; 1133 case V4L2_PIX_FMT_NV12_TP10_UBWC: 1134 color_format = COLOR_FMT_NV12_BPP10_UBWC; 1135 break; 1136 default: 1137 DEBUG_PRINT_ERROR("Color format not recognized\n"); 1138 rc = OMX_ErrorUndefined; 1139 return rc; 1140 } 1141 1142 rc = update_resolution(width, height, 1143 VENUS_Y_STRIDE(color_format, width), VENUS_Y_SCANLINES(color_format, height)); 1144 if (rc < 0) { 1145 DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed \n", __func__, width, height); 1146 return rc; 1147 } 1148 } else { 1149 1150 rc = disable_downscalar(); 1151 if (rc < 0) { 1152 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 1153 return rc; 1154 } 1155 1156 rc = update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, 1157 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); 1158 if (rc < 0) { 1159 DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed\n", __func__, fmt.fmt.pix_mp.width, 1160 fmt.fmt.pix_mp.height); 1161 return rc; 1162 } 1163 } 1164 1165 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1166 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1167 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 1168 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 1169 fmt.fmt.pix_mp.pixelformat = capture_capability; 1170 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1171 if (rc) { 1172 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__); 1173 return rc; 1174 } 1175 1176 rc = get_buffer_req(&drv_ctx.op_buf); 1177 if (rc) { 1178 DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__); 1179 return rc; 1180 } 1181 1182 return rc; 1183 } 1184 1185 /* ====================================================================== 1186 FUNCTION 1187 omx_vdec::OMXCntrlProcessMsgCb 1188 1189 DESCRIPTION 1190 IL Client callbacks are generated through this routine. The decoder 1191 provides the thread context for this routine. 1192 1193 PARAMETERS 1194 ctxt -- Context information related to the self. 1195 id -- Event identifier. This could be any of the following: 1196 1. Command completion event 1197 2. Buffer done callback event 1198 3. Frame done callback event 1199 1200 RETURN VALUE 1201 None. 1202 1203 ========================================================================== */ 1204 void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 1205 { 1206 unsigned long p1; // Parameter - 1 1207 unsigned long p2; // Parameter - 2 1208 unsigned long ident; 1209 unsigned qsize=0; // qsize 1210 omx_vdec *pThis = (omx_vdec *) ctxt; 1211 1212 if (!pThis) { 1213 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out", 1214 __func__); 1215 return; 1216 } 1217 1218 // Protect the shared queue data structure 1219 do { 1220 /*Read the message id's from the queue*/ 1221 pthread_mutex_lock(&pThis->m_lock); 1222 qsize = pThis->m_cmd_q.m_size; 1223 if (qsize) { 1224 pThis->m_cmd_q.pop_entry(&p1, &p2, &ident); 1225 } 1226 1227 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1228 qsize = pThis->m_ftb_q.m_size; 1229 if (qsize) { 1230 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident); 1231 } 1232 } 1233 1234 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1235 qsize = pThis->m_etb_q.m_size; 1236 if (qsize) { 1237 pThis->m_etb_q.pop_entry(&p1, &p2, &ident); 1238 } 1239 } 1240 pthread_mutex_unlock(&pThis->m_lock); 1241 1242 /*process message if we have one*/ 1243 if (qsize > 0) { 1244 id = ident; 1245 switch (id) { 1246 case OMX_COMPONENT_GENERATE_EVENT: 1247 if (pThis->m_cb.EventHandler) { 1248 switch (p1) { 1249 case OMX_CommandStateSet: 1250 pThis->m_state = (OMX_STATETYPE) p2; 1251 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", 1252 pThis->m_state); 1253 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1254 OMX_EventCmdComplete, p1, p2, NULL); 1255 break; 1256 1257 case OMX_EventError: 1258 if (p2 == OMX_StateInvalid) { 1259 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid"); 1260 pThis->m_state = (OMX_STATETYPE) p2; 1261 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1262 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 1263 } else if (p2 == (unsigned long)OMX_ErrorHardware) { 1264 pThis->omx_report_error(); 1265 } else { 1266 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1267 OMX_EventError, p2, (OMX_U32)NULL, NULL ); 1268 } 1269 break; 1270 1271 case OMX_CommandPortDisable: 1272 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2); 1273 if (BITMASK_PRESENT(&pThis->m_flags, 1274 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1275 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1276 break; 1277 } 1278 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) { 1279 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1280 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 1281 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) 1282 DEBUG_PRINT_HIGH("Failed to release output buffers"); 1283 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); 1284 pThis->in_reconfig = false; 1285 if (eRet != OMX_ErrorNone) { 1286 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); 1287 pThis->omx_report_error(); 1288 break; 1289 } 1290 } 1291 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1292 OMX_EventCmdComplete, p1, p2, NULL ); 1293 break; 1294 case OMX_CommandPortEnable: 1295 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2); 1296 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 1297 OMX_EventCmdComplete, p1, p2, NULL ); 1298 break; 1299 1300 default: 1301 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1302 OMX_EventCmdComplete, p1, p2, NULL ); 1303 break; 1304 1305 } 1306 } else { 1307 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1308 } 1309 break; 1310 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 1311 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 1312 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1313 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure"); 1314 pThis->omx_report_error (); 1315 } 1316 break; 1317 case OMX_COMPONENT_GENERATE_ETB: { 1318 OMX_ERRORTYPE iret; 1319 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2); 1320 if (iret == OMX_ErrorInsufficientResources) { 1321 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload"); 1322 pThis->omx_report_hw_overload (); 1323 } else if (iret != OMX_ErrorNone) { 1324 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); 1325 pThis->omx_report_error (); 1326 } 1327 } 1328 break; 1329 1330 case OMX_COMPONENT_GENERATE_FTB: 1331 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\ 1332 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1333 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure"); 1334 pThis->omx_report_error (); 1335 } 1336 break; 1337 1338 case OMX_COMPONENT_GENERATE_COMMAND: 1339 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 1340 (OMX_U32)p2,(OMX_PTR)NULL); 1341 break; 1342 1343 case OMX_COMPONENT_GENERATE_EBD: 1344 1345 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) { 1346 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure"); 1347 pThis->omx_report_error (); 1348 } else { 1349 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) { 1350 pThis->time_stamp_dts.remove_time_stamp( 1351 ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp, 1352 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1353 ?true:false); 1354 } 1355 1356 if ( pThis->empty_buffer_done(&pThis->m_cmp, 1357 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) { 1358 DEBUG_PRINT_ERROR("empty_buffer_done failure"); 1359 pThis->omx_report_error (); 1360 } 1361 } 1362 break; 1363 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: { 1364 int64_t *timestamp = (int64_t *)(intptr_t)p1; 1365 if (p1) { 1366 pThis->time_stamp_dts.remove_time_stamp(*timestamp, 1367 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1368 ?true:false); 1369 free(timestamp); 1370 } 1371 } 1372 break; 1373 case OMX_COMPONENT_GENERATE_FBD: 1374 if (p2 != VDEC_S_SUCCESS) { 1375 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure"); 1376 pThis->omx_report_error (); 1377 } else if ( pThis->fill_buffer_done(&pThis->m_cmp, 1378 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) { 1379 DEBUG_PRINT_ERROR("fill_buffer_done failure"); 1380 pThis->omx_report_error (); 1381 } 1382 break; 1383 1384 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 1385 DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); 1386 if (!pThis->input_flush_progress) { 1387 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1388 } else { 1389 pThis->execute_input_flush(); 1390 if (pThis->m_cb.EventHandler) { 1391 if (p2 != VDEC_S_SUCCESS) { 1392 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 1393 pThis->omx_report_error (); 1394 } else { 1395 /*Check if we need generate event for Flush done*/ 1396 if (BITMASK_PRESENT(&pThis->m_flags, 1397 OMX_COMPONENT_INPUT_FLUSH_PENDING)) { 1398 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 1399 DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); 1400 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1401 OMX_EventCmdComplete,OMX_CommandFlush, 1402 OMX_CORE_INPUT_PORT_INDEX,NULL ); 1403 } 1404 if (BITMASK_PRESENT(&pThis->m_flags, 1405 OMX_COMPONENT_IDLE_PENDING)) { 1406 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { 1407 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port"); 1408 pThis->omx_report_error (); 1409 } else { 1410 pThis->streaming[OUTPUT_PORT] = false; 1411 } 1412 if (!pThis->output_flush_progress) { 1413 DEBUG_PRINT_LOW("Input flush done hence issue stop"); 1414 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1415 OMX_COMPONENT_GENERATE_STOP_DONE); 1416 } 1417 } 1418 } 1419 } else { 1420 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1421 } 1422 } 1423 break; 1424 1425 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 1426 DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); 1427 if (!pThis->output_flush_progress) { 1428 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1429 } else { 1430 pThis->execute_output_flush(); 1431 if (pThis->m_cb.EventHandler) { 1432 if (p2 != VDEC_S_SUCCESS) { 1433 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 1434 pThis->omx_report_error (); 1435 } else { 1436 /*Check if we need generate event for Flush done*/ 1437 if (BITMASK_PRESENT(&pThis->m_flags, 1438 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) { 1439 DEBUG_PRINT_LOW("Notify Output Flush done"); 1440 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1441 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1442 OMX_EventCmdComplete,OMX_CommandFlush, 1443 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 1444 } 1445 if (BITMASK_PRESENT(&pThis->m_flags, 1446 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1447 DEBUG_PRINT_LOW("Internal flush complete"); 1448 BITMASK_CLEAR (&pThis->m_flags, 1449 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 1450 if (BITMASK_PRESENT(&pThis->m_flags, 1451 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) { 1452 pThis->post_event(OMX_CommandPortDisable, 1453 OMX_CORE_OUTPUT_PORT_INDEX, 1454 OMX_COMPONENT_GENERATE_EVENT); 1455 BITMASK_CLEAR (&pThis->m_flags, 1456 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1457 BITMASK_CLEAR (&pThis->m_flags, 1458 OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1459 1460 } 1461 } 1462 1463 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) { 1464 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 1465 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port"); 1466 pThis->omx_report_error (); 1467 break; 1468 } 1469 pThis->streaming[CAPTURE_PORT] = false; 1470 if (!pThis->input_flush_progress) { 1471 DEBUG_PRINT_LOW("Output flush done hence issue stop"); 1472 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1473 OMX_COMPONENT_GENERATE_STOP_DONE); 1474 } 1475 } 1476 } 1477 } else { 1478 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1479 } 1480 } 1481 break; 1482 1483 case OMX_COMPONENT_GENERATE_START_DONE: 1484 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); 1485 1486 if (pThis->m_cb.EventHandler) { 1487 if (p2 != VDEC_S_SUCCESS) { 1488 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure"); 1489 pThis->omx_report_error (); 1490 } else { 1491 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); 1492 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1493 DEBUG_PRINT_LOW("Move to executing"); 1494 // Send the callback now 1495 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1496 pThis->m_state = OMX_StateExecuting; 1497 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1498 OMX_EventCmdComplete,OMX_CommandStateSet, 1499 OMX_StateExecuting, NULL); 1500 } else if (BITMASK_PRESENT(&pThis->m_flags, 1501 OMX_COMPONENT_PAUSE_PENDING)) { 1502 if (/*ioctl (pThis->drv_ctx.video_driver_fd, 1503 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) { 1504 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed"); 1505 pThis->omx_report_error (); 1506 } 1507 } 1508 } 1509 } else { 1510 DEBUG_PRINT_LOW("Event Handler callback is NULL"); 1511 } 1512 break; 1513 1514 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 1515 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 1516 if (pThis->m_cb.EventHandler) { 1517 if (p2 != VDEC_S_SUCCESS) { 1518 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 1519 pThis->omx_report_error (); 1520 } else { 1521 pThis->complete_pending_buffer_done_cbs(); 1522 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) { 1523 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 1524 //Send the callback now 1525 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 1526 pThis->m_state = OMX_StatePause; 1527 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1528 OMX_EventCmdComplete,OMX_CommandStateSet, 1529 OMX_StatePause, NULL); 1530 } 1531 } 1532 } else { 1533 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1534 } 1535 1536 break; 1537 1538 case OMX_COMPONENT_GENERATE_RESUME_DONE: 1539 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 1540 if (pThis->m_cb.EventHandler) { 1541 if (p2 != VDEC_S_SUCCESS) { 1542 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 1543 pThis->omx_report_error (); 1544 } else { 1545 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1546 DEBUG_PRINT_LOW("Moving the decoder to execute state"); 1547 // Send the callback now 1548 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1549 pThis->m_state = OMX_StateExecuting; 1550 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1551 OMX_EventCmdComplete,OMX_CommandStateSet, 1552 OMX_StateExecuting,NULL); 1553 } 1554 } 1555 } else { 1556 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1557 } 1558 1559 break; 1560 1561 case OMX_COMPONENT_GENERATE_STOP_DONE: 1562 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 1563 if (pThis->m_cb.EventHandler) { 1564 if (p2 != VDEC_S_SUCCESS) { 1565 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 1566 pThis->omx_report_error (); 1567 } else { 1568 pThis->complete_pending_buffer_done_cbs(); 1569 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) { 1570 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); 1571 // Send the callback now 1572 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 1573 pThis->m_state = OMX_StateIdle; 1574 DEBUG_PRINT_LOW("Move to Idle State"); 1575 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 1576 OMX_EventCmdComplete,OMX_CommandStateSet, 1577 OMX_StateIdle,NULL); 1578 } 1579 } 1580 } else { 1581 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1582 } 1583 1584 break; 1585 1586 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 1587 if (p2 == OMX_IndexParamPortDefinition) { 1588 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition"); 1589 pThis->in_reconfig = true; 1590 } else if (p2 == OMX_IndexConfigCommonOutputCrop) { 1591 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop"); 1592 1593 /* Check if resolution is changed in smooth streaming mode */ 1594 if (pThis->m_smoothstreaming_mode && 1595 (pThis->framesize.nWidth != 1596 pThis->drv_ctx.video_resolution.frame_width) || 1597 (pThis->framesize.nHeight != 1598 pThis->drv_ctx.video_resolution.frame_height)) { 1599 1600 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d", 1601 pThis->framesize.nWidth, 1602 pThis->framesize.nHeight, 1603 pThis->drv_ctx.video_resolution.frame_width, 1604 pThis->drv_ctx.video_resolution.frame_height); 1605 1606 /* Update new resolution */ 1607 pThis->framesize.nWidth = 1608 pThis->drv_ctx.video_resolution.frame_width; 1609 pThis->framesize.nHeight = 1610 pThis->drv_ctx.video_resolution.frame_height; 1611 1612 /* Update C2D with new resolution */ 1613 if (!pThis->client_buffers.update_buffer_req()) { 1614 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed"); 1615 } 1616 } 1617 1618 /* Update new crop information */ 1619 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left; 1620 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top; 1621 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right; 1622 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom; 1623 1624 /* Validate the new crop information */ 1625 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth > 1626 pThis->drv_ctx.video_resolution.frame_width) { 1627 1628 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]", 1629 pThis->rectangle.nLeft, pThis->rectangle.nWidth, 1630 pThis->drv_ctx.video_resolution.frame_width); 1631 pThis->rectangle.nLeft = 0; 1632 1633 if (pThis->rectangle.nWidth > 1634 pThis->drv_ctx.video_resolution.frame_width) { 1635 1636 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]", 1637 pThis->rectangle.nWidth, 1638 pThis->drv_ctx.video_resolution.frame_width); 1639 pThis->rectangle.nWidth = 1640 pThis->drv_ctx.video_resolution.frame_width; 1641 } 1642 } 1643 if (pThis->rectangle.nTop + pThis->rectangle.nHeight > 1644 pThis->drv_ctx.video_resolution.frame_height) { 1645 1646 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]", 1647 pThis->rectangle.nTop, pThis->rectangle.nHeight, 1648 pThis->drv_ctx.video_resolution.frame_height); 1649 pThis->rectangle.nTop = 0; 1650 1651 if (pThis->rectangle.nHeight > 1652 pThis->drv_ctx.video_resolution.frame_height) { 1653 1654 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]", 1655 pThis->rectangle.nHeight, 1656 pThis->drv_ctx.video_resolution.frame_height); 1657 pThis->rectangle.nHeight = 1658 pThis->drv_ctx.video_resolution.frame_height; 1659 } 1660 } 1661 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u", 1662 pThis->rectangle.nLeft, pThis->rectangle.nTop, 1663 pThis->rectangle.nWidth, pThis->rectangle.nHeight); 1664 } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) { 1665 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects"); 1666 } else { 1667 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2); 1668 break; 1669 } 1670 if (pThis->m_debug.outfile) { 1671 fclose(pThis->m_debug.outfile); 1672 pThis->m_debug.outfile = NULL; 1673 } 1674 if (pThis->m_debug.out_ymeta_file) { 1675 fclose(pThis->m_debug.out_ymeta_file); 1676 pThis->m_debug.out_ymeta_file = NULL; 1677 } 1678 if (pThis->m_debug.out_uvmeta_file) { 1679 fclose(pThis->m_debug.out_uvmeta_file); 1680 pThis->m_debug.out_uvmeta_file = NULL; 1681 } 1682 1683 if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) { 1684 pThis->prefetchNewBuffers(); 1685 } 1686 1687 if (pThis->m_cb.EventHandler) { 1688 uint32_t frame_data[2]; 1689 frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ? 1690 pThis->m_reconfig_height : pThis->rectangle.nHeight; 1691 frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ? 1692 pThis->m_reconfig_width : pThis->rectangle.nWidth; 1693 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1694 OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data ); 1695 } else { 1696 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1697 } 1698 break; 1699 1700 case OMX_COMPONENT_GENERATE_EOS_DONE: 1701 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); 1702 if (pThis->m_cb.EventHandler) { 1703 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, 1704 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); 1705 } else { 1706 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1707 } 1708 pThis->prev_ts = LLONG_MAX; 1709 pThis->rst_prev_ts = true; 1710 break; 1711 1712 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 1713 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 1714 pThis->omx_report_error(); 1715 break; 1716 1717 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: 1718 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING"); 1719 pThis->omx_report_unsupported_setting(); 1720 break; 1721 1722 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD: 1723 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD"); 1724 pThis->omx_report_hw_overload(); 1725 break; 1726 1727 default: 1728 break; 1729 } 1730 } 1731 pthread_mutex_lock(&pThis->m_lock); 1732 qsize = pThis->m_cmd_q.m_size; 1733 if (pThis->m_state != OMX_StatePause) 1734 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); 1735 pthread_mutex_unlock(&pThis->m_lock); 1736 } while (qsize>0); 1737 1738 } 1739 1740 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) 1741 { 1742 int format_changed = 0; 1743 if ((height != (int)drv_ctx.video_resolution.frame_height) || 1744 (width != (int)drv_ctx.video_resolution.frame_width)) { 1745 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)", 1746 width, drv_ctx.video_resolution.frame_width, 1747 height,drv_ctx.video_resolution.frame_height); 1748 format_changed = 1; 1749 } 1750 drv_ctx.video_resolution.frame_height = height; 1751 drv_ctx.video_resolution.frame_width = width; 1752 drv_ctx.video_resolution.scan_lines = scan_lines; 1753 drv_ctx.video_resolution.stride = stride; 1754 if(!is_down_scalar_enabled) { 1755 rectangle.nLeft = 0; 1756 rectangle.nTop = 0; 1757 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 1758 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 1759 } 1760 return format_changed; 1761 } 1762 1763 OMX_ERRORTYPE omx_vdec::is_video_session_supported() 1764 { 1765 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 1766 OMX_MAX_STRINGNAME_SIZE) && 1767 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) { 1768 m_decoder_capability.max_width = 1280; 1769 m_decoder_capability.max_height = 720; 1770 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP"); 1771 } 1772 1773 if ((drv_ctx.video_resolution.frame_width * 1774 drv_ctx.video_resolution.frame_height > 1775 m_decoder_capability.max_width * 1776 m_decoder_capability.max_height) || 1777 (drv_ctx.video_resolution.frame_width* 1778 drv_ctx.video_resolution.frame_height < 1779 m_decoder_capability.min_width * 1780 m_decoder_capability.min_height)) { 1781 DEBUG_PRINT_ERROR( 1782 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", 1783 drv_ctx.video_resolution.frame_width, 1784 drv_ctx.video_resolution.frame_height, 1785 m_decoder_capability.min_width, 1786 m_decoder_capability.min_height, 1787 m_decoder_capability.max_width, 1788 m_decoder_capability.max_height); 1789 return OMX_ErrorUnsupportedSetting; 1790 } 1791 DEBUG_PRINT_HIGH("video session supported"); 1792 return OMX_ErrorNone; 1793 } 1794 1795 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len) 1796 { 1797 if (m_debug.in_buffer_log && !m_debug.infile) { 1798 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 1799 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v", 1800 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1801 } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 1802 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, 1803 drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1804 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 1805 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263", 1806 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1807 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) || 1808 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 1809 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264", 1810 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1811 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 1812 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265", 1813 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1814 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 1815 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 1816 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1817 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) { 1818 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 1819 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1820 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 1821 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 1822 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1823 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 1824 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 1825 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1826 } else { 1827 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx", 1828 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1829 } 1830 m_debug.infile = fopen (m_debug.infile_name, "ab"); 1831 if (!m_debug.infile) { 1832 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); 1833 m_debug.infile_name[0] = '\0'; 1834 return -1; 1835 } 1836 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 1837 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 1838 struct ivf_file_header { 1839 OMX_U8 signature[4]; //='DKIF'; 1840 OMX_U8 version ; //= 0; 1841 OMX_U8 headersize ; //= 32; 1842 OMX_U32 FourCC; 1843 OMX_U8 width; 1844 OMX_U8 height; 1845 OMX_U32 rate; 1846 OMX_U32 scale; 1847 OMX_U32 length; 1848 OMX_U8 unused[4]; 1849 } file_header; 1850 1851 memset((void *)&file_header,0,sizeof(file_header)); 1852 file_header.signature[0] = 'D'; 1853 file_header.signature[1] = 'K'; 1854 file_header.signature[2] = 'I'; 1855 file_header.signature[3] = 'F'; 1856 file_header.version = 0; 1857 file_header.headersize = 32; 1858 switch (drv_ctx.decoder_format) { 1859 case VDEC_CODECTYPE_VP8: 1860 file_header.FourCC = 0x30385056; 1861 break; 1862 case VDEC_CODECTYPE_VP9: 1863 file_header.FourCC = 0x30395056; 1864 break; 1865 default: 1866 DEBUG_PRINT_ERROR("unsupported format for VP8/VP9"); 1867 break; 1868 } 1869 fwrite((const char *)&file_header, 1870 sizeof(file_header),1,m_debug.infile); 1871 } 1872 } 1873 if (m_debug.infile && buffer_addr && buffer_len) { 1874 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 1875 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 1876 struct vpx_ivf_frame_header { 1877 OMX_U32 framesize; 1878 OMX_U32 timestamp_lo; 1879 OMX_U32 timestamp_hi; 1880 } vpx_frame_header; 1881 vpx_frame_header.framesize = buffer_len; 1882 /* Currently FW doesn't use timestamp values */ 1883 vpx_frame_header.timestamp_lo = 0; 1884 vpx_frame_header.timestamp_hi = 0; 1885 fwrite((const char *)&vpx_frame_header, 1886 sizeof(vpx_frame_header),1,m_debug.infile); 1887 } 1888 fwrite(buffer_addr, buffer_len, 1, m_debug.infile); 1889 } 1890 return 0; 1891 } 1892 1893 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) { 1894 int buf_index = 0; 1895 char *temp = NULL; 1896 1897 if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) { 1898 snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv", 1899 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1900 m_debug.outfile = fopen (m_debug.outfile_name, "ab"); 1901 if (!m_debug.outfile) { 1902 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc); 1903 m_debug.outfile_name[0] = '\0'; 1904 return -1; 1905 } 1906 } 1907 1908 if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file 1909 && buffer->nFilledLen) { 1910 snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta", 1911 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1912 snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta", 1913 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 1914 m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab"); 1915 m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab"); 1916 if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) { 1917 DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc); 1918 m_debug.out_ymetafile_name[0] = '\0'; 1919 m_debug.out_uvmetafile_name[0] = '\0'; 1920 return -1; 1921 } 1922 } 1923 1924 if ((!m_debug.outfile && !m_debug.out_ymeta_file) || !buffer || !buffer->nFilledLen) 1925 return 0; 1926 1927 buf_index = buffer - m_out_mem_ptr; 1928 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 1929 1930 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 1931 DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)", 1932 drv_ctx.video_resolution.frame_width, 1933 drv_ctx.video_resolution.frame_height); 1934 1935 if (m_debug.outfile) 1936 fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile); 1937 1938 if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) { 1939 unsigned int width = 0, height = 0; 1940 unsigned int y_plane, y_meta_plane; 1941 int y_stride = 0, y_sclines = 0; 1942 int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0; 1943 int color_fmt = COLOR_FMT_NV12_UBWC; 1944 int i; 1945 int bytes_written = 0; 1946 1947 width = drv_ctx.video_resolution.frame_width; 1948 height = drv_ctx.video_resolution.frame_height; 1949 y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); 1950 y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); 1951 y_stride = VENUS_Y_STRIDE(color_fmt, width); 1952 y_sclines = VENUS_Y_SCANLINES(color_fmt, height); 1953 uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); 1954 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); 1955 1956 y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096); 1957 y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); 1958 1959 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 1960 for (i = 0; i < y_meta_scanlines; i++) { 1961 bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file); 1962 temp += y_meta_stride; 1963 } 1964 1965 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane; 1966 for(i = 0; i < uv_meta_scanlines; i++) { 1967 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file); 1968 temp += uv_meta_stride; 1969 } 1970 } 1971 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12 && m_debug.outfile) { 1972 int stride = drv_ctx.video_resolution.stride; 1973 int scanlines = drv_ctx.video_resolution.scan_lines; 1974 if (m_smoothstreaming_mode) { 1975 stride = drv_ctx.video_resolution.frame_width; 1976 scanlines = drv_ctx.video_resolution.frame_height; 1977 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1)); 1978 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1)); 1979 } 1980 unsigned i; 1981 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)", 1982 drv_ctx.video_resolution.frame_width, 1983 drv_ctx.video_resolution.frame_height, stride, scanlines); 1984 int bytes_written = 0; 1985 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { 1986 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 1987 temp += stride; 1988 } 1989 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; 1990 int stride_c = stride; 1991 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { 1992 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 1993 temp += stride_c; 1994 } 1995 } 1996 return 0; 1997 } 1998 1999 /* ====================================================================== 2000 FUNCTION 2001 omx_vdec::ComponentInit 2002 2003 DESCRIPTION 2004 Initialize the component. 2005 2006 PARAMETERS 2007 ctxt -- Context information related to the self. 2008 id -- Event identifier. This could be any of the following: 2009 1. Command completion event 2010 2. Buffer done callback event 2011 3. Frame done callback event 2012 2013 RETURN VALUE 2014 None. 2015 2016 ========================================================================== */ 2017 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 2018 { 2019 2020 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2021 struct v4l2_fmtdesc fdesc; 2022 struct v4l2_format fmt; 2023 struct v4l2_requestbuffers bufreq; 2024 struct v4l2_control control; 2025 struct v4l2_frmsizeenum frmsize; 2026 unsigned int alignment = 0,buffer_size = 0; 2027 int fds[2]; 2028 int r,ret=0; 2029 bool codec_ambiguous = false; 2030 OMX_STRING device_name = (OMX_STRING)"/dev/video32"; 2031 char property_value[PROPERTY_VALUE_MAX] = {0}; 2032 FILE *soc_file = NULL; 2033 char buffer[10]; 2034 2035 #ifdef _ANDROID_ 2036 char platform_name[PROPERTY_VALUE_MAX]; 2037 property_get("ro.board.platform", platform_name, "0"); 2038 if (!strncmp(platform_name, "msm8610", 7)) { 2039 device_name = (OMX_STRING)"/dev/video/q6_dec"; 2040 is_q6_platform = true; 2041 maxSmoothStreamingWidth = 1280; 2042 maxSmoothStreamingHeight = 720; 2043 } 2044 #endif 2045 2046 is_thulium_v1 = false; 2047 soc_file = fopen("/sys/devices/soc0/soc_id", "r"); 2048 if (soc_file) { 2049 fread(buffer, 1, 4, soc_file); 2050 fclose(soc_file); 2051 if (atoi(buffer) == 246) { 2052 soc_file = fopen("/sys/devices/soc0/revision", "r"); 2053 if (soc_file) { 2054 fread(buffer, 1, 4, soc_file); 2055 fclose(soc_file); 2056 if (atoi(buffer) == 1) { 2057 is_thulium_v1 = true; 2058 DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE"); 2059 } 2060 } 2061 } 2062 } 2063 2064 #ifdef _ANDROID_ 2065 /* 2066 * turn off frame parsing for Android by default. 2067 * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode 2068 */ 2069 arbitrary_bytes = false; 2070 property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 2071 if (atoi(property_value)) { 2072 DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command"); 2073 arbitrary_bytes = true; 2074 } 2075 #endif 2076 2077 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure", 2078 OMX_MAX_STRINGNAME_SIZE)) { 2079 secure_mode = true; 2080 arbitrary_bytes = false; 2081 role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; 2082 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure", 2083 OMX_MAX_STRINGNAME_SIZE)) { 2084 secure_mode = true; 2085 arbitrary_bytes = false; 2086 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2"; 2087 } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure", 2088 OMX_MAX_STRINGNAME_SIZE)) { 2089 secure_mode = true; 2090 arbitrary_bytes = false; 2091 role = (OMX_STRING)"OMX.qcom.video.decoder.hevc"; 2092 } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure", 2093 OMX_MAX_STRINGNAME_SIZE)) { 2094 secure_mode = true; 2095 arbitrary_bytes = false; 2096 role = (OMX_STRING)"OMX.qcom.video.decoder.vc1"; 2097 } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure", 2098 OMX_MAX_STRINGNAME_SIZE)) { 2099 secure_mode = true; 2100 arbitrary_bytes = false; 2101 role = (OMX_STRING)"OMX.qcom.video.decoder.wmv"; 2102 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure", 2103 OMX_MAX_STRINGNAME_SIZE)) { 2104 secure_mode = true; 2105 arbitrary_bytes = false; 2106 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4"; 2107 } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure", 2108 OMX_MAX_STRINGNAME_SIZE)) { 2109 secure_mode = true; 2110 arbitrary_bytes = false; 2111 role = (OMX_STRING)"OMX.qcom.video.decoder.vp9"; 2112 } 2113 2114 drv_ctx.video_driver_fd = open(device_name, O_RDWR); 2115 2116 DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd); 2117 2118 if (drv_ctx.video_driver_fd < 0) { 2119 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno); 2120 return OMX_ErrorInsufficientResources; 2121 } 2122 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; 2123 drv_ctx.frame_rate.fps_denominator = 1; 2124 m_poll_efd = eventfd(0, 0); 2125 if (m_poll_efd < 0) { 2126 DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno)); 2127 return OMX_ErrorInsufficientResources; 2128 } 2129 ret = subscribe_to_events(drv_ctx.video_driver_fd); 2130 if (!ret) { 2131 async_thread_created = true; 2132 ret = pthread_create(&async_thread_id,0,async_message_thread,this); 2133 } 2134 if (ret) { 2135 DEBUG_PRINT_ERROR("Failed to create async_message_thread"); 2136 async_thread_created = false; 2137 return OMX_ErrorInsufficientResources; 2138 } 2139 2140 #ifdef OUTPUT_EXTRADATA_LOG 2141 outputExtradataFile = fopen (output_extradata_filename, "ab"); 2142 #endif 2143 2144 // Copy the role information which provides the decoder kind 2145 strlcpy(drv_ctx.kind,role,128); 2146 2147 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ 2148 OMX_MAX_STRINGNAME_SIZE)) { 2149 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ 2150 OMX_MAX_STRINGNAME_SIZE); 2151 drv_ctx.timestamp_adjust = true; 2152 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; 2153 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 2154 output_capability=V4L2_PIX_FMT_MPEG4; 2155 /*Initialize Start Code for MPEG4*/ 2156 codec_type_parse = CODEC_TYPE_MPEG4; 2157 m_frame_parser.init_start_codes(codec_type_parse); 2158 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ 2159 OMX_MAX_STRINGNAME_SIZE)) { 2160 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ 2161 OMX_MAX_STRINGNAME_SIZE); 2162 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; 2163 output_capability = V4L2_PIX_FMT_MPEG2; 2164 eCompressionFormat = OMX_VIDEO_CodingMPEG2; 2165 /*Initialize Start Code for MPEG2*/ 2166 codec_type_parse = CODEC_TYPE_MPEG2; 2167 m_frame_parser.init_start_codes(codec_type_parse); 2168 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ 2169 OMX_MAX_STRINGNAME_SIZE)) { 2170 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 2171 DEBUG_PRINT_LOW("H263 Decoder selected"); 2172 drv_ctx.decoder_format = VDEC_CODECTYPE_H263; 2173 eCompressionFormat = OMX_VIDEO_CodingH263; 2174 output_capability = V4L2_PIX_FMT_H263; 2175 codec_type_parse = CODEC_TYPE_H263; 2176 m_frame_parser.init_start_codes(codec_type_parse); 2177 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ 2178 OMX_MAX_STRINGNAME_SIZE)) { 2179 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2180 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); 2181 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; 2182 output_capability = V4L2_PIX_FMT_DIVX_311; 2183 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2184 codec_type_parse = CODEC_TYPE_DIVX; 2185 m_frame_parser.init_start_codes(codec_type_parse); 2186 2187 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 2188 OMX_MAX_STRINGNAME_SIZE)) { 2189 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2190 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); 2191 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; 2192 output_capability = V4L2_PIX_FMT_DIVX; 2193 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2194 codec_type_parse = CODEC_TYPE_DIVX; 2195 codec_ambiguous = true; 2196 m_frame_parser.init_start_codes(codec_type_parse); 2197 2198 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ 2199 OMX_MAX_STRINGNAME_SIZE)) { 2200 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2201 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); 2202 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; 2203 output_capability = V4L2_PIX_FMT_DIVX; 2204 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2205 codec_type_parse = CODEC_TYPE_DIVX; 2206 codec_ambiguous = true; 2207 m_frame_parser.init_start_codes(codec_type_parse); 2208 2209 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ 2210 OMX_MAX_STRINGNAME_SIZE)) { 2211 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 2212 drv_ctx.decoder_format = VDEC_CODECTYPE_H264; 2213 output_capability=V4L2_PIX_FMT_H264; 2214 eCompressionFormat = OMX_VIDEO_CodingAVC; 2215 codec_type_parse = CODEC_TYPE_H264; 2216 m_frame_parser.init_start_codes(codec_type_parse); 2217 m_frame_parser.init_nal_length(nal_length); 2218 if (is_thulium_v1) { 2219 arbitrary_bytes = true; 2220 DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264"); 2221 } 2222 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\ 2223 OMX_MAX_STRINGNAME_SIZE)) { 2224 strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 2225 drv_ctx.decoder_format = VDEC_CODECTYPE_MVC; 2226 output_capability = V4L2_PIX_FMT_H264_MVC; 2227 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC; 2228 codec_type_parse = CODEC_TYPE_H264; 2229 m_frame_parser.init_start_codes(codec_type_parse); 2230 m_frame_parser.init_nal_length(nal_length); 2231 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ 2232 OMX_MAX_STRINGNAME_SIZE)) { 2233 strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 2234 drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; 2235 output_capability = V4L2_PIX_FMT_HEVC; 2236 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; 2237 codec_type_parse = CODEC_TYPE_HEVC; 2238 m_frame_parser.init_start_codes(codec_type_parse); 2239 m_frame_parser.init_nal_length(nal_length); 2240 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ 2241 OMX_MAX_STRINGNAME_SIZE)) { 2242 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2243 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; 2244 eCompressionFormat = OMX_VIDEO_CodingWMV; 2245 codec_type_parse = CODEC_TYPE_VC1; 2246 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; 2247 m_frame_parser.init_start_codes(codec_type_parse); 2248 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ 2249 OMX_MAX_STRINGNAME_SIZE)) { 2250 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2251 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; 2252 eCompressionFormat = OMX_VIDEO_CodingWMV; 2253 codec_type_parse = CODEC_TYPE_VC1; 2254 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; 2255 m_frame_parser.init_start_codes(codec_type_parse); 2256 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ 2257 OMX_MAX_STRINGNAME_SIZE)) { 2258 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 2259 drv_ctx.decoder_format = VDEC_CODECTYPE_VP8; 2260 output_capability = V4L2_PIX_FMT_VP8; 2261 eCompressionFormat = OMX_VIDEO_CodingVP8; 2262 codec_type_parse = CODEC_TYPE_VP8; 2263 arbitrary_bytes = false; 2264 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", \ 2265 OMX_MAX_STRINGNAME_SIZE)) { 2266 strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 2267 drv_ctx.decoder_format = VDEC_CODECTYPE_VP9; 2268 output_capability = V4L2_PIX_FMT_VP9; 2269 eCompressionFormat = OMX_VIDEO_CodingVP9; 2270 codec_type_parse = CODEC_TYPE_VP9; 2271 arbitrary_bytes = false; 2272 } else { 2273 DEBUG_PRINT_ERROR("ERROR:Unknown Component"); 2274 eRet = OMX_ErrorInvalidComponentName; 2275 } 2276 2277 if (eRet == OMX_ErrorNone) { 2278 OMX_COLOR_FORMATTYPE dest_color_format; 2279 if (m_disable_ubwc_mode) { 2280 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 2281 } else { 2282 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC; 2283 } 2284 if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC) 2285 dest_color_format = (OMX_COLOR_FORMATTYPE) 2286 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 2287 else 2288 dest_color_format = (OMX_COLOR_FORMATTYPE) 2289 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 2290 if (!client_buffers.set_color_format(dest_color_format)) { 2291 DEBUG_PRINT_ERROR("Setting color format failed"); 2292 eRet = OMX_ErrorInsufficientResources; 2293 } 2294 2295 dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8; 2296 2297 if (m_disable_ubwc_mode) { 2298 capture_capability = V4L2_PIX_FMT_NV12; 2299 } else { 2300 capture_capability = V4L2_PIX_FMT_NV12_UBWC; 2301 } 2302 2303 struct v4l2_capability cap; 2304 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); 2305 if (ret) { 2306 DEBUG_PRINT_ERROR("Failed to query capabilities"); 2307 /*TODO: How to handle this case */ 2308 } else { 2309 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," 2310 " version = %d, capabilities = %x", cap.driver, cap.card, 2311 cap.bus_info, cap.version, cap.capabilities); 2312 } 2313 ret=0; 2314 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2315 fdesc.index=0; 2316 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 2317 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 2318 fdesc.pixelformat, fdesc.flags); 2319 fdesc.index++; 2320 } 2321 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2322 fdesc.index=0; 2323 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 2324 2325 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 2326 fdesc.pixelformat, fdesc.flags); 2327 fdesc.index++; 2328 } 2329 update_resolution(320, 240, 320, 240); 2330 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2331 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2332 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2333 fmt.fmt.pix_mp.pixelformat = output_capability; 2334 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2335 if (ret) { 2336 /*TODO: How to handle this case */ 2337 DEBUG_PRINT_ERROR("Failed to set format on output port"); 2338 return OMX_ErrorInsufficientResources; 2339 } 2340 DEBUG_PRINT_HIGH("Set Format was successful"); 2341 if (codec_ambiguous) { 2342 if (output_capability == V4L2_PIX_FMT_DIVX) { 2343 struct v4l2_control divx_ctrl; 2344 2345 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { 2346 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; 2347 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { 2348 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; 2349 } else { 2350 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; 2351 } 2352 2353 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; 2354 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); 2355 if (ret) { 2356 DEBUG_PRINT_ERROR("Failed to set divx version"); 2357 } 2358 } else { 2359 DEBUG_PRINT_ERROR("Codec should not be ambiguous"); 2360 } 2361 } 2362 2363 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR); 2364 m_conceal_color= atoi(property_value); 2365 DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color); 2366 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR; 2367 control.value = m_conceal_color; 2368 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2369 if (ret) { 2370 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret); 2371 } 2372 2373 //Get the hardware capabilities 2374 memset((void *)&frmsize,0,sizeof(frmsize)); 2375 frmsize.index = 0; 2376 frmsize.pixel_format = output_capability; 2377 ret = ioctl(drv_ctx.video_driver_fd, 2378 VIDIOC_ENUM_FRAMESIZES, &frmsize); 2379 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 2380 DEBUG_PRINT_ERROR("Failed to get framesizes"); 2381 return OMX_ErrorHardware; 2382 } 2383 2384 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 2385 m_decoder_capability.min_width = frmsize.stepwise.min_width; 2386 m_decoder_capability.max_width = frmsize.stepwise.max_width; 2387 m_decoder_capability.min_height = frmsize.stepwise.min_height; 2388 m_decoder_capability.max_height = frmsize.stepwise.max_height; 2389 } 2390 2391 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 2392 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2393 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2394 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2395 fmt.fmt.pix_mp.pixelformat = capture_capability; 2396 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2397 if (ret) { 2398 /*TODO: How to handle this case */ 2399 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 2400 } 2401 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE)); 2402 framesize.nWidth = drv_ctx.video_resolution.frame_width; 2403 framesize.nHeight = drv_ctx.video_resolution.frame_height; 2404 2405 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE)); 2406 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 2407 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 2408 2409 DEBUG_PRINT_HIGH("Set Format was successful"); 2410 if (secure_mode) { 2411 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 2412 control.value = 1; 2413 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret); 2414 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 2415 if (ret) { 2416 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret); 2417 return OMX_ErrorInsufficientResources; 2418 } 2419 } 2420 if (output_capability == V4L2_PIX_FMT_H264_MVC) { 2421 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT; 2422 control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM; 2423 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2424 if (ret) { 2425 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout"); 2426 return OMX_ErrorInsufficientResources; 2427 } 2428 } 2429 2430 if (is_thulium_v1) { 2431 eRet = enable_smoothstreaming(); 2432 if (eRet != OMX_ErrorNone) { 2433 DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver"); 2434 return eRet; 2435 } 2436 } 2437 2438 /*Get the Buffer requirements for input and output ports*/ 2439 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; 2440 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 2441 2442 if (secure_mode) { 2443 drv_ctx.op_buf.alignment = SECURE_ALIGN; 2444 drv_ctx.ip_buf.alignment = SECURE_ALIGN; 2445 } else { 2446 drv_ctx.op_buf.alignment = SZ_4K; 2447 drv_ctx.ip_buf.alignment = SZ_4K; 2448 } 2449 2450 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 2451 drv_ctx.extradata = 0; 2452 drv_ctx.picture_order = VDEC_ORDER_DISPLAY; 2453 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 2454 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 2455 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2456 drv_ctx.idr_only_decoding = 0; 2457 2458 #ifdef _ANDROID_ 2459 property_get("vidc.dec.downscalar_width",property_value,"0"); 2460 if (atoi(property_value)) { 2461 m_downscalar_width = atoi(property_value); 2462 } 2463 property_get("vidc.dec.downscalar_height",property_value,"0"); 2464 if (atoi(property_value)) { 2465 m_downscalar_height = atoi(property_value); 2466 } 2467 2468 if (m_downscalar_width < m_decoder_capability.min_width || 2469 m_downscalar_height < m_decoder_capability.min_height) { 2470 m_downscalar_width = 0; 2471 m_downscalar_height = 0; 2472 } 2473 2474 DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n", 2475 m_downscalar_width, m_downscalar_height); 2476 #endif 2477 m_state = OMX_StateLoaded; 2478 #ifdef DEFAULT_EXTRADATA 2479 if ((strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", 2480 OMX_MAX_STRINGNAME_SIZE) && 2481 strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", 2482 OMX_MAX_STRINGNAME_SIZE)) && 2483 (eRet == OMX_ErrorNone)) 2484 enable_extradata(DEFAULT_EXTRADATA, true, true); 2485 #endif 2486 eRet = get_buffer_req(&drv_ctx.ip_buf); 2487 DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size); 2488 get_buffer_req(&drv_ctx.op_buf); 2489 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2490 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC || 2491 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2492 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; 2493 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); 2494 h264_scratch.nFilledLen = 0; 2495 h264_scratch.nOffset = 0; 2496 2497 if (h264_scratch.pBuffer == NULL) { 2498 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed "); 2499 return OMX_ErrorInsufficientResources; 2500 } 2501 } 2502 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2503 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2504 if (m_frame_parser.mutils == NULL) { 2505 m_frame_parser.mutils = new H264_Utils(); 2506 if (m_frame_parser.mutils == NULL) { 2507 DEBUG_PRINT_ERROR("parser utils Allocation failed "); 2508 eRet = OMX_ErrorInsufficientResources; 2509 } else { 2510 m_frame_parser.mutils->initialize_frame_checking_environment(); 2511 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); 2512 } 2513 } 2514 2515 h264_parser = new h264_stream_parser(); 2516 if (!h264_parser) { 2517 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); 2518 eRet = OMX_ErrorInsufficientResources; 2519 } 2520 } 2521 2522 if (pipe(fds)) { 2523 DEBUG_PRINT_ERROR("pipe creation failed"); 2524 eRet = OMX_ErrorInsufficientResources; 2525 } else { 2526 m_pipe_in = fds[0]; 2527 m_pipe_out = fds[1]; 2528 msg_thread_created = true; 2529 r = pthread_create(&msg_thread_id,0,message_thread,this); 2530 2531 if (r < 0) { 2532 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed"); 2533 msg_thread_created = false; 2534 eRet = OMX_ErrorInsufficientResources; 2535 } 2536 } 2537 } 2538 2539 if (eRet != OMX_ErrorNone) { 2540 DEBUG_PRINT_ERROR("Component Init Failed"); 2541 } else { 2542 DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d", 2543 drv_ctx.video_driver_fd); 2544 } 2545 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); 2546 return eRet; 2547 } 2548 2549 /* ====================================================================== 2550 FUNCTION 2551 omx_vdec::GetComponentVersion 2552 2553 DESCRIPTION 2554 Returns the component version. 2555 2556 PARAMETERS 2557 TBD. 2558 2559 RETURN VALUE 2560 OMX_ErrorNone. 2561 2562 ========================================================================== */ 2563 OMX_ERRORTYPE omx_vdec::get_component_version 2564 ( 2565 OMX_IN OMX_HANDLETYPE hComp, 2566 OMX_OUT OMX_STRING componentName, 2567 OMX_OUT OMX_VERSIONTYPE* componentVersion, 2568 OMX_OUT OMX_VERSIONTYPE* specVersion, 2569 OMX_OUT OMX_UUIDTYPE* componentUUID 2570 ) 2571 { 2572 (void) hComp; 2573 (void) componentName; 2574 (void) componentVersion; 2575 (void) componentUUID; 2576 if (m_state == OMX_StateInvalid) { 2577 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State"); 2578 return OMX_ErrorInvalidState; 2579 } 2580 /* TBD -- Return the proper version */ 2581 if (specVersion) { 2582 specVersion->nVersion = OMX_SPEC_VERSION; 2583 } 2584 return OMX_ErrorNone; 2585 } 2586 /* ====================================================================== 2587 FUNCTION 2588 omx_vdec::SendCommand 2589 2590 DESCRIPTION 2591 Returns zero if all the buffers released.. 2592 2593 PARAMETERS 2594 None. 2595 2596 RETURN VALUE 2597 true/false 2598 2599 ========================================================================== */ 2600 OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 2601 OMX_IN OMX_COMMANDTYPE cmd, 2602 OMX_IN OMX_U32 param1, 2603 OMX_IN OMX_PTR cmdData 2604 ) 2605 { 2606 (void) hComp; 2607 (void) cmdData; 2608 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client"); 2609 if (m_state == OMX_StateInvalid) { 2610 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State"); 2611 return OMX_ErrorInvalidState; 2612 } 2613 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX 2614 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) { 2615 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush " 2616 "to invalid port: %u", (unsigned int)param1); 2617 return OMX_ErrorBadPortIndex; 2618 } 2619 2620 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 2621 sem_wait(&m_cmd_lock); 2622 DEBUG_PRINT_LOW("send_command: Command Processed"); 2623 return OMX_ErrorNone; 2624 } 2625 2626 /* ====================================================================== 2627 FUNCTION 2628 omx_vdec::SendCommand 2629 2630 DESCRIPTION 2631 Returns zero if all the buffers released.. 2632 2633 PARAMETERS 2634 None. 2635 2636 RETURN VALUE 2637 true/false 2638 2639 ========================================================================== */ 2640 OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 2641 OMX_IN OMX_COMMANDTYPE cmd, 2642 OMX_IN OMX_U32 param1, 2643 OMX_IN OMX_PTR cmdData 2644 ) 2645 { 2646 (void) hComp; 2647 (void) cmdData; 2648 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2649 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 2650 int bFlag = 1,sem_posted = 0,ret=0; 2651 2652 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd); 2653 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d", 2654 m_state, eState); 2655 2656 if (cmd == OMX_CommandStateSet) { 2657 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); 2658 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); 2659 /***************************/ 2660 /* Current State is Loaded */ 2661 /***************************/ 2662 if (m_state == OMX_StateLoaded) { 2663 if (eState == OMX_StateIdle) { 2664 //if all buffers are allocated or all ports disabled 2665 if (allocate_done() || 2666 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) { 2667 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); 2668 } else { 2669 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); 2670 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 2671 // Skip the event notification 2672 bFlag = 0; 2673 } 2674 } 2675 /* Requesting transition from Loaded to Loaded */ 2676 else if (eState == OMX_StateLoaded) { 2677 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded"); 2678 post_event(OMX_EventError,OMX_ErrorSameState,\ 2679 OMX_COMPONENT_GENERATE_EVENT); 2680 eRet = OMX_ErrorSameState; 2681 } 2682 /* Requesting transition from Loaded to WaitForResources */ 2683 else if (eState == OMX_StateWaitForResources) { 2684 /* Since error is None , we will post an event 2685 at the end of this function definition */ 2686 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); 2687 } 2688 /* Requesting transition from Loaded to Executing */ 2689 else if (eState == OMX_StateExecuting) { 2690 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing"); 2691 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2692 OMX_COMPONENT_GENERATE_EVENT); 2693 eRet = OMX_ErrorIncorrectStateTransition; 2694 } 2695 /* Requesting transition from Loaded to Pause */ 2696 else if (eState == OMX_StatePause) { 2697 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause"); 2698 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2699 OMX_COMPONENT_GENERATE_EVENT); 2700 eRet = OMX_ErrorIncorrectStateTransition; 2701 } 2702 /* Requesting transition from Loaded to Invalid */ 2703 else if (eState == OMX_StateInvalid) { 2704 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid"); 2705 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2706 eRet = OMX_ErrorInvalidState; 2707 } else { 2708 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\ 2709 eState); 2710 eRet = OMX_ErrorBadParameter; 2711 } 2712 } 2713 2714 /***************************/ 2715 /* Current State is IDLE */ 2716 /***************************/ 2717 else if (m_state == OMX_StateIdle) { 2718 if (eState == OMX_StateLoaded) { 2719 if (release_done()) { 2720 /* 2721 Since error is None , we will post an event at the end 2722 of this function definition 2723 */ 2724 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded"); 2725 } else { 2726 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending"); 2727 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 2728 // Skip the event notification 2729 bFlag = 0; 2730 } 2731 } 2732 /* Requesting transition from Idle to Executing */ 2733 else if (eState == OMX_StateExecuting) { 2734 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2735 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); 2736 bFlag = 1; 2737 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2738 m_state=OMX_StateExecuting; 2739 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful"); 2740 } 2741 /* Requesting transition from Idle to Idle */ 2742 else if (eState == OMX_StateIdle) { 2743 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle"); 2744 post_event(OMX_EventError,OMX_ErrorSameState,\ 2745 OMX_COMPONENT_GENERATE_EVENT); 2746 eRet = OMX_ErrorSameState; 2747 } 2748 /* Requesting transition from Idle to WaitForResources */ 2749 else if (eState == OMX_StateWaitForResources) { 2750 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources"); 2751 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2752 OMX_COMPONENT_GENERATE_EVENT); 2753 eRet = OMX_ErrorIncorrectStateTransition; 2754 } 2755 /* Requesting transition from Idle to Pause */ 2756 else if (eState == OMX_StatePause) { 2757 /*To pause the Video core we need to start the driver*/ 2758 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 2759 NULL) < */0) { 2760 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED"); 2761 omx_report_error (); 2762 eRet = OMX_ErrorHardware; 2763 } else { 2764 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 2765 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause"); 2766 bFlag = 0; 2767 } 2768 } 2769 /* Requesting transition from Idle to Invalid */ 2770 else if (eState == OMX_StateInvalid) { 2771 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid"); 2772 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2773 eRet = OMX_ErrorInvalidState; 2774 } else { 2775 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState); 2776 eRet = OMX_ErrorBadParameter; 2777 } 2778 } 2779 2780 /******************************/ 2781 /* Current State is Executing */ 2782 /******************************/ 2783 else if (m_state == OMX_StateExecuting) { 2784 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting"); 2785 /* Requesting transition from Executing to Idle */ 2786 if (eState == OMX_StateIdle) { 2787 /* Since error is None , we will post an event 2788 at the end of this function definition 2789 */ 2790 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle"); 2791 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 2792 if (!sem_posted) { 2793 sem_posted = 1; 2794 sem_post (&m_cmd_lock); 2795 execute_omx_flush(OMX_ALL); 2796 } 2797 bFlag = 0; 2798 } 2799 /* Requesting transition from Executing to Paused */ 2800 else if (eState == OMX_StatePause) { 2801 DEBUG_PRINT_LOW("PAUSE Command Issued"); 2802 m_state = OMX_StatePause; 2803 bFlag = 1; 2804 } 2805 /* Requesting transition from Executing to Loaded */ 2806 else if (eState == OMX_StateLoaded) { 2807 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded"); 2808 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2809 OMX_COMPONENT_GENERATE_EVENT); 2810 eRet = OMX_ErrorIncorrectStateTransition; 2811 } 2812 /* Requesting transition from Executing to WaitForResources */ 2813 else if (eState == OMX_StateWaitForResources) { 2814 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources"); 2815 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2816 OMX_COMPONENT_GENERATE_EVENT); 2817 eRet = OMX_ErrorIncorrectStateTransition; 2818 } 2819 /* Requesting transition from Executing to Executing */ 2820 else if (eState == OMX_StateExecuting) { 2821 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing"); 2822 post_event(OMX_EventError,OMX_ErrorSameState,\ 2823 OMX_COMPONENT_GENERATE_EVENT); 2824 eRet = OMX_ErrorSameState; 2825 } 2826 /* Requesting transition from Executing to Invalid */ 2827 else if (eState == OMX_StateInvalid) { 2828 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid"); 2829 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2830 eRet = OMX_ErrorInvalidState; 2831 } else { 2832 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState); 2833 eRet = OMX_ErrorBadParameter; 2834 } 2835 } 2836 /***************************/ 2837 /* Current State is Pause */ 2838 /***************************/ 2839 else if (m_state == OMX_StatePause) { 2840 /* Requesting transition from Pause to Executing */ 2841 if (eState == OMX_StateExecuting) { 2842 DEBUG_PRINT_LOW("Pause --> Executing"); 2843 m_state = OMX_StateExecuting; 2844 bFlag = 1; 2845 } 2846 /* Requesting transition from Pause to Idle */ 2847 else if (eState == OMX_StateIdle) { 2848 /* Since error is None , we will post an event 2849 at the end of this function definition */ 2850 DEBUG_PRINT_LOW("Pause --> Idle"); 2851 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 2852 if (!sem_posted) { 2853 sem_posted = 1; 2854 sem_post (&m_cmd_lock); 2855 execute_omx_flush(OMX_ALL); 2856 } 2857 bFlag = 0; 2858 } 2859 /* Requesting transition from Pause to loaded */ 2860 else if (eState == OMX_StateLoaded) { 2861 DEBUG_PRINT_ERROR("Pause --> loaded"); 2862 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2863 OMX_COMPONENT_GENERATE_EVENT); 2864 eRet = OMX_ErrorIncorrectStateTransition; 2865 } 2866 /* Requesting transition from Pause to WaitForResources */ 2867 else if (eState == OMX_StateWaitForResources) { 2868 DEBUG_PRINT_ERROR("Pause --> WaitForResources"); 2869 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2870 OMX_COMPONENT_GENERATE_EVENT); 2871 eRet = OMX_ErrorIncorrectStateTransition; 2872 } 2873 /* Requesting transition from Pause to Pause */ 2874 else if (eState == OMX_StatePause) { 2875 DEBUG_PRINT_ERROR("Pause --> Pause"); 2876 post_event(OMX_EventError,OMX_ErrorSameState,\ 2877 OMX_COMPONENT_GENERATE_EVENT); 2878 eRet = OMX_ErrorSameState; 2879 } 2880 /* Requesting transition from Pause to Invalid */ 2881 else if (eState == OMX_StateInvalid) { 2882 DEBUG_PRINT_ERROR("Pause --> Invalid"); 2883 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2884 eRet = OMX_ErrorInvalidState; 2885 } else { 2886 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState); 2887 eRet = OMX_ErrorBadParameter; 2888 } 2889 } 2890 /***************************/ 2891 /* Current State is WaitForResources */ 2892 /***************************/ 2893 else if (m_state == OMX_StateWaitForResources) { 2894 /* Requesting transition from WaitForResources to Loaded */ 2895 if (eState == OMX_StateLoaded) { 2896 /* Since error is None , we will post an event 2897 at the end of this function definition */ 2898 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded"); 2899 } 2900 /* Requesting transition from WaitForResources to WaitForResources */ 2901 else if (eState == OMX_StateWaitForResources) { 2902 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources"); 2903 post_event(OMX_EventError,OMX_ErrorSameState, 2904 OMX_COMPONENT_GENERATE_EVENT); 2905 eRet = OMX_ErrorSameState; 2906 } 2907 /* Requesting transition from WaitForResources to Executing */ 2908 else if (eState == OMX_StateExecuting) { 2909 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing"); 2910 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2911 OMX_COMPONENT_GENERATE_EVENT); 2912 eRet = OMX_ErrorIncorrectStateTransition; 2913 } 2914 /* Requesting transition from WaitForResources to Pause */ 2915 else if (eState == OMX_StatePause) { 2916 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause"); 2917 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2918 OMX_COMPONENT_GENERATE_EVENT); 2919 eRet = OMX_ErrorIncorrectStateTransition; 2920 } 2921 /* Requesting transition from WaitForResources to Invalid */ 2922 else if (eState == OMX_StateInvalid) { 2923 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid"); 2924 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2925 eRet = OMX_ErrorInvalidState; 2926 } 2927 /* Requesting transition from WaitForResources to Loaded - 2928 is NOT tested by Khronos TS */ 2929 2930 } else { 2931 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState); 2932 eRet = OMX_ErrorBadParameter; 2933 } 2934 } 2935 /********************************/ 2936 /* Current State is Invalid */ 2937 /*******************************/ 2938 else if (m_state == OMX_StateInvalid) { 2939 /* State Transition from Inavlid to any state */ 2940 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources 2941 || OMX_StateIdle || OMX_StateExecuting 2942 || OMX_StatePause || OMX_StateInvalid)) { 2943 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded"); 2944 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 2945 OMX_COMPONENT_GENERATE_EVENT); 2946 eRet = OMX_ErrorInvalidState; 2947 } 2948 } else if (cmd == OMX_CommandFlush) { 2949 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued" 2950 "with param1: %u", (unsigned int)param1); 2951 #ifdef _MSM8974_ 2952 send_codec_config(); 2953 #endif 2954 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX || 2955 param1 == OMX_ALL)) { 2956 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) { 2957 struct timespec ts; 2958 2959 clock_gettime(CLOCK_REALTIME, &ts); 2960 ts.tv_sec += 2; 2961 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ", 2962 m_queued_codec_config_count); 2963 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED); 2964 if (sem_timedwait(&m_safe_flush, &ts)) { 2965 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers"); 2966 } 2967 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED); 2968 } 2969 } 2970 2971 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 2972 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 2973 } 2974 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 2975 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 2976 } 2977 if (!sem_posted) { 2978 sem_posted = 1; 2979 DEBUG_PRINT_LOW("Set the Semaphore"); 2980 sem_post (&m_cmd_lock); 2981 execute_omx_flush(param1); 2982 } 2983 bFlag = 0; 2984 } else if ( cmd == OMX_CommandPortEnable) { 2985 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued" 2986 "with param1: %u", (unsigned int)param1); 2987 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 2988 m_inp_bEnabled = OMX_TRUE; 2989 2990 if ( (m_state == OMX_StateLoaded && 2991 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2992 || allocate_input_done()) { 2993 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 2994 OMX_COMPONENT_GENERATE_EVENT); 2995 } else { 2996 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 2997 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 2998 // Skip the event notification 2999 bFlag = 0; 3000 } 3001 } 3002 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3003 DEBUG_PRINT_LOW("Enable output Port command recieved"); 3004 m_out_bEnabled = OMX_TRUE; 3005 3006 if ( (m_state == OMX_StateLoaded && 3007 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3008 || (allocate_output_done())) { 3009 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 3010 OMX_COMPONENT_GENERATE_EVENT); 3011 3012 } else { 3013 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 3014 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3015 // Skip the event notification 3016 bFlag = 0; 3017 /* enable/disable downscaling if required */ 3018 ret = decide_downscalar(); 3019 if (ret) { 3020 DEBUG_PRINT_LOW("decide_downscalar failed\n"); 3021 } 3022 } 3023 } 3024 } else if (cmd == OMX_CommandPortDisable) { 3025 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued" 3026 "with param1: %u", (unsigned int)param1); 3027 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 3028 codec_config_flag = false; 3029 m_inp_bEnabled = OMX_FALSE; 3030 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3031 && release_input_done()) { 3032 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 3033 OMX_COMPONENT_GENERATE_EVENT); 3034 } else { 3035 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 3036 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3037 if (!sem_posted) { 3038 sem_posted = 1; 3039 sem_post (&m_cmd_lock); 3040 } 3041 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 3042 } 3043 3044 // Skip the event notification 3045 bFlag = 0; 3046 } 3047 } 3048 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3049 m_out_bEnabled = OMX_FALSE; 3050 DEBUG_PRINT_LOW("Disable output Port command recieved"); 3051 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3052 && release_output_done()) { 3053 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 3054 OMX_COMPONENT_GENERATE_EVENT); 3055 } else { 3056 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 3057 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3058 if (!sem_posted) { 3059 sem_posted = 1; 3060 sem_post (&m_cmd_lock); 3061 } 3062 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 3063 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 3064 } 3065 // Skip the event notification 3066 bFlag = 0; 3067 3068 } 3069 } 3070 } else { 3071 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd); 3072 eRet = OMX_ErrorNotImplemented; 3073 } 3074 if (eRet == OMX_ErrorNone && bFlag) { 3075 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 3076 } 3077 if (!sem_posted) { 3078 sem_post(&m_cmd_lock); 3079 } 3080 3081 return eRet; 3082 } 3083 3084 /* ====================================================================== 3085 FUNCTION 3086 omx_vdec::ExecuteOmxFlush 3087 3088 DESCRIPTION 3089 Executes the OMX flush. 3090 3091 PARAMETERS 3092 flushtype - input flush(1)/output flush(0)/ both. 3093 3094 RETURN VALUE 3095 true/false 3096 3097 ========================================================================== */ 3098 bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 3099 { 3100 bool bRet = false; 3101 struct v4l2_plane plane; 3102 struct v4l2_buffer v4l2_buf; 3103 struct v4l2_decoder_cmd dec; 3104 DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType); 3105 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 3106 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; 3107 3108 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig); 3109 3110 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) { 3111 output_flush_progress = true; 3112 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3113 } else { 3114 /* XXX: The driver/hardware does not support flushing of individual ports 3115 * in all states. So we pretty much need to flush both ports internally, 3116 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it 3117 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, 3118 * we automatically omit sending the FLUSH done for the "opposite" port. */ 3119 input_flush_progress = true; 3120 output_flush_progress = true; 3121 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3122 request_perf_level(VIDC_TURBO); 3123 } 3124 3125 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 3126 DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType); 3127 bRet = false; 3128 } 3129 3130 return bRet; 3131 } 3132 /*========================================================================= 3133 FUNCTION : execute_output_flush 3134 3135 DESCRIPTION 3136 Executes the OMX flush at OUTPUT PORT. 3137 3138 PARAMETERS 3139 None. 3140 3141 RETURN VALUE 3142 true/false 3143 ==========================================================================*/ 3144 bool omx_vdec::execute_output_flush() 3145 { 3146 unsigned long p1 = 0; // Parameter - 1 3147 unsigned long p2 = 0; // Parameter - 2 3148 unsigned long ident = 0; 3149 bool bRet = true; 3150 3151 /*Generate FBD for all Buffers in the FTBq*/ 3152 pthread_mutex_lock(&m_lock); 3153 DEBUG_PRINT_LOW("Initiate Output Flush"); 3154 3155 //reset last render TS 3156 if(m_last_rendered_TS > 0) { 3157 m_last_rendered_TS = 0; 3158 } 3159 3160 while (m_ftb_q.m_size) { 3161 DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d", 3162 m_ftb_q.m_size,pending_output_buffers); 3163 m_ftb_q.pop_entry(&p1,&p2,&ident); 3164 DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2); 3165 if (ident == m_fill_output_msg ) { 3166 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2); 3167 } else if (ident == OMX_COMPONENT_GENERATE_FBD) { 3168 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1); 3169 } 3170 } 3171 pthread_mutex_unlock(&m_lock); 3172 output_flush_progress = false; 3173 3174 if (arbitrary_bytes) { 3175 prev_ts = LLONG_MAX; 3176 rst_prev_ts = true; 3177 } 3178 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); 3179 return bRet; 3180 } 3181 /*========================================================================= 3182 FUNCTION : execute_input_flush 3183 3184 DESCRIPTION 3185 Executes the OMX flush at INPUT PORT. 3186 3187 PARAMETERS 3188 None. 3189 3190 RETURN VALUE 3191 true/false 3192 ==========================================================================*/ 3193 bool omx_vdec::execute_input_flush() 3194 { 3195 unsigned i =0; 3196 unsigned long p1 = 0; // Parameter - 1 3197 unsigned long p2 = 0; // Parameter - 2 3198 unsigned long ident = 0; 3199 bool bRet = true; 3200 3201 /*Generate EBD for all Buffers in the ETBq*/ 3202 DEBUG_PRINT_LOW("Initiate Input Flush"); 3203 3204 pthread_mutex_lock(&m_lock); 3205 DEBUG_PRINT_LOW("Check if the Queue is empty"); 3206 while (m_etb_q.m_size) { 3207 m_etb_q.pop_entry(&p1,&p2,&ident); 3208 3209 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 3210 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 3211 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 3212 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 3213 pending_input_buffers++; 3214 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 3215 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 3216 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 3217 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 3218 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p", 3219 (OMX_BUFFERHEADERTYPE *)p1); 3220 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 3221 } 3222 } 3223 time_stamp_dts.flush_timestamp(); 3224 /*Check if Heap Buffers are to be flushed*/ 3225 if (arbitrary_bytes && !(codec_config_flag)) { 3226 DEBUG_PRINT_LOW("Reset all the variables before flusing"); 3227 h264_scratch.nFilledLen = 0; 3228 nal_count = 0; 3229 look_ahead_nal = false; 3230 frame_count = 0; 3231 h264_last_au_ts = LLONG_MAX; 3232 h264_last_au_flags = 0; 3233 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 3234 m_demux_entries = 0; 3235 DEBUG_PRINT_LOW("Initialize parser"); 3236 if (m_frame_parser.mutils) { 3237 m_frame_parser.mutils->initialize_frame_checking_environment(); 3238 } 3239 3240 while (m_input_pending_q.m_size) { 3241 m_input_pending_q.pop_entry(&p1,&p2,&ident); 3242 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 3243 } 3244 3245 if (psource_frame) { 3246 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 3247 psource_frame = NULL; 3248 } 3249 3250 if (pdest_frame) { 3251 pdest_frame->nFilledLen = 0; 3252 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL, 3253 (unsigned int)NULL); 3254 pdest_frame = NULL; 3255 } 3256 m_frame_parser.flush(); 3257 } else if (codec_config_flag) { 3258 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " 3259 "is not sent to the driver yet"); 3260 } 3261 pthread_mutex_unlock(&m_lock); 3262 input_flush_progress = false; 3263 if (!arbitrary_bytes) { 3264 prev_ts = LLONG_MAX; 3265 rst_prev_ts = true; 3266 } 3267 #ifdef _ANDROID_ 3268 if (m_debug_timestamp) { 3269 m_timestamp_list.reset_ts_list(); 3270 } 3271 #endif 3272 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); 3273 return bRet; 3274 } 3275 3276 3277 /* ====================================================================== 3278 FUNCTION 3279 omx_vdec::SendCommandEvent 3280 3281 DESCRIPTION 3282 Send the event to decoder pipe. This is needed to generate the callbacks 3283 in decoder thread context. 3284 3285 PARAMETERS 3286 None. 3287 3288 RETURN VALUE 3289 true/false 3290 3291 ========================================================================== */ 3292 bool omx_vdec::post_event(unsigned long p1, 3293 unsigned long p2, 3294 unsigned long id) 3295 { 3296 bool bRet = false; 3297 3298 /* Just drop messages typically generated by hardware (w/o client request), 3299 * if we've reported an error to client. */ 3300 if (m_error_propogated) { 3301 switch (id) { 3302 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 3303 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 3304 DEBUG_PRINT_ERROR("Dropping message %lx " 3305 "since client expected to be in error state", id); 3306 return false; 3307 default: 3308 /* whatever */ 3309 break; 3310 } 3311 } 3312 3313 pthread_mutex_lock(&m_lock); 3314 3315 if (id == m_fill_output_msg || 3316 id == OMX_COMPONENT_GENERATE_FBD || 3317 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG || 3318 id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) { 3319 m_ftb_q.insert_entry(p1,p2,id); 3320 } else if (id == OMX_COMPONENT_GENERATE_ETB || 3321 id == OMX_COMPONENT_GENERATE_EBD || 3322 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY || 3323 id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) { 3324 m_etb_q.insert_entry(p1,p2,id); 3325 } else { 3326 m_cmd_q.insert_entry(p1,p2,id); 3327 } 3328 3329 bRet = true; 3330 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); 3331 post_message(this, id); 3332 3333 pthread_mutex_unlock(&m_lock); 3334 3335 return bRet; 3336 } 3337 3338 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 3339 { 3340 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3341 if (!profileLevelType) 3342 return OMX_ErrorBadParameter; 3343 3344 if (profileLevelType->nPortIndex == 0) { 3345 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 3346 if (profileLevelType->nProfileIndex == 0) { 3347 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 3348 profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; 3349 3350 } else if (profileLevelType->nProfileIndex == 1) { 3351 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 3352 profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; 3353 } else if (profileLevelType->nProfileIndex == 2) { 3354 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 3355 profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; 3356 } else { 3357 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3358 (unsigned int)profileLevelType->nProfileIndex); 3359 eRet = OMX_ErrorNoMore; 3360 } 3361 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 3362 if (profileLevelType->nProfileIndex == 0) { 3363 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh; 3364 profileLevelType->eLevel = QOMX_VIDEO_MVCLevel51; 3365 } else { 3366 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3367 (unsigned int)profileLevelType->nProfileIndex); 3368 eRet = OMX_ErrorNoMore; 3369 } 3370 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 3371 if (profileLevelType->nProfileIndex == 0) { 3372 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain; 3373 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3374 } else if (profileLevelType->nProfileIndex == 1) { 3375 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10; 3376 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3377 } else { 3378 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3379 (unsigned int)profileLevelType->nProfileIndex); 3380 eRet = OMX_ErrorNoMore; 3381 } 3382 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) { 3383 if (profileLevelType->nProfileIndex == 0) { 3384 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 3385 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 3386 } else { 3387 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3388 (unsigned int)profileLevelType->nProfileIndex); 3389 eRet = OMX_ErrorNoMore; 3390 } 3391 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 3392 if (profileLevelType->nProfileIndex == 0) { 3393 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3394 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3395 } else if (profileLevelType->nProfileIndex == 1) { 3396 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 3397 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3398 } else { 3399 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3400 (unsigned int)profileLevelType->nProfileIndex); 3401 eRet = OMX_ErrorNoMore; 3402 } 3403 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || 3404 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 3405 eRet = OMX_ErrorNoMore; 3406 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 3407 if (profileLevelType->nProfileIndex == 0) { 3408 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; 3409 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3410 } else if (profileLevelType->nProfileIndex == 1) { 3411 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; 3412 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3413 } else { 3414 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3415 (unsigned int)profileLevelType->nProfileIndex); 3416 eRet = OMX_ErrorNoMore; 3417 } 3418 } else { 3419 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind); 3420 eRet = OMX_ErrorNoMore; 3421 } 3422 } else { 3423 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u", 3424 (unsigned int)profileLevelType->nPortIndex); 3425 eRet = OMX_ErrorBadPortIndex; 3426 } 3427 return eRet; 3428 } 3429 3430 /* ====================================================================== 3431 FUNCTION 3432 omx_vdec::GetParameter 3433 3434 DESCRIPTION 3435 OMX Get Parameter method implementation 3436 3437 PARAMETERS 3438 <TBD>. 3439 3440 RETURN VALUE 3441 Error None if successful. 3442 3443 ========================================================================== */ 3444 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 3445 OMX_IN OMX_INDEXTYPE paramIndex, 3446 OMX_INOUT OMX_PTR paramData) 3447 { 3448 (void) hComp; 3449 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3450 3451 DEBUG_PRINT_LOW("get_parameter:"); 3452 if (m_state == OMX_StateInvalid) { 3453 DEBUG_PRINT_ERROR("Get Param in Invalid State"); 3454 return OMX_ErrorInvalidState; 3455 } 3456 if (paramData == NULL) { 3457 DEBUG_PRINT_LOW("Get Param in Invalid paramData"); 3458 return OMX_ErrorBadParameter; 3459 } 3460 switch ((unsigned long)paramIndex) { 3461 case OMX_IndexParamPortDefinition: { 3462 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 3463 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = 3464 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 3465 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition"); 3466 decide_dpb_buffer_mode(is_down_scalar_enabled); 3467 eRet = update_portdef(portDefn); 3468 if (eRet == OMX_ErrorNone) 3469 m_port_def = *portDefn; 3470 break; 3471 } 3472 case OMX_IndexParamVideoInit: { 3473 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3474 OMX_PORT_PARAM_TYPE *portParamType = 3475 (OMX_PORT_PARAM_TYPE *) paramData; 3476 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); 3477 3478 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3479 portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3480 portParamType->nPorts = 2; 3481 portParamType->nStartPortNumber = 0; 3482 break; 3483 } 3484 case OMX_IndexParamVideoPortFormat: { 3485 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 3486 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 3487 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 3488 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); 3489 3490 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 3491 portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); 3492 3493 if (0 == portFmt->nPortIndex) { 3494 if (0 == portFmt->nIndex) { 3495 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 3496 portFmt->eCompressionFormat = eCompressionFormat; 3497 } else { 3498 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3499 " NoMore compression formats"); 3500 eRet = OMX_ErrorNoMore; 3501 } 3502 } else if (1 == portFmt->nPortIndex) { 3503 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 3504 3505 // Distinguish non-surface mode from normal playback use-case based on 3506 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2" 3507 // For non-android, use the default list 3508 // Also use default format-list if FLEXIBLE YUV is supported, 3509 // as the client negotiates the standard color-format if it needs to 3510 bool useNonSurfaceMode = false; 3511 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) 3512 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE); 3513 #endif 3514 if (is_thulium_v1) { 3515 portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex); 3516 } else { 3517 portFmt->eColorFormat = useNonSurfaceMode ? 3518 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) : 3519 getPreferredColorFormatDefaultMode(portFmt->nIndex); 3520 } 3521 3522 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) { 3523 eRet = OMX_ErrorNoMore; 3524 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3525 " NoMore Color formats"); 3526 } 3527 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat); 3528 } else { 3529 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d", 3530 (int)portFmt->nPortIndex); 3531 eRet = OMX_ErrorBadPortIndex; 3532 } 3533 break; 3534 } 3535 /*Component should support this port definition*/ 3536 case OMX_IndexParamAudioInit: { 3537 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3538 OMX_PORT_PARAM_TYPE *audioPortParamType = 3539 (OMX_PORT_PARAM_TYPE *) paramData; 3540 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); 3541 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3542 audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3543 audioPortParamType->nPorts = 0; 3544 audioPortParamType->nStartPortNumber = 0; 3545 break; 3546 } 3547 /*Component should support this port definition*/ 3548 case OMX_IndexParamImageInit: { 3549 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3550 OMX_PORT_PARAM_TYPE *imagePortParamType = 3551 (OMX_PORT_PARAM_TYPE *) paramData; 3552 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); 3553 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3554 imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3555 imagePortParamType->nPorts = 0; 3556 imagePortParamType->nStartPortNumber = 0; 3557 break; 3558 3559 } 3560 /*Component should support this port definition*/ 3561 case OMX_IndexParamOtherInit: { 3562 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x", 3563 paramIndex); 3564 eRet =OMX_ErrorUnsupportedIndex; 3565 break; 3566 } 3567 case OMX_IndexParamStandardComponentRole: { 3568 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 3569 OMX_PARAM_COMPONENTROLETYPE *comp_role; 3570 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 3571 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 3572 comp_role->nSize = sizeof(*comp_role); 3573 3574 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d", 3575 paramIndex); 3576 strlcpy((char*)comp_role->cRole,(const char*)m_cRole, 3577 OMX_MAX_STRINGNAME_SIZE); 3578 break; 3579 } 3580 /* Added for parameter test */ 3581 case OMX_IndexParamPriorityMgmt: { 3582 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 3583 OMX_PRIORITYMGMTTYPE *priorityMgmType = 3584 (OMX_PRIORITYMGMTTYPE *) paramData; 3585 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); 3586 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 3587 priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE); 3588 3589 break; 3590 } 3591 /* Added for parameter test */ 3592 case OMX_IndexParamCompBufferSupplier: { 3593 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 3594 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 3595 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 3596 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); 3597 3598 bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); 3599 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 3600 if (0 == bufferSupplierType->nPortIndex) 3601 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3602 else if (1 == bufferSupplierType->nPortIndex) 3603 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3604 else 3605 eRet = OMX_ErrorBadPortIndex; 3606 3607 3608 break; 3609 } 3610 case OMX_IndexParamVideoAvc: { 3611 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x", 3612 paramIndex); 3613 break; 3614 } 3615 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 3616 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x", 3617 paramIndex); 3618 break; 3619 } 3620 case OMX_IndexParamVideoH263: { 3621 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x", 3622 paramIndex); 3623 break; 3624 } 3625 case OMX_IndexParamVideoMpeg4: { 3626 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x", 3627 paramIndex); 3628 break; 3629 } 3630 case OMX_IndexParamVideoMpeg2: { 3631 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x", 3632 paramIndex); 3633 break; 3634 } 3635 case OMX_IndexParamVideoProfileLevelQuerySupported: { 3636 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3637 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex); 3638 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = 3639 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 3640 eRet = get_supported_profile_level(profileLevelType); 3641 break; 3642 } 3643 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3644 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: { 3645 VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams); 3646 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); 3647 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; 3648 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 3649 3650 if (secure_mode && !secure_scaling_to_non_secure_opb) { 3651 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | 3652 GRALLOC_USAGE_PRIVATE_UNCACHED); 3653 } else { 3654 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED; 3655 } 3656 } else { 3657 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); 3658 eRet = OMX_ErrorBadParameter; 3659 } 3660 } 3661 break; 3662 #endif 3663 3664 #ifdef FLEXYUV_SUPPORTED 3665 case OMX_QcomIndexFlexibleYUVDescription: { 3666 DEBUG_PRINT_LOW("get_parameter: describeColorFormat"); 3667 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams); 3668 eRet = describeColorFormat(paramData); 3669 break; 3670 } 3671 #endif 3672 case OMX_IndexParamVideoProfileLevelCurrent: { 3673 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3674 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 3675 struct v4l2_control profile_control, level_control; 3676 3677 switch (drv_ctx.decoder_format) { 3678 case VDEC_CODECTYPE_H264: 3679 profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 3680 level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 3681 break; 3682 default: 3683 DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264"); 3684 eRet = OMX_ErrorNotImplemented; 3685 break; 3686 } 3687 3688 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) { 3689 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) { 3690 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 3691 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 3692 pParam->eProfile = OMX_VIDEO_AVCProfileBaseline; 3693 break; 3694 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 3695 pParam->eProfile = OMX_VIDEO_AVCProfileMain; 3696 break; 3697 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 3698 pParam->eProfile = OMX_VIDEO_AVCProfileExtended; 3699 break; 3700 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 3701 pParam->eProfile = OMX_VIDEO_AVCProfileHigh; 3702 break; 3703 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 3704 pParam->eProfile = OMX_VIDEO_AVCProfileHigh10; 3705 break; 3706 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 3707 pParam->eProfile = OMX_VIDEO_AVCProfileHigh422; 3708 break; 3709 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 3710 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA: 3711 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA: 3712 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA: 3713 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA: 3714 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE: 3715 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH: 3716 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA: 3717 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH: 3718 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH: 3719 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: 3720 eRet = OMX_ErrorUnsupportedIndex; 3721 break; 3722 } 3723 } else { 3724 eRet = OMX_ErrorUnsupportedIndex; 3725 } 3726 3727 3728 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) { 3729 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) { 3730 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 3731 pParam->eLevel = OMX_VIDEO_AVCLevel1; 3732 break; 3733 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 3734 pParam->eLevel = OMX_VIDEO_AVCLevel1b; 3735 break; 3736 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 3737 pParam->eLevel = OMX_VIDEO_AVCLevel11; 3738 break; 3739 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 3740 pParam->eLevel = OMX_VIDEO_AVCLevel12; 3741 break; 3742 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 3743 pParam->eLevel = OMX_VIDEO_AVCLevel13; 3744 break; 3745 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 3746 pParam->eLevel = OMX_VIDEO_AVCLevel2; 3747 break; 3748 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 3749 pParam->eLevel = OMX_VIDEO_AVCLevel21; 3750 break; 3751 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 3752 pParam->eLevel = OMX_VIDEO_AVCLevel22; 3753 break; 3754 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 3755 pParam->eLevel = OMX_VIDEO_AVCLevel3; 3756 break; 3757 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 3758 pParam->eLevel = OMX_VIDEO_AVCLevel31; 3759 break; 3760 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 3761 pParam->eLevel = OMX_VIDEO_AVCLevel32; 3762 break; 3763 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 3764 pParam->eLevel = OMX_VIDEO_AVCLevel4; 3765 break; 3766 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 3767 pParam->eLevel = OMX_VIDEO_AVCLevel41; 3768 break; 3769 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 3770 pParam->eLevel = OMX_VIDEO_AVCLevel42; 3771 break; 3772 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 3773 pParam->eLevel = OMX_VIDEO_AVCLevel5; 3774 break; 3775 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 3776 pParam->eLevel = OMX_VIDEO_AVCLevel51; 3777 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: 3778 pParam->eLevel = OMX_VIDEO_AVCLevel52; 3779 break; 3780 } 3781 } else { 3782 eRet = OMX_ErrorUnsupportedIndex; 3783 } 3784 3785 break; 3786 3787 } 3788 default: { 3789 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex); 3790 eRet =OMX_ErrorUnsupportedIndex; 3791 } 3792 3793 } 3794 3795 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", 3796 drv_ctx.video_resolution.frame_width, 3797 drv_ctx.video_resolution.frame_height, 3798 drv_ctx.video_resolution.stride, 3799 drv_ctx.video_resolution.scan_lines); 3800 3801 return eRet; 3802 } 3803 3804 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3805 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) 3806 { 3807 DEBUG_PRINT_LOW("Inside use_android_native_buffer"); 3808 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3809 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; 3810 3811 if ((params == NULL) || 3812 (params->nativeBuffer == NULL) || 3813 (params->nativeBuffer->handle == NULL) || 3814 !m_enable_android_native_buffers) 3815 return OMX_ErrorBadParameter; 3816 m_use_android_native_buffers = OMX_TRUE; 3817 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 3818 private_handle_t *handle = (private_handle_t *)nBuf->handle; 3819 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port 3820 OMX_U8 *buffer = NULL; 3821 if (!secure_mode) { 3822 buffer = (OMX_U8*)mmap(0, handle->size, 3823 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 3824 if (buffer == MAP_FAILED) { 3825 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 3826 return OMX_ErrorInsufficientResources; 3827 } 3828 } 3829 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); 3830 } else { 3831 eRet = OMX_ErrorBadParameter; 3832 } 3833 return eRet; 3834 } 3835 #endif 3836 3837 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() { 3838 struct v4l2_control control; 3839 struct v4l2_format fmt; 3840 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; 3841 control.value = 1; 3842 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 3843 if (rc < 0) { 3844 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 3845 return OMX_ErrorHardware; 3846 } 3847 m_smoothstreaming_mode = true; 3848 return OMX_ErrorNone; 3849 } 3850 3851 /* ====================================================================== 3852 FUNCTION 3853 omx_vdec::Setparameter 3854 3855 DESCRIPTION 3856 OMX Set Parameter method implementation. 3857 3858 PARAMETERS 3859 <TBD>. 3860 3861 RETURN VALUE 3862 OMX Error None if successful. 3863 3864 ========================================================================== */ 3865 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 3866 OMX_IN OMX_INDEXTYPE paramIndex, 3867 OMX_IN OMX_PTR paramData) 3868 { 3869 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3870 int ret=0; 3871 struct v4l2_format fmt; 3872 #ifdef _ANDROID_ 3873 char property_value[PROPERTY_VALUE_MAX] = {0}; 3874 #endif 3875 if (m_state == OMX_StateInvalid) { 3876 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 3877 return OMX_ErrorInvalidState; 3878 } 3879 if (paramData == NULL) { 3880 DEBUG_PRINT_ERROR("Get Param in Invalid paramData"); 3881 return OMX_ErrorBadParameter; 3882 } 3883 if ((m_state != OMX_StateLoaded) && 3884 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && 3885 (m_out_bEnabled == OMX_TRUE) && 3886 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && 3887 (m_inp_bEnabled == OMX_TRUE)) { 3888 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 3889 return OMX_ErrorIncorrectStateOperation; 3890 } 3891 switch ((unsigned long)paramIndex) { 3892 case OMX_IndexParamPortDefinition: { 3893 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 3894 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 3895 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 3896 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has 3897 //been called. 3898 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", 3899 (int)portDefn->format.video.nFrameHeight, 3900 (int)portDefn->format.video.nFrameWidth); 3901 3902 if (portDefn->nBufferCountActual >= MAX_NUM_INPUT_OUTPUT_BUFFERS) { 3903 DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d", 3904 portDefn->nBufferCountActual); 3905 eRet = OMX_ErrorBadParameter; 3906 break; 3907 } 3908 if (OMX_DirOutput == portDefn->eDir) { 3909 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); 3910 bool port_format_changed = false; 3911 m_display_id = portDefn->format.video.pNativeWindow; 3912 unsigned int buffer_size; 3913 /* update output port resolution with client supplied dimensions 3914 in case scaling is enabled, else it follows input resolution set 3915 */ 3916 decide_dpb_buffer_mode(is_down_scalar_enabled); 3917 if (is_down_scalar_enabled) { 3918 DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)", 3919 (unsigned int)portDefn->format.video.nFrameWidth, 3920 (unsigned int)portDefn->format.video.nFrameHeight); 3921 if (portDefn->format.video.nFrameHeight != 0x0 && 3922 portDefn->format.video.nFrameWidth != 0x0) { 3923 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 3924 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3925 fmt.fmt.pix_mp.pixelformat = capture_capability; 3926 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 3927 if (ret) { 3928 DEBUG_PRINT_ERROR("Get Resolution failed"); 3929 eRet = OMX_ErrorHardware; 3930 break; 3931 } 3932 if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) || 3933 (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) { 3934 port_format_changed = true; 3935 } 3936 update_resolution(portDefn->format.video.nFrameWidth, 3937 portDefn->format.video.nFrameHeight, 3938 portDefn->format.video.nFrameWidth, 3939 portDefn->format.video.nFrameHeight); 3940 3941 /* set crop info */ 3942 rectangle.nLeft = 0; 3943 rectangle.nTop = 0; 3944 rectangle.nWidth = portDefn->format.video.nFrameWidth; 3945 rectangle.nHeight = portDefn->format.video.nFrameHeight; 3946 3947 eRet = is_video_session_supported(); 3948 if (eRet) 3949 break; 3950 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 3951 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3952 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 3953 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 3954 fmt.fmt.pix_mp.pixelformat = capture_capability; 3955 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d", 3956 fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width); 3957 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 3958 if (ret) { 3959 DEBUG_PRINT_ERROR("Set Resolution failed"); 3960 eRet = OMX_ErrorUnsupportedSetting; 3961 } else 3962 eRet = get_buffer_req(&drv_ctx.op_buf); 3963 } 3964 3965 if (eRet) { 3966 break; 3967 } 3968 3969 if (secure_mode) { 3970 struct v4l2_control control; 3971 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD; 3972 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 3973 DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id); 3974 eRet = OMX_ErrorHardware; 3975 } else { 3976 /* This is a workaround for a bug in fw which uses stride 3977 * and slice instead of width and height to check against 3978 * the threshold. 3979 */ 3980 OMX_U32 stride, slice; 3981 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 3982 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth); 3983 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight); 3984 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 3985 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth); 3986 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight); 3987 } else { 3988 stride = portDefn->format.video.nFrameWidth; 3989 slice = portDefn->format.video.nFrameHeight; 3990 } 3991 3992 DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice); 3993 DEBUG_PRINT_LOW("Threshold value is %d\n", control.value); 3994 3995 if (stride * slice <= (OMX_U32)control.value) { 3996 secure_scaling_to_non_secure_opb = true; 3997 DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ"); 3998 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2; 3999 control.value = 1; 4000 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) { 4001 DEBUG_PRINT_ERROR("Enabling non-secure output2 failed"); 4002 eRet = OMX_ErrorUnsupportedSetting; 4003 } 4004 } 4005 } 4006 } 4007 } 4008 4009 if (eRet) { 4010 break; 4011 } 4012 4013 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4014 DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)", 4015 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4016 eRet = OMX_ErrorBadParameter; 4017 } else if (!client_buffers.get_buffer_req(buffer_size)) { 4018 DEBUG_PRINT_ERROR("Error in getting buffer requirements"); 4019 eRet = OMX_ErrorBadParameter; 4020 } else if (!port_format_changed) { 4021 4022 // Buffer count can change only when port is disabled 4023 if (!release_output_done()) { 4024 DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !"); 4025 eRet = OMX_ErrorInvalidState; 4026 break; 4027 } 4028 4029 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && 4030 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) { 4031 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; 4032 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; 4033 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount; 4034 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count * 4035 drv_ctx.extradata_info.buffer_size; 4036 eRet = set_buffer_req(&drv_ctx.op_buf); 4037 if (eRet == OMX_ErrorNone) 4038 m_port_def = *portDefn; 4039 } else { 4040 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)", 4041 drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size, 4042 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4043 eRet = OMX_ErrorBadParameter; 4044 } 4045 } 4046 } else if (OMX_DirInput == portDefn->eDir) { 4047 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); 4048 bool port_format_changed = false; 4049 if ((portDefn->format.video.xFramerate >> 16) > 0 && 4050 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) { 4051 // Frame rate only should be set if this is a "known value" or to 4052 // activate ts prediction logic (arbitrary mode only) sending input 4053 // timestamps with max value (LLONG_MAX). 4054 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u", 4055 (unsigned int)portDefn->format.video.xFramerate >> 16); 4056 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, 4057 drv_ctx.frame_rate.fps_denominator); 4058 if (!drv_ctx.frame_rate.fps_numerator) { 4059 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 4060 drv_ctx.frame_rate.fps_numerator = 30; 4061 } 4062 if (drv_ctx.frame_rate.fps_denominator) 4063 drv_ctx.frame_rate.fps_numerator = (int) 4064 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 4065 drv_ctx.frame_rate.fps_denominator = 1; 4066 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 4067 drv_ctx.frame_rate.fps_numerator; 4068 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", 4069 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 4070 (float)drv_ctx.frame_rate.fps_denominator); 4071 4072 struct v4l2_outputparm oparm; 4073 /*XXX: we're providing timing info as seconds per frame rather than frames 4074 * per second.*/ 4075 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 4076 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 4077 4078 struct v4l2_streamparm sparm; 4079 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4080 sparm.parm.output = oparm; 4081 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 4082 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected"); 4083 eRet = OMX_ErrorHardware; 4084 break; 4085 } 4086 m_perf_control.request_cores(frm_int); 4087 } 4088 4089 if (drv_ctx.video_resolution.frame_height != 4090 portDefn->format.video.nFrameHeight || 4091 drv_ctx.video_resolution.frame_width != 4092 portDefn->format.video.nFrameWidth) { 4093 DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)", 4094 (unsigned int)portDefn->format.video.nFrameWidth, 4095 (unsigned int)portDefn->format.video.nFrameHeight); 4096 port_format_changed = true; 4097 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth; 4098 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight; 4099 if (frameHeight != 0x0 && frameWidth != 0x0) { 4100 if (m_smoothstreaming_mode && 4101 ((frameWidth * frameHeight) < 4102 (m_smoothstreaming_width * m_smoothstreaming_height))) { 4103 frameWidth = m_smoothstreaming_width; 4104 frameHeight = m_smoothstreaming_height; 4105 DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u " 4106 "for adaptive-playback/smooth-streaming", 4107 (unsigned int)frameWidth, (unsigned int)frameHeight); 4108 } 4109 update_resolution(frameWidth, frameHeight, 4110 frameWidth, frameHeight); 4111 eRet = is_video_session_supported(); 4112 if (eRet) 4113 break; 4114 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4115 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4116 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4117 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4118 fmt.fmt.pix_mp.pixelformat = output_capability; 4119 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 4120 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4121 if (ret) { 4122 DEBUG_PRINT_ERROR("Set Resolution failed"); 4123 eRet = OMX_ErrorUnsupportedSetting; 4124 } else { 4125 if (!is_down_scalar_enabled) 4126 eRet = get_buffer_req(&drv_ctx.op_buf); 4127 } 4128 } 4129 } 4130 if (m_custom_buffersize.input_buffersize 4131 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) { 4132 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d", 4133 m_custom_buffersize.input_buffersize, portDefn->nBufferSize); 4134 eRet = OMX_ErrorBadParameter; 4135 break; 4136 } 4137 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4138 DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)", 4139 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4140 eRet = OMX_ErrorBadParameter; 4141 break; 4142 } 4143 // Buffer count can change only when port is disabled 4144 if (!release_input_done()) { 4145 DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !"); 4146 eRet = OMX_ErrorInvalidState; 4147 break; 4148 } 4149 4150 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount 4151 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) { 4152 port_format_changed = true; 4153 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; 4154 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; 4155 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & 4156 (~(buffer_prop->alignment - 1)); 4157 eRet = set_buffer_req(buffer_prop); 4158 } 4159 if (false == port_format_changed) { 4160 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)", 4161 drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size, 4162 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4163 eRet = OMX_ErrorBadParameter; 4164 } 4165 } else if (portDefn->eDir == OMX_DirMax) { 4166 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 4167 (int)portDefn->nPortIndex); 4168 eRet = OMX_ErrorBadPortIndex; 4169 } 4170 } 4171 break; 4172 case OMX_IndexParamVideoPortFormat: { 4173 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 4174 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 4175 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 4176 int ret=0; 4177 struct v4l2_format fmt; 4178 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u", 4179 portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex); 4180 4181 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4182 if (1 == portFmt->nPortIndex) { 4183 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4184 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4185 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4186 enum vdec_output_fromat op_format; 4187 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4188 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m || 4189 portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4190 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView || 4191 portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar || 4192 portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 4193 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; 4194 } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4195 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4196 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC; 4197 } else 4198 eRet = OMX_ErrorBadParameter; 4199 4200 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4201 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4202 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC; 4203 } else { 4204 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12; 4205 } 4206 4207 if (eRet == OMX_ErrorNone) { 4208 drv_ctx.output_format = op_format; 4209 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4210 if (ret) { 4211 DEBUG_PRINT_ERROR("Set output format failed"); 4212 eRet = OMX_ErrorUnsupportedSetting; 4213 /*TODO: How to handle this case */ 4214 } else { 4215 eRet = get_buffer_req(&drv_ctx.op_buf); 4216 } 4217 } 4218 if (eRet == OMX_ErrorNone) { 4219 if (!client_buffers.set_color_format(portFmt->eColorFormat)) { 4220 DEBUG_PRINT_ERROR("Set color format failed"); 4221 eRet = OMX_ErrorBadParameter; 4222 } 4223 } 4224 } 4225 } 4226 break; 4227 4228 case OMX_QcomIndexPortDefn: { 4229 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE); 4230 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 4231 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 4232 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u", 4233 (unsigned int)portFmt->nFramePackingFormat); 4234 4235 /* Input port */ 4236 if (portFmt->nPortIndex == 0) { 4237 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) { 4238 if (secure_mode || m_input_pass_buffer_fd) { 4239 arbitrary_bytes = false; 4240 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode"); 4241 eRet = OMX_ErrorUnsupportedSetting; 4242 } else { 4243 arbitrary_bytes = true; 4244 } 4245 } else if (portFmt->nFramePackingFormat == 4246 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) { 4247 arbitrary_bytes = false; 4248 #ifdef _ANDROID_ 4249 property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 4250 if (atoi(property_value)) { 4251 DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command"); 4252 arbitrary_bytes = true; 4253 } 4254 #endif 4255 } else { 4256 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u", 4257 (unsigned int)portFmt->nFramePackingFormat); 4258 eRet = OMX_ErrorUnsupportedSetting; 4259 } 4260 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 4261 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); 4262 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && 4263 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && 4264 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) { 4265 m_out_mem_region_smi = OMX_TRUE; 4266 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4267 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set"); 4268 m_use_output_pmem = OMX_TRUE; 4269 } 4270 } 4271 } 4272 } 4273 if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 4274 OMX_MAX_STRINGNAME_SIZE)) { 4275 arbitrary_bytes = true; 4276 DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264"); 4277 } 4278 break; 4279 4280 case OMX_IndexParamStandardComponentRole: { 4281 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 4282 OMX_PARAM_COMPONENTROLETYPE *comp_role; 4283 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 4284 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", 4285 comp_role->cRole); 4286 4287 if ((m_state == OMX_StateLoaded)&& 4288 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) { 4289 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 4290 } else { 4291 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4292 return OMX_ErrorIncorrectStateOperation; 4293 } 4294 4295 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4296 if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4297 strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE); 4298 } else { 4299 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4300 eRet =OMX_ErrorUnsupportedSetting; 4301 } 4302 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4303 if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4304 strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 4305 } else { 4306 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4307 eRet = OMX_ErrorUnsupportedSetting; 4308 } 4309 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4310 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4311 strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE); 4312 } else { 4313 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4314 eRet = OMX_ErrorUnsupportedSetting; 4315 } 4316 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4317 if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4318 strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE); 4319 } else { 4320 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4321 eRet =OMX_ErrorUnsupportedSetting; 4322 } 4323 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4324 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4325 strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE); 4326 } else { 4327 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4328 eRet = OMX_ErrorUnsupportedSetting; 4329 } 4330 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) || 4331 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) || 4332 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE)) 4333 ) { 4334 if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) { 4335 strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE); 4336 } else { 4337 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4338 eRet =OMX_ErrorUnsupportedSetting; 4339 } 4340 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) || 4341 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) 4342 ) { 4343 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 4344 strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE); 4345 } else { 4346 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4347 eRet =OMX_ErrorUnsupportedSetting; 4348 } 4349 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 4350 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 4351 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4352 strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE); 4353 } else { 4354 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4355 eRet = OMX_ErrorUnsupportedSetting; 4356 } 4357 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 4358 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) || 4359 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4360 strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE); 4361 } else { 4362 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4363 eRet = OMX_ErrorUnsupportedSetting; 4364 } 4365 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4366 if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4367 strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 4368 } else { 4369 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4370 eRet = OMX_ErrorUnsupportedSetting; 4371 } 4372 } else { 4373 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind); 4374 eRet = OMX_ErrorInvalidComponentName; 4375 } 4376 break; 4377 } 4378 4379 case OMX_IndexParamPriorityMgmt: { 4380 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 4381 if (m_state != OMX_StateLoaded) { 4382 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4383 return OMX_ErrorIncorrectStateOperation; 4384 } 4385 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 4386 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u", 4387 (unsigned int)priorityMgmtype->nGroupID); 4388 4389 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u", 4390 (unsigned int)priorityMgmtype->nGroupPriority); 4391 4392 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 4393 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 4394 4395 break; 4396 } 4397 4398 case OMX_IndexParamCompBufferSupplier: { 4399 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 4400 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 4401 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d", 4402 bufferSupplierType->eBufferSupplier); 4403 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 4404 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 4405 4406 else 4407 4408 eRet = OMX_ErrorBadPortIndex; 4409 4410 break; 4411 4412 } 4413 case OMX_IndexParamVideoAvc: { 4414 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d", 4415 paramIndex); 4416 break; 4417 } 4418 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 4419 DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d", 4420 paramIndex); 4421 break; 4422 } 4423 case OMX_IndexParamVideoH263: { 4424 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d", 4425 paramIndex); 4426 break; 4427 } 4428 case OMX_IndexParamVideoMpeg4: { 4429 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d", 4430 paramIndex); 4431 break; 4432 } 4433 case OMX_IndexParamVideoMpeg2: { 4434 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d", 4435 paramIndex); 4436 break; 4437 } 4438 case OMX_QcomIndexParamVideoDecoderPictureOrder: { 4439 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER); 4440 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = 4441 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; 4442 struct v4l2_control control; 4443 int pic_order,rc=0; 4444 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d", 4445 pictureOrder->eOutputPictureOrder); 4446 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { 4447 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 4448 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) { 4449 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4450 time_stamp_dts.set_timestamp_reorder_mode(false); 4451 } else 4452 eRet = OMX_ErrorBadParameter; 4453 if (eRet == OMX_ErrorNone) { 4454 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4455 control.value = pic_order; 4456 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4457 if (rc) { 4458 DEBUG_PRINT_ERROR("Set picture order failed"); 4459 eRet = OMX_ErrorUnsupportedSetting; 4460 } 4461 } 4462 break; 4463 } 4464 case OMX_QcomIndexParamConcealMBMapExtraData: 4465 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4466 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, 4467 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4468 break; 4469 case OMX_QcomIndexParamFrameInfoExtraData: 4470 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4471 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 4472 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4473 break; 4474 case OMX_ExtraDataFrameDimension: 4475 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4476 eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false, 4477 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4478 break; 4479 case OMX_QcomIndexParamInterlaceExtraData: 4480 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4481 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, 4482 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4483 break; 4484 case OMX_QcomIndexParamH264TimeInfo: 4485 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4486 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, 4487 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4488 break; 4489 case OMX_QcomIndexParamVideoFramePackingExtradata: 4490 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4491 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false, 4492 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4493 break; 4494 case OMX_QcomIndexParamVideoQPExtraData: 4495 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4496 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 4497 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4498 break; 4499 case OMX_QcomIndexParamVideoInputBitsInfoExtraData: 4500 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4501 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false, 4502 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4503 break; 4504 case OMX_QcomIndexEnableExtnUserData: 4505 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4506 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false, 4507 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4508 break; 4509 case OMX_QTIIndexParamVQZipSEIExtraData: 4510 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4511 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 4512 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4513 break; 4514 case OMX_QcomIndexParamVideoDivx: { 4515 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; 4516 } 4517 break; 4518 case OMX_QcomIndexPlatformPvt: { 4519 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN); 4520 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); 4521 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; 4522 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 4523 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); 4524 eRet = OMX_ErrorUnsupportedSetting; 4525 } else { 4526 m_out_pvt_entry_pmem = OMX_TRUE; 4527 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4528 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set"); 4529 m_use_output_pmem = OMX_TRUE; 4530 } 4531 } 4532 4533 } 4534 break; 4535 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: { 4536 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); 4537 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); 4538 struct v4l2_control control; 4539 int rc; 4540 drv_ctx.idr_only_decoding = 1; 4541 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4542 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4543 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4544 if (rc) { 4545 DEBUG_PRINT_ERROR("Set picture order failed"); 4546 eRet = OMX_ErrorUnsupportedSetting; 4547 } else { 4548 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; 4549 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; 4550 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4551 if (rc) { 4552 DEBUG_PRINT_ERROR("Sync frame setting failed"); 4553 eRet = OMX_ErrorUnsupportedSetting; 4554 } 4555 /*Setting sync frame decoding on driver might change buffer 4556 * requirements so update them here*/ 4557 if (get_buffer_req(&drv_ctx.ip_buf)) { 4558 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements"); 4559 eRet = OMX_ErrorUnsupportedSetting; 4560 } 4561 if (get_buffer_req(&drv_ctx.op_buf)) { 4562 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements"); 4563 eRet = OMX_ErrorUnsupportedSetting; 4564 } 4565 } 4566 } 4567 break; 4568 4569 case OMX_QcomIndexParamIndexExtraDataType: { 4570 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE); 4571 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; 4572 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && 4573 (extradataIndexType->bEnabled == OMX_TRUE) && 4574 (extradataIndexType->nPortIndex == 1)) { 4575 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); 4576 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); 4577 4578 } 4579 } 4580 break; 4581 case OMX_QcomIndexParamEnableSmoothStreaming: { 4582 #ifndef SMOOTH_STREAMING_DISABLED 4583 eRet = enable_smoothstreaming(); 4584 #else 4585 eRet = OMX_ErrorUnsupportedSetting; 4586 #endif 4587 } 4588 break; 4589 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 4590 /* Need to allow following two set_parameters even in Idle 4591 * state. This is ANDROID architecture which is not in sync 4592 * with openmax standard. */ 4593 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: { 4594 VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams); 4595 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; 4596 if (enableNativeBuffers) { 4597 m_enable_android_native_buffers = enableNativeBuffers->enable; 4598 } 4599 #if !defined(FLEXYUV_SUPPORTED) 4600 if (m_enable_android_native_buffers) { 4601 // Use the most-preferred-native-color-format as surface-mode is hinted here 4602 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) { 4603 DEBUG_PRINT_ERROR("Failed to set native color format!"); 4604 eRet = OMX_ErrorUnsupportedSetting; 4605 } 4606 } 4607 #endif 4608 } 4609 break; 4610 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: { 4611 VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams); 4612 eRet = use_android_native_buffer(hComp, paramData); 4613 } 4614 break; 4615 case OMX_GoogleAndroidIndexAllocateNativeHandle: { 4616 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData; 4617 if (allocateNativeHandleParams != NULL) { 4618 allocate_native_handle = allocateNativeHandleParams->enable; 4619 } 4620 } 4621 break; 4622 #endif 4623 case OMX_QcomIndexParamEnableTimeStampReorder: { 4624 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER); 4625 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; 4626 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { 4627 if (reorder->bEnable == OMX_TRUE) { 4628 frm_int =0; 4629 time_stamp_dts.set_timestamp_reorder_mode(true); 4630 } else 4631 time_stamp_dts.set_timestamp_reorder_mode(false); 4632 } else { 4633 time_stamp_dts.set_timestamp_reorder_mode(false); 4634 if (reorder->bEnable == OMX_TRUE) { 4635 eRet = OMX_ErrorUnsupportedSetting; 4636 } 4637 } 4638 } 4639 break; 4640 case OMX_IndexParamVideoProfileLevelCurrent: { 4641 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 4642 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = 4643 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 4644 if (pParam) { 4645 m_profile_lvl.eProfile = pParam->eProfile; 4646 m_profile_lvl.eLevel = pParam->eLevel; 4647 } 4648 break; 4649 4650 } 4651 case OMX_QcomIndexParamVideoMetaBufferMode: 4652 { 4653 VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams); 4654 StoreMetaDataInBuffersParams *metabuffer = 4655 (StoreMetaDataInBuffersParams *)paramData; 4656 if (!metabuffer) { 4657 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer); 4658 eRet = OMX_ErrorBadParameter; 4659 break; 4660 } 4661 if (m_disable_dynamic_buf_mode) { 4662 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled"); 4663 eRet = OMX_ErrorUnsupportedSetting; 4664 break; 4665 } 4666 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 4667 //set property dynamic buffer mode to driver. 4668 struct v4l2_control control; 4669 struct v4l2_format fmt; 4670 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT; 4671 if (metabuffer->bStoreMetaData == true) { 4672 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC; 4673 } else { 4674 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC; 4675 } 4676 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 4677 if (!rc) { 4678 DEBUG_PRINT_HIGH("%s buffer mode", 4679 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic"); 4680 dynamic_buf_mode = metabuffer->bStoreMetaData; 4681 } else { 4682 DEBUG_PRINT_ERROR("Failed to %s buffer mode", 4683 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic"); 4684 eRet = OMX_ErrorUnsupportedSetting; 4685 } 4686 } else { 4687 DEBUG_PRINT_ERROR( 4688 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u", 4689 (unsigned int)metabuffer->nPortIndex); 4690 eRet = OMX_ErrorUnsupportedSetting; 4691 } 4692 break; 4693 } 4694 case OMX_QcomIndexParamVideoDownScalar: 4695 { 4696 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR); 4697 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData; 4698 struct v4l2_control control; 4699 int rc; 4700 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable); 4701 4702 if (pParam && pParam->bEnable) { 4703 rc = enable_downscalar(); 4704 if (rc < 0) { 4705 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 4706 return OMX_ErrorUnsupportedSetting; 4707 } 4708 m_force_down_scalar = pParam->bEnable; 4709 } else { 4710 rc = disable_downscalar(); 4711 if (rc < 0) { 4712 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 4713 return OMX_ErrorUnsupportedSetting; 4714 } 4715 m_force_down_scalar = pParam->bEnable; 4716 } 4717 break; 4718 } 4719 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 4720 case OMX_QcomIndexParamVideoAdaptivePlaybackMode: 4721 { 4722 VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams); 4723 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback"); 4724 PrepareForAdaptivePlaybackParams* pParams = 4725 (PrepareForAdaptivePlaybackParams *) paramData; 4726 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 4727 if (!pParams->bEnable) { 4728 return OMX_ErrorNone; 4729 } 4730 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth 4731 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) { 4732 DEBUG_PRINT_ERROR( 4733 "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]", 4734 (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight, 4735 (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight); 4736 eRet = OMX_ErrorBadParameter; 4737 } else { 4738 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight); 4739 } 4740 } else { 4741 DEBUG_PRINT_ERROR( 4742 "Prepare for adaptive playback supported only on output port"); 4743 eRet = OMX_ErrorBadParameter; 4744 } 4745 break; 4746 } 4747 4748 case OMX_QTIIndexParamVideoPreferAdaptivePlayback: 4749 { 4750 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4751 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback"); 4752 m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable; 4753 if (m_disable_dynamic_buf_mode) { 4754 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set"); 4755 } 4756 break; 4757 } 4758 #endif 4759 case OMX_QcomIndexParamVideoCustomBufferSize: 4760 { 4761 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE); 4762 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize"); 4763 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData; 4764 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 4765 struct v4l2_control control; 4766 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT; 4767 control.value = pParam->nBufferSize; 4768 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 4769 DEBUG_PRINT_ERROR("Failed to set input buffer size"); 4770 eRet = OMX_ErrorUnsupportedSetting; 4771 } else { 4772 eRet = get_buffer_req(&drv_ctx.ip_buf); 4773 if (eRet == OMX_ErrorNone) { 4774 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size; 4775 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d", 4776 m_custom_buffersize.input_buffersize); 4777 } else { 4778 DEBUG_PRINT_ERROR("Failed to get buffer requirement"); 4779 } 4780 } 4781 } else { 4782 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port"); 4783 eRet = OMX_ErrorBadParameter; 4784 } 4785 break; 4786 } 4787 case OMX_QTIIndexParamVQZIPSEIType: 4788 { 4789 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE); 4790 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType"); 4791 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam = 4792 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData; 4793 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable); 4794 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 4795 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4796 if (eRet != OMX_ErrorNone) { 4797 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata"); 4798 eRet = OMX_ErrorBadParameter; 4799 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 4800 } else { 4801 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 4802 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4803 if (eRet != OMX_ErrorNone) { 4804 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata"); 4805 eRet = OMX_ErrorBadParameter; 4806 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 4807 client_extradata = client_extradata & ~OMX_QP_EXTRADATA; 4808 } 4809 } 4810 break; 4811 } 4812 4813 case OMX_QTIIndexParamPassInputBufferFd: 4814 { 4815 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4816 if (arbitrary_bytes) { 4817 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode"); 4818 eRet = OMX_ErrorUnsupportedSetting; 4819 break; 4820 } 4821 4822 m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable; 4823 if (m_input_pass_buffer_fd) 4824 DEBUG_PRINT_LOW("Enable passing input buffer FD"); 4825 break; 4826 } 4827 case OMX_QTIIndexParamForceCompressedForDPB: 4828 { 4829 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE); 4830 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB"); 4831 OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam = 4832 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData; 4833 if (m_disable_ubwc_mode) { 4834 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled"); 4835 eRet = OMX_ErrorUnsupportedSetting; 4836 break; 4837 } 4838 if (!paramData) { 4839 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL"); 4840 eRet = OMX_ErrorBadParameter; 4841 break; 4842 } 4843 4844 m_force_compressed_for_dpb = pParam->bEnable; 4845 break; 4846 } 4847 case OMX_QTIIndexParamForceUnCompressedForOPB: 4848 { 4849 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE); 4850 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB"); 4851 OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam = 4852 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData; 4853 if (!paramData) { 4854 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL"); 4855 eRet = OMX_ErrorBadParameter; 4856 break; 4857 } 4858 m_disable_ubwc_mode = pParam->bEnable; 4859 DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled"); 4860 break; 4861 } 4862 4863 4864 default: { 4865 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex); 4866 eRet = OMX_ErrorUnsupportedIndex; 4867 } 4868 } 4869 if (eRet != OMX_ErrorNone) 4870 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex); 4871 return eRet; 4872 } 4873 4874 /* ====================================================================== 4875 FUNCTION 4876 omx_vdec::GetConfig 4877 4878 DESCRIPTION 4879 OMX Get Config Method implementation. 4880 4881 PARAMETERS 4882 <TBD>. 4883 4884 RETURN VALUE 4885 OMX Error None if successful. 4886 4887 ========================================================================== */ 4888 OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 4889 OMX_IN OMX_INDEXTYPE configIndex, 4890 OMX_INOUT OMX_PTR configData) 4891 { 4892 (void) hComp; 4893 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4894 4895 if (m_state == OMX_StateInvalid) { 4896 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 4897 return OMX_ErrorInvalidState; 4898 } 4899 4900 switch ((unsigned long)configIndex) { 4901 case OMX_QcomIndexConfigInterlaced: { 4902 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE); 4903 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 4904 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 4905 if (configFmt->nPortIndex == 1) { 4906 if (configFmt->nIndex == 0) { 4907 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 4908 } else if (configFmt->nIndex == 1) { 4909 configFmt->eInterlaceType = 4910 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 4911 } else if (configFmt->nIndex == 2) { 4912 configFmt->eInterlaceType = 4913 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 4914 } else { 4915 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 4916 " NoMore Interlaced formats"); 4917 eRet = OMX_ErrorNoMore; 4918 } 4919 4920 } else { 4921 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port", 4922 (int)configFmt->nPortIndex); 4923 eRet = OMX_ErrorBadPortIndex; 4924 } 4925 break; 4926 } 4927 case OMX_QcomIndexQueryNumberOfVideoDecInstance: { 4928 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES); 4929 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 4930 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 4931 decoderinstances->nNumOfInstances = 16; 4932 /*TODO: How to handle this case */ 4933 break; 4934 } 4935 case OMX_QcomIndexConfigVideoFramePackingArrangement: { 4936 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) { 4937 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT); 4938 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = 4939 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; 4940 memcpy(configFmt, &m_frame_pack_arrangement, 4941 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 4942 } else { 4943 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); 4944 } 4945 break; 4946 } 4947 case OMX_IndexConfigCommonOutputCrop: { 4948 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE); 4949 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; 4950 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); 4951 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u", 4952 rectangle.nLeft, rectangle.nTop, 4953 rectangle.nWidth, rectangle.nHeight); 4954 break; 4955 } 4956 case OMX_QcomIndexConfigPerfLevel: { 4957 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); 4958 struct v4l2_control control; 4959 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 4960 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 4961 4962 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 4963 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 4964 DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno); 4965 eRet = OMX_ErrorHardware; 4966 } 4967 4968 if (eRet == OMX_ErrorNone) { 4969 switch (control.value) { 4970 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO: 4971 perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo; 4972 break; 4973 default: 4974 DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value); 4975 /* Fall through */ 4976 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL: 4977 perf->ePerfLevel = OMX_QCOM_PerfLevelNominal; 4978 break; 4979 } 4980 } 4981 4982 break; 4983 } 4984 case OMX_QcomIndexConfigH264EntropyCodingCabac: { 4985 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE); 4986 QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData; 4987 struct v4l2_control control; 4988 4989 if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) { 4990 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264"); 4991 eRet = OMX_ErrorNotImplemented; 4992 break; 4993 } 4994 4995 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 4996 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) { 4997 coding->bCabac = (OMX_BOOL) 4998 (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC); 4999 /* We can't query driver at the moment for the cabac mode, so 5000 * just use 0xff...f as a place holder for future improvement */ 5001 coding->nCabacInitIdc = ~0; 5002 } else { 5003 eRet = OMX_ErrorUnsupportedIndex; 5004 } 5005 5006 break; 5007 } 5008 case OMX_QTIIndexConfigDescribeColorAspects: 5009 { 5010 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5011 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5012 5013 print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client"); 5014 print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal"); 5015 5016 if (params->bRequestingDataSpace) { 5017 DEBUG_PRINT_ERROR("Does not handle dataspace request"); 5018 return OMX_ErrorUnsupportedSetting; 5019 } 5020 if (m_internal_color_space.bDataSpaceChanged == OMX_TRUE) { 5021 DEBUG_PRINT_LOW("Updating Client's color aspects with internal"); 5022 memcpy(&(m_client_color_space.sAspects), 5023 &(m_internal_color_space.sAspects), sizeof(ColorAspects)); 5024 m_internal_color_space.bDataSpaceChanged = OMX_FALSE; 5025 } 5026 memcpy(&(params->sAspects), &(m_client_color_space.sAspects), sizeof(ColorAspects)); 5027 5028 break; 5029 } 5030 default: { 5031 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex); 5032 eRet = OMX_ErrorBadParameter; 5033 } 5034 5035 } 5036 5037 return eRet; 5038 } 5039 5040 /* ====================================================================== 5041 FUNCTION 5042 omx_vdec::SetConfig 5043 5044 DESCRIPTION 5045 OMX Set Config method implementation 5046 5047 PARAMETERS 5048 <TBD>. 5049 5050 RETURN VALUE 5051 OMX Error None if successful. 5052 ========================================================================== */ 5053 OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 5054 OMX_IN OMX_INDEXTYPE configIndex, 5055 OMX_IN OMX_PTR configData) 5056 { 5057 (void) hComp; 5058 if (m_state == OMX_StateInvalid) { 5059 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 5060 return OMX_ErrorInvalidState; 5061 } 5062 5063 OMX_ERRORTYPE ret = OMX_ErrorNone; 5064 OMX_VIDEO_CONFIG_NALSIZE *pNal; 5065 5066 DEBUG_PRINT_LOW("Set Config Called"); 5067 5068 if (configIndex == OMX_IndexConfigVideoNalSize) { 5069 struct v4l2_control temp; 5070 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT; 5071 5072 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE); 5073 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 5074 switch (pNal->nNaluBytes) { 5075 case 0: 5076 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES; 5077 break; 5078 case 2: 5079 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH; 5080 break; 5081 case 4: 5082 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH; 5083 break; 5084 default: 5085 return OMX_ErrorUnsupportedSetting; 5086 } 5087 5088 if (!arbitrary_bytes) { 5089 /* In arbitrary bytes mode, the assembler strips out nal size and replaces 5090 * with start code, so only need to notify driver in frame by frame mode */ 5091 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) { 5092 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT"); 5093 return OMX_ErrorHardware; 5094 } 5095 } 5096 5097 nal_length = pNal->nNaluBytes; 5098 m_frame_parser.init_nal_length(nal_length); 5099 5100 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length); 5101 return ret; 5102 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) { 5103 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData; 5104 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps); 5105 5106 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 5107 if (config->bEnabled) { 5108 if ((config->nFps >> 16) > 0) { 5109 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u", 5110 (unsigned int)config->nFps >> 16); 5111 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator, 5112 drv_ctx.frame_rate.fps_denominator); 5113 5114 if (!drv_ctx.frame_rate.fps_numerator) { 5115 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 5116 drv_ctx.frame_rate.fps_numerator = 30; 5117 } 5118 5119 if (drv_ctx.frame_rate.fps_denominator) { 5120 drv_ctx.frame_rate.fps_numerator = (int) 5121 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 5122 } 5123 5124 drv_ctx.frame_rate.fps_denominator = 1; 5125 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 5126 drv_ctx.frame_rate.fps_numerator; 5127 5128 struct v4l2_outputparm oparm; 5129 /*XXX: we're providing timing info as seconds per frame rather than frames 5130 * per second.*/ 5131 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 5132 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 5133 5134 struct v4l2_streamparm sparm; 5135 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5136 sparm.parm.output = oparm; 5137 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 5138 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 5139 performance might be affected"); 5140 ret = OMX_ErrorHardware; 5141 } 5142 client_set_fps = true; 5143 } else { 5144 DEBUG_PRINT_ERROR("Frame rate not supported."); 5145 ret = OMX_ErrorUnsupportedSetting; 5146 } 5147 } else { 5148 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate"); 5149 client_set_fps = false; 5150 } 5151 } else { 5152 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d", 5153 (int)config->nPortIndex); 5154 ret = OMX_ErrorBadPortIndex; 5155 } 5156 5157 return ret; 5158 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) { 5159 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 5160 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 5161 struct v4l2_control control; 5162 5163 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel); 5164 5165 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5166 5167 switch (perf->ePerfLevel) { 5168 case OMX_QCOM_PerfLevelNominal: 5169 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 5170 break; 5171 case OMX_QCOM_PerfLevelTurbo: 5172 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 5173 break; 5174 default: 5175 ret = OMX_ErrorUnsupportedSetting; 5176 break; 5177 } 5178 5179 if (ret == OMX_ErrorNone) { 5180 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5181 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5182 } 5183 5184 return ret; 5185 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) { 5186 OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config = 5187 (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData; 5188 struct v4l2_control control; 5189 DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType); 5190 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE; 5191 5192 switch (config->eDecodeType) { 5193 case OMX_QCOM_PictypeDecode_I: 5194 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON; 5195 break; 5196 case OMX_QCOM_PictypeDecode_IPB: 5197 default: 5198 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF; 5199 break; 5200 } 5201 5202 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5203 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5204 if (ret) 5205 DEBUG_PRINT_ERROR("Failed to set picture type decode"); 5206 5207 return ret; 5208 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) { 5209 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData; 5210 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32); 5211 5212 struct v4l2_control control; 5213 5214 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY; 5215 if (priority->nU32 == 0) 5216 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE; 5217 else 5218 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE; 5219 5220 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5221 DEBUG_PRINT_ERROR("Failed to set Priority"); 5222 ret = OMX_ErrorUnsupportedSetting; 5223 } 5224 return ret; 5225 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) { 5226 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData; 5227 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16); 5228 5229 struct v4l2_control control; 5230 5231 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE; 5232 control.value = rate->nU32; 5233 5234 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5235 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources : 5236 OMX_ErrorUnsupportedSetting; 5237 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)", 5238 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno)); 5239 } 5240 return ret; 5241 5242 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) { 5243 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5244 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5245 if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) { 5246 enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true); 5247 } 5248 5249 print_debug_color_aspects(&(params->sAspects), "Set Config"); 5250 memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams)); 5251 return ret; 5252 } 5253 5254 return OMX_ErrorNotImplemented; 5255 } 5256 5257 #define extn_equals(param, extn) (!strcmp(param, extn)) 5258 5259 /* ====================================================================== 5260 FUNCTION 5261 omx_vdec::GetExtensionIndex 5262 5263 DESCRIPTION 5264 OMX GetExtensionIndex method implementaion. <TBD> 5265 5266 PARAMETERS 5267 <TBD>. 5268 5269 RETURN VALUE 5270 OMX Error None if everything successful. 5271 5272 ========================================================================== */ 5273 OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 5274 OMX_IN OMX_STRING paramName, 5275 OMX_OUT OMX_INDEXTYPE* indexType) 5276 { 5277 (void) hComp; 5278 if (m_state == OMX_StateInvalid) { 5279 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State"); 5280 return OMX_ErrorInvalidState; 5281 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) { 5282 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; 5283 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) { 5284 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; 5285 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) { 5286 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata; 5287 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) { 5288 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement; 5289 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) { 5290 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData; 5291 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) { 5292 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData; 5293 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) { 5294 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData; 5295 } 5296 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 5297 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) { 5298 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; 5299 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) { 5300 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; 5301 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) { 5302 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName); 5303 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; 5304 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) { 5305 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; 5306 } else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) { 5307 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle; 5308 } 5309 #endif 5310 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) { 5311 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; 5312 } 5313 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 5314 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) { 5315 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode; 5316 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) { 5317 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback; 5318 } 5319 #endif 5320 #ifdef FLEXYUV_SUPPORTED 5321 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) { 5322 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription; 5323 } 5324 #endif 5325 else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) { 5326 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd; 5327 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) { 5328 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB; 5329 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) { 5330 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB; 5331 } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) { 5332 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects; 5333 } else { 5334 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName); 5335 return OMX_ErrorNotImplemented; 5336 } 5337 return OMX_ErrorNone; 5338 } 5339 5340 /* ====================================================================== 5341 FUNCTION 5342 omx_vdec::GetState 5343 5344 DESCRIPTION 5345 Returns the state information back to the caller.<TBD> 5346 5347 PARAMETERS 5348 <TBD>. 5349 5350 RETURN VALUE 5351 Error None if everything is successful. 5352 ========================================================================== */ 5353 OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 5354 OMX_OUT OMX_STATETYPE* state) 5355 { 5356 (void) hComp; 5357 *state = m_state; 5358 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); 5359 return OMX_ErrorNone; 5360 } 5361 5362 /* ====================================================================== 5363 FUNCTION 5364 omx_vdec::ComponentTunnelRequest 5365 5366 DESCRIPTION 5367 OMX Component Tunnel Request method implementation. <TBD> 5368 5369 PARAMETERS 5370 None. 5371 5372 RETURN VALUE 5373 OMX Error None if everything successful. 5374 5375 ========================================================================== */ 5376 OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 5377 OMX_IN OMX_U32 port, 5378 OMX_IN OMX_HANDLETYPE peerComponent, 5379 OMX_IN OMX_U32 peerPort, 5380 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 5381 { 5382 (void) hComp; 5383 (void) port; 5384 (void) peerComponent; 5385 (void) peerPort; 5386 (void) tunnelSetup; 5387 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented"); 5388 return OMX_ErrorNotImplemented; 5389 } 5390 5391 /* ====================================================================== 5392 FUNCTION 5393 omx_vdec::UseOutputBuffer 5394 5395 DESCRIPTION 5396 Helper function for Use buffer in the input pin 5397 5398 PARAMETERS 5399 None. 5400 5401 RETURN VALUE 5402 true/false 5403 5404 ========================================================================== */ 5405 OMX_ERRORTYPE omx_vdec::allocate_extradata() 5406 { 5407 #ifdef USE_ION 5408 if (drv_ctx.extradata_info.buffer_size) { 5409 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { 5410 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5411 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5412 free_ion_memory(&drv_ctx.extradata_info.ion); 5413 } 5414 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); 5415 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( 5416 drv_ctx.extradata_info.size, 4096, 5417 &drv_ctx.extradata_info.ion.ion_alloc_data, 5418 &drv_ctx.extradata_info.ion.fd_ion_data, 0); 5419 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { 5420 DEBUG_PRINT_ERROR("Failed to alloc extradata memory"); 5421 return OMX_ErrorInsufficientResources; 5422 } 5423 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, 5424 drv_ctx.extradata_info.size, 5425 PROT_READ|PROT_WRITE, MAP_SHARED, 5426 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); 5427 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { 5428 DEBUG_PRINT_ERROR("Failed to map extradata memory"); 5429 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5430 free_ion_memory(&drv_ctx.extradata_info.ion); 5431 return OMX_ErrorInsufficientResources; 5432 } 5433 } 5434 #endif 5435 if (!m_other_extradata) { 5436 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size); 5437 if (!m_other_extradata) { 5438 DEBUG_PRINT_ERROR("Failed to alloc memory\n"); 5439 return OMX_ErrorInsufficientResources; 5440 } 5441 } 5442 return OMX_ErrorNone; 5443 } 5444 5445 void omx_vdec::free_extradata() 5446 { 5447 #ifdef USE_ION 5448 if (drv_ctx.extradata_info.uaddr) { 5449 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5450 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5451 free_ion_memory(&drv_ctx.extradata_info.ion); 5452 } 5453 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 5454 #endif 5455 if (m_other_extradata) { 5456 free(m_other_extradata); 5457 m_other_extradata = NULL; 5458 } 5459 } 5460 5461 OMX_ERRORTYPE omx_vdec::use_output_buffer( 5462 OMX_IN OMX_HANDLETYPE hComp, 5463 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5464 OMX_IN OMX_U32 port, 5465 OMX_IN OMX_PTR appData, 5466 OMX_IN OMX_U32 bytes, 5467 OMX_IN OMX_U8* buffer) 5468 { 5469 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5470 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 5471 unsigned i= 0; // Temporary counter 5472 struct vdec_setbuffer_cmd setbuffers; 5473 OMX_PTR privateAppData = NULL; 5474 private_handle_t *handle = NULL; 5475 OMX_U8 *buff = buffer; 5476 struct v4l2_buffer buf; 5477 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 5478 int extra_idx = 0; 5479 (void) hComp; 5480 (void) port; 5481 5482 if (!m_out_mem_ptr) { 5483 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); 5484 eRet = allocate_output_headers(); 5485 if (eRet == OMX_ErrorNone) 5486 eRet = allocate_extradata(); 5487 } 5488 5489 if (eRet == OMX_ErrorNone) { 5490 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 5491 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 5492 break; 5493 } 5494 } 5495 } 5496 5497 if (i >= drv_ctx.op_buf.actualcount) { 5498 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount); 5499 eRet = OMX_ErrorInsufficientResources; 5500 } 5501 5502 if (eRet != OMX_ErrorNone) 5503 return eRet; 5504 5505 if (dynamic_buf_mode) { 5506 *bufferHdr = (m_out_mem_ptr + i ); 5507 (*bufferHdr)->pBuffer = NULL; 5508 if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) { 5509 enum v4l2_buf_type buf_type; 5510 int rr = 0; 5511 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5512 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) { 5513 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr); 5514 return OMX_ErrorInsufficientResources; 5515 } else { 5516 streaming[CAPTURE_PORT] = true; 5517 DEBUG_PRINT_LOW("STREAMON Successful"); 5518 } 5519 5520 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 5521 request_perf_level(VIDC_TURBO); 5522 } 5523 BITMASK_SET(&m_out_bm_count,i); 5524 (*bufferHdr)->pAppPrivate = appData; 5525 (*bufferHdr)->pBuffer = buffer; 5526 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 5527 return eRet; 5528 } 5529 5530 if (eRet == OMX_ErrorNone) { 5531 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 5532 if (m_enable_android_native_buffers) { 5533 if (m_use_android_native_buffers) { 5534 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; 5535 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 5536 handle = (private_handle_t *)nBuf->handle; 5537 privateAppData = params->pAppPrivate; 5538 } else { 5539 handle = (private_handle_t *)buff; 5540 privateAppData = appData; 5541 } 5542 if (!handle) { 5543 DEBUG_PRINT_ERROR("handle is invalid"); 5544 return OMX_ErrorBadParameter; 5545 } 5546 5547 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 5548 if (secure_mode && secure_scaling_to_non_secure_opb) { 5549 DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it", 5550 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 5551 } else { 5552 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 5553 " expected %u, got %u", 5554 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 5555 return OMX_ErrorBadParameter; 5556 } 5557 } 5558 5559 drv_ctx.op_buf.buffer_size = handle->size; 5560 5561 if (!m_use_android_native_buffers) { 5562 if (!secure_mode) { 5563 buff = (OMX_U8*)mmap(0, handle->size, 5564 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 5565 if (buff == MAP_FAILED) { 5566 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 5567 return OMX_ErrorInsufficientResources; 5568 } 5569 } 5570 } 5571 #if defined(_ANDROID_ICS_) 5572 native_buffer[i].nativehandle = handle; 5573 native_buffer[i].privatehandle = handle; 5574 #endif 5575 if (!handle) { 5576 DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); 5577 return OMX_ErrorBadParameter; 5578 } 5579 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; 5580 drv_ctx.ptr_outputbuffer[i].offset = 0; 5581 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 5582 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 5583 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size; 5584 } else 5585 #endif 5586 5587 if (!ouput_egl_buffers && !m_use_output_pmem) { 5588 #ifdef USE_ION 5589 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 5590 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 5591 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 5592 &drv_ctx.op_buf_ion_info[i].fd_ion_data, 5593 secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0); 5594 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 5595 DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd); 5596 return OMX_ErrorInsufficientResources; 5597 } 5598 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 5599 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 5600 #else 5601 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 5602 open (MEM_DEVICE,O_RDWR); 5603 5604 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 5605 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 5606 return OMX_ErrorInsufficientResources; 5607 } 5608 5609 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ 5610 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) { 5611 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 5612 open (MEM_DEVICE,O_RDWR); 5613 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 5614 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 5615 return OMX_ErrorInsufficientResources; 5616 } 5617 } 5618 5619 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, 5620 drv_ctx.op_buf.buffer_size, 5621 drv_ctx.op_buf.alignment)) { 5622 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 5623 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 5624 return OMX_ErrorInsufficientResources; 5625 } 5626 #endif 5627 if (!secure_mode) { 5628 drv_ctx.ptr_outputbuffer[i].bufferaddr = 5629 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, 5630 PROT_READ|PROT_WRITE, MAP_SHARED, 5631 drv_ctx.ptr_outputbuffer[i].pmem_fd,0); 5632 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { 5633 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 5634 #ifdef USE_ION 5635 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 5636 #endif 5637 DEBUG_PRINT_ERROR("Unable to mmap output buffer"); 5638 return OMX_ErrorInsufficientResources; 5639 } 5640 } 5641 drv_ctx.ptr_outputbuffer[i].offset = 0; 5642 privateAppData = appData; 5643 } else { 5644 5645 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); 5646 if (!appData || !bytes ) { 5647 if (!secure_mode && !buffer) { 5648 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case"); 5649 return OMX_ErrorBadParameter; 5650 } 5651 } 5652 5653 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; 5654 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; 5655 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; 5656 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry || 5657 !pmem_list->nEntries || 5658 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 5659 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer"); 5660 return OMX_ErrorBadParameter; 5661 } 5662 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 5663 pmem_list->entryList->entry; 5664 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx", 5665 pmem_info->pmem_fd); 5666 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; 5667 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; 5668 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 5669 drv_ctx.ptr_outputbuffer[i].mmaped_size = 5670 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 5671 privateAppData = appData; 5672 } 5673 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 5674 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; 5675 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 5676 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 5677 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 5678 5679 *bufferHdr = (m_out_mem_ptr + i ); 5680 if (secure_mode) 5681 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 5682 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 5683 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], 5684 sizeof (vdec_bufferpayload)); 5685 5686 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, 5687 drv_ctx.ptr_outputbuffer[i].bufferaddr, 5688 drv_ctx.ptr_outputbuffer[i].pmem_fd ); 5689 5690 buf.index = i; 5691 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5692 buf.memory = V4L2_MEMORY_USERPTR; 5693 plane[0].length = drv_ctx.op_buf.buffer_size; 5694 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 5695 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 5696 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; 5697 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 5698 plane[0].data_offset = 0; 5699 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 5700 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 5701 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 5702 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 5703 #ifdef USE_ION 5704 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 5705 #endif 5706 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 5707 plane[extra_idx].data_offset = 0; 5708 } else if (extra_idx >= VIDEO_MAX_PLANES) { 5709 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 5710 return OMX_ErrorBadParameter; 5711 } 5712 buf.m.planes = plane; 5713 buf.length = drv_ctx.num_planes; 5714 5715 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { 5716 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 5717 /*TODO: How to handle this case */ 5718 return OMX_ErrorInsufficientResources; 5719 } 5720 5721 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { 5722 enum v4l2_buf_type buf_type; 5723 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5724 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { 5725 return OMX_ErrorInsufficientResources; 5726 } else { 5727 streaming[CAPTURE_PORT] = true; 5728 DEBUG_PRINT_LOW("STREAMON Successful"); 5729 } 5730 5731 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 5732 request_perf_level(VIDC_TURBO); 5733 } 5734 5735 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 5736 if (m_enable_android_native_buffers) { 5737 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); 5738 (*bufferHdr)->pBuffer = (OMX_U8 *)handle; 5739 } else { 5740 (*bufferHdr)->pBuffer = buff; 5741 } 5742 (*bufferHdr)->pAppPrivate = privateAppData; 5743 BITMASK_SET(&m_out_bm_count,i); 5744 } 5745 return eRet; 5746 } 5747 5748 /* ====================================================================== 5749 FUNCTION 5750 omx_vdec::use_input_heap_buffers 5751 5752 DESCRIPTION 5753 OMX Use Buffer Heap allocation method implementation. 5754 5755 PARAMETERS 5756 <TBD>. 5757 5758 RETURN VALUE 5759 OMX Error None , if everything successful. 5760 5761 ========================================================================== */ 5762 OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( 5763 OMX_IN OMX_HANDLETYPE hComp, 5764 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5765 OMX_IN OMX_U32 port, 5766 OMX_IN OMX_PTR appData, 5767 OMX_IN OMX_U32 bytes, 5768 OMX_IN OMX_U8* buffer) 5769 { 5770 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); 5771 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5772 if (!m_inp_heap_ptr) 5773 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) 5774 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 5775 drv_ctx.ip_buf.actualcount); 5776 if (!m_phdr_pmem_ptr) 5777 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) 5778 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 5779 drv_ctx.ip_buf.actualcount); 5780 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) { 5781 DEBUG_PRINT_ERROR("Insufficent memory"); 5782 eRet = OMX_ErrorInsufficientResources; 5783 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) { 5784 input_use_buffer = true; 5785 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); 5786 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; 5787 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; 5788 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; 5789 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; 5790 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; 5791 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; 5792 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); 5793 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); 5794 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt], 5795 (unsigned)NULL, (unsigned)NULL)) { 5796 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 5797 return OMX_ErrorInsufficientResources; 5798 } 5799 m_in_alloc_cnt++; 5800 } else { 5801 DEBUG_PRINT_ERROR("All i/p buffers have been set!"); 5802 eRet = OMX_ErrorInsufficientResources; 5803 } 5804 return eRet; 5805 } 5806 5807 /* ====================================================================== 5808 FUNCTION 5809 omx_vdec::UseBuffer 5810 5811 DESCRIPTION 5812 OMX Use Buffer method implementation. 5813 5814 PARAMETERS 5815 <TBD>. 5816 5817 RETURN VALUE 5818 OMX Error None , if everything successful. 5819 5820 ========================================================================== */ 5821 OMX_ERRORTYPE omx_vdec::use_buffer( 5822 OMX_IN OMX_HANDLETYPE hComp, 5823 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5824 OMX_IN OMX_U32 port, 5825 OMX_IN OMX_PTR appData, 5826 OMX_IN OMX_U32 bytes, 5827 OMX_IN OMX_U8* buffer) 5828 { 5829 OMX_ERRORTYPE error = OMX_ErrorNone; 5830 struct vdec_setbuffer_cmd setbuffers; 5831 5832 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) { 5833 DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer); 5834 return OMX_ErrorBadParameter; 5835 } 5836 if (m_state == OMX_StateInvalid) { 5837 DEBUG_PRINT_ERROR("Use Buffer in Invalid State"); 5838 return OMX_ErrorInvalidState; 5839 } 5840 if (port == OMX_CORE_INPUT_PORT_INDEX) 5841 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); 5842 else if (port == OMX_CORE_OUTPUT_PORT_INDEX) 5843 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested 5844 else { 5845 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 5846 error = OMX_ErrorBadPortIndex; 5847 } 5848 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error); 5849 if (error == OMX_ErrorNone) { 5850 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 5851 // Send the callback now 5852 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 5853 post_event(OMX_CommandStateSet,OMX_StateIdle, 5854 OMX_COMPONENT_GENERATE_EVENT); 5855 } 5856 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && 5857 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 5858 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 5859 post_event(OMX_CommandPortEnable, 5860 OMX_CORE_INPUT_PORT_INDEX, 5861 OMX_COMPONENT_GENERATE_EVENT); 5862 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && 5863 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 5864 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 5865 post_event(OMX_CommandPortEnable, 5866 OMX_CORE_OUTPUT_PORT_INDEX, 5867 OMX_COMPONENT_GENERATE_EVENT); 5868 } 5869 } 5870 return error; 5871 } 5872 5873 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, 5874 OMX_BUFFERHEADERTYPE *pmem_bufferHdr) 5875 { 5876 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) { 5877 if (m_inp_heap_ptr[bufferindex].pBuffer) 5878 free(m_inp_heap_ptr[bufferindex].pBuffer); 5879 m_inp_heap_ptr[bufferindex].pBuffer = NULL; 5880 } 5881 if (pmem_bufferHdr) 5882 free_input_buffer(pmem_bufferHdr); 5883 return OMX_ErrorNone; 5884 } 5885 5886 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 5887 { 5888 unsigned int index = 0; 5889 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { 5890 return OMX_ErrorBadParameter; 5891 } 5892 5893 index = bufferHdr - m_inp_mem_ptr; 5894 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 5895 5896 auto_lock l(buf_lock); 5897 bufferHdr->pInputPortPrivate = NULL; 5898 5899 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) { 5900 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 5901 if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) { 5902 struct vdec_setbuffer_cmd setbuffers; 5903 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 5904 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], 5905 sizeof (vdec_bufferpayload)); 5906 if (!secure_mode) { 5907 DEBUG_PRINT_LOW("unmap the input buffer fd=%d", 5908 drv_ctx.ptr_inputbuffer[index].pmem_fd); 5909 DEBUG_PRINT_LOW("unmap the input buffer size=%u address = %p", 5910 (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size, 5911 drv_ctx.ptr_inputbuffer[index].bufferaddr); 5912 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, 5913 drv_ctx.ptr_inputbuffer[index].mmaped_size); 5914 close (drv_ctx.ptr_inputbuffer[index].pmem_fd); 5915 } else if (allocate_native_handle){ 5916 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer; 5917 native_handle_close(nh); 5918 native_handle_delete(nh); 5919 } 5920 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; 5921 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) { 5922 free(m_desc_buffer_ptr[index].buf_addr); 5923 m_desc_buffer_ptr[index].buf_addr = NULL; 5924 m_desc_buffer_ptr[index].desc_data_size = 0; 5925 } 5926 #ifdef USE_ION 5927 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); 5928 #endif 5929 } 5930 } 5931 5932 return OMX_ErrorNone; 5933 } 5934 5935 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 5936 { 5937 unsigned int index = 0; 5938 5939 if (bufferHdr == NULL || m_out_mem_ptr == NULL) { 5940 return OMX_ErrorBadParameter; 5941 } 5942 5943 index = bufferHdr - m_out_mem_ptr; 5944 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); 5945 5946 if (index < drv_ctx.op_buf.actualcount 5947 && drv_ctx.ptr_outputbuffer) { 5948 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index, 5949 drv_ctx.ptr_outputbuffer[index].bufferaddr); 5950 5951 struct vdec_setbuffer_cmd setbuffers; 5952 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 5953 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], 5954 sizeof (vdec_bufferpayload)); 5955 5956 if (!dynamic_buf_mode) { 5957 if (streaming[CAPTURE_PORT] && 5958 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) { 5959 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 5960 DEBUG_PRINT_ERROR("STREAMOFF Failed"); 5961 } else { 5962 DEBUG_PRINT_LOW("STREAMOFF Successful"); 5963 } 5964 } 5965 #ifdef _ANDROID_ 5966 if (m_enable_android_native_buffers) { 5967 if (!secure_mode) { 5968 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { 5969 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, 5970 drv_ctx.ptr_outputbuffer[index].mmaped_size); 5971 } 5972 } 5973 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 5974 } else { 5975 #endif 5976 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) { 5977 if (!secure_mode) { 5978 DEBUG_PRINT_LOW("unmap the output buffer fd = %d", 5979 drv_ctx.ptr_outputbuffer[0].pmem_fd); 5980 DEBUG_PRINT_LOW("unmap the ouput buffer size=%u address = %p", 5981 (unsigned int)drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, 5982 drv_ctx.ptr_outputbuffer[0].bufferaddr); 5983 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, 5984 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); 5985 } 5986 close (drv_ctx.ptr_outputbuffer[0].pmem_fd); 5987 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; 5988 #ifdef USE_ION 5989 free_ion_memory(&drv_ctx.op_buf_ion_info[0]); 5990 #endif 5991 } 5992 #ifdef _ANDROID_ 5993 } 5994 #endif 5995 } //!dynamic_buf_mode 5996 if (release_output_done()) { 5997 free_extradata(); 5998 } 5999 } 6000 6001 return OMX_ErrorNone; 6002 6003 } 6004 6005 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 6006 OMX_BUFFERHEADERTYPE **bufferHdr, 6007 OMX_U32 port, 6008 OMX_PTR appData, 6009 OMX_U32 bytes) 6010 { 6011 OMX_BUFFERHEADERTYPE *input = NULL; 6012 unsigned char *buf_addr = NULL; 6013 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6014 unsigned i = 0; 6015 6016 /* Sanity Check*/ 6017 if (bufferHdr == NULL) { 6018 return OMX_ErrorBadParameter; 6019 } 6020 6021 if (m_inp_heap_ptr == NULL) { 6022 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 6023 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 6024 drv_ctx.ip_buf.actualcount); 6025 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 6026 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 6027 drv_ctx.ip_buf.actualcount); 6028 6029 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) { 6030 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed "); 6031 return OMX_ErrorInsufficientResources; 6032 } 6033 } 6034 6035 /*Find a Free index*/ 6036 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6037 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) { 6038 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6039 break; 6040 } 6041 } 6042 6043 if (i < drv_ctx.ip_buf.actualcount) { 6044 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); 6045 6046 if (buf_addr == NULL) { 6047 return OMX_ErrorInsufficientResources; 6048 } 6049 6050 *bufferHdr = (m_inp_heap_ptr + i); 6051 input = *bufferHdr; 6052 BITMASK_SET(&m_heap_inp_bm_count,i); 6053 6054 input->pBuffer = (OMX_U8 *)buf_addr; 6055 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6056 input->nVersion.nVersion = OMX_SPEC_VERSION; 6057 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6058 input->pAppPrivate = appData; 6059 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6060 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); 6061 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 6062 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); 6063 /*Add the Buffers to freeq*/ 6064 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i], 6065 (unsigned)NULL, (unsigned)NULL)) { 6066 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 6067 return OMX_ErrorInsufficientResources; 6068 } 6069 } else { 6070 return OMX_ErrorBadParameter; 6071 } 6072 6073 return eRet; 6074 6075 } 6076 6077 6078 /* ====================================================================== 6079 FUNCTION 6080 omx_vdec::AllocateInputBuffer 6081 6082 DESCRIPTION 6083 Helper function for allocate buffer in the input pin 6084 6085 PARAMETERS 6086 None. 6087 6088 RETURN VALUE 6089 true/false 6090 6091 ========================================================================== */ 6092 OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 6093 OMX_IN OMX_HANDLETYPE hComp, 6094 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6095 OMX_IN OMX_U32 port, 6096 OMX_IN OMX_PTR appData, 6097 OMX_IN OMX_U32 bytes) 6098 { 6099 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6100 struct vdec_setbuffer_cmd setbuffers; 6101 OMX_BUFFERHEADERTYPE *input = NULL; 6102 unsigned i = 0; 6103 unsigned char *buf_addr = NULL; 6104 int pmem_fd = -1; 6105 6106 (void) hComp; 6107 (void) port; 6108 6109 6110 if (bytes != drv_ctx.ip_buf.buffer_size) { 6111 DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u", 6112 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size); 6113 return OMX_ErrorBadParameter; 6114 } 6115 6116 if (!m_inp_mem_ptr) { 6117 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)", 6118 drv_ctx.ip_buf.actualcount, 6119 (unsigned int)drv_ctx.ip_buf.buffer_size); 6120 6121 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 6122 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); 6123 6124 if (m_inp_mem_ptr == NULL) { 6125 return OMX_ErrorInsufficientResources; 6126 } 6127 6128 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 6129 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); 6130 6131 if (drv_ctx.ptr_inputbuffer == NULL) { 6132 return OMX_ErrorInsufficientResources; 6133 } 6134 #ifdef USE_ION 6135 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ 6136 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); 6137 6138 if (drv_ctx.ip_buf_ion_info == NULL) { 6139 return OMX_ErrorInsufficientResources; 6140 } 6141 #endif 6142 6143 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) { 6144 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; 6145 #ifdef USE_ION 6146 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; 6147 #endif 6148 } 6149 } 6150 6151 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6152 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 6153 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6154 break; 6155 } 6156 } 6157 6158 if (i < drv_ctx.ip_buf.actualcount) { 6159 struct v4l2_buffer buf; 6160 struct v4l2_plane plane; 6161 int rc; 6162 DEBUG_PRINT_LOW("Allocate input Buffer"); 6163 #ifdef USE_ION 6164 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 6165 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, 6166 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, 6167 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? 6168 SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED); 6169 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { 6170 return OMX_ErrorInsufficientResources; 6171 } 6172 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; 6173 #else 6174 pmem_fd = open (MEM_DEVICE,O_RDWR); 6175 6176 if (pmem_fd < 0) { 6177 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6178 return OMX_ErrorInsufficientResources; 6179 } 6180 6181 if (pmem_fd == 0) { 6182 pmem_fd = open (MEM_DEVICE,O_RDWR); 6183 6184 if (pmem_fd < 0) { 6185 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6186 return OMX_ErrorInsufficientResources; 6187 } 6188 } 6189 6190 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, 6191 drv_ctx.ip_buf.alignment)) { 6192 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6193 close(pmem_fd); 6194 return OMX_ErrorInsufficientResources; 6195 } 6196 #endif 6197 if (!secure_mode) { 6198 buf_addr = (unsigned char *)mmap(NULL, 6199 drv_ctx.ip_buf.buffer_size, 6200 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); 6201 6202 if (buf_addr == MAP_FAILED) { 6203 close(pmem_fd); 6204 #ifdef USE_ION 6205 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); 6206 #endif 6207 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer"); 6208 return OMX_ErrorInsufficientResources; 6209 } 6210 } 6211 *bufferHdr = (m_inp_mem_ptr + i); 6212 if (secure_mode) 6213 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; 6214 else 6215 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; 6216 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; 6217 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; 6218 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; 6219 drv_ctx.ptr_inputbuffer [i].offset = 0; 6220 6221 6222 buf.index = i; 6223 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 6224 buf.memory = V4L2_MEMORY_USERPTR; 6225 plane.bytesused = 0; 6226 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; 6227 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; 6228 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; 6229 plane.reserved[1] = 0; 6230 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; 6231 buf.m.planes = &plane; 6232 buf.length = 1; 6233 6234 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i, 6235 drv_ctx.ptr_inputbuffer[i].bufferaddr); 6236 6237 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 6238 6239 if (rc) { 6240 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 6241 /*TODO: How to handle this case */ 6242 return OMX_ErrorInsufficientResources; 6243 } 6244 6245 input = *bufferHdr; 6246 BITMASK_SET(&m_inp_bm_count,i); 6247 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); 6248 if (allocate_native_handle) { 6249 native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/); 6250 nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd; 6251 input->pBuffer = (OMX_U8 *)nh; 6252 } else if (secure_mode || m_input_pass_buffer_fd) { 6253 /*Legacy method, pass ion fd stashed directly in pBuffer*/ 6254 input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd; 6255 } else { 6256 input->pBuffer = (OMX_U8 *)buf_addr; 6257 } 6258 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6259 input->nVersion.nVersion = OMX_SPEC_VERSION; 6260 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6261 input->pAppPrivate = appData; 6262 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6263 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; 6264 6265 if (drv_ctx.disable_dmx) { 6266 eRet = allocate_desc_buffer(i); 6267 } 6268 } else { 6269 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found"); 6270 eRet = OMX_ErrorInsufficientResources; 6271 } 6272 return eRet; 6273 } 6274 6275 6276 /* ====================================================================== 6277 FUNCTION 6278 omx_vdec::AllocateOutputBuffer 6279 6280 DESCRIPTION 6281 Helper fn for AllocateBuffer in the output pin 6282 6283 PARAMETERS 6284 <TBD>. 6285 6286 RETURN VALUE 6287 OMX Error None if everything went well. 6288 6289 ========================================================================== */ 6290 OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 6291 OMX_IN OMX_HANDLETYPE hComp, 6292 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6293 OMX_IN OMX_U32 port, 6294 OMX_IN OMX_PTR appData, 6295 OMX_IN OMX_U32 bytes) 6296 { 6297 (void)hComp; 6298 (void)port; 6299 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6300 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 6301 unsigned i= 0; // Temporary counter 6302 struct vdec_setbuffer_cmd setbuffers; 6303 int extra_idx = 0; 6304 #ifdef USE_ION 6305 int ion_device_fd =-1; 6306 struct ion_allocation_data ion_alloc_data; 6307 struct ion_fd_data fd_ion_data; 6308 #endif 6309 if (!m_out_mem_ptr) { 6310 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)", 6311 drv_ctx.op_buf.actualcount, 6312 (unsigned int)drv_ctx.op_buf.buffer_size); 6313 int nBufHdrSize = 0; 6314 int nPlatformEntrySize = 0; 6315 int nPlatformListSize = 0; 6316 int nPMEMInfoSize = 0; 6317 int pmem_fd = -1; 6318 unsigned char *pmem_baseaddress = NULL; 6319 6320 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 6321 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 6322 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 6323 6324 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", 6325 drv_ctx.op_buf.actualcount); 6326 nBufHdrSize = drv_ctx.op_buf.actualcount * 6327 sizeof(OMX_BUFFERHEADERTYPE); 6328 6329 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 6330 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 6331 nPlatformListSize = drv_ctx.op_buf.actualcount * 6332 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 6333 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 6334 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 6335 6336 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 6337 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 6338 nPMEMInfoSize, 6339 nPlatformListSize); 6340 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, 6341 drv_ctx.op_buf.actualcount); 6342 #ifdef USE_ION 6343 // Allocate output buffers as cached to improve performance of software-reading 6344 // of the YUVs. Output buffers are cache-invalidated in driver. 6345 // If color-conversion is involved, Only the C2D output buffers are cached, no 6346 // need to cache the decoder's output buffers 6347 int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED; 6348 ion_device_fd = alloc_map_ion_memory( 6349 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, 6350 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment, 6351 &ion_alloc_data, &fd_ion_data, 6352 (secure_mode && !secure_scaling_to_non_secure_opb) ? 6353 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag); 6354 if (ion_device_fd < 0) { 6355 return OMX_ErrorInsufficientResources; 6356 } 6357 pmem_fd = fd_ion_data.fd; 6358 #else 6359 pmem_fd = open (MEM_DEVICE,O_RDWR); 6360 6361 if (pmem_fd < 0) { 6362 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d", 6363 drv_ctx.op_buf.buffer_size); 6364 return OMX_ErrorInsufficientResources; 6365 } 6366 6367 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * 6368 drv_ctx.op_buf.actualcount, 6369 drv_ctx.op_buf.alignment)) { 6370 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6371 close(pmem_fd); 6372 return OMX_ErrorInsufficientResources; 6373 } 6374 #endif 6375 if (!secure_mode) { 6376 pmem_baseaddress = (unsigned char *)mmap(NULL, 6377 (drv_ctx.op_buf.buffer_size * 6378 drv_ctx.op_buf.actualcount), 6379 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); 6380 if (pmem_baseaddress == MAP_FAILED) { 6381 DEBUG_PRINT_ERROR("MMAP failed for Size %u", 6382 (unsigned int)drv_ctx.op_buf.buffer_size); 6383 close(pmem_fd); 6384 #ifdef USE_ION 6385 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 6386 #endif 6387 return OMX_ErrorInsufficientResources; 6388 } 6389 } 6390 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 6391 // Alloc mem for platform specific info 6392 char *pPtr=NULL; 6393 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 6394 nPMEMInfoSize,1); 6395 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ 6396 calloc (sizeof(struct vdec_bufferpayload), 6397 drv_ctx.op_buf.actualcount); 6398 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 6399 calloc (sizeof (struct vdec_output_frameinfo), 6400 drv_ctx.op_buf.actualcount); 6401 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 6402 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer "); 6403 return OMX_ErrorInsufficientResources; 6404 } 6405 6406 #ifdef USE_ION 6407 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ 6408 calloc (sizeof(struct vdec_ion), 6409 drv_ctx.op_buf.actualcount); 6410 if (!drv_ctx.op_buf_ion_info) { 6411 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 6412 return OMX_ErrorInsufficientResources; 6413 } 6414 #endif 6415 6416 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 6417 && drv_ctx.ptr_respbuffer) { 6418 drv_ctx.ptr_outputbuffer[0].mmaped_size = 6419 (drv_ctx.op_buf.buffer_size * 6420 drv_ctx.op_buf.actualcount); 6421 bufHdr = m_out_mem_ptr; 6422 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 6423 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 6424 (((char *) m_platform_list) + nPlatformListSize); 6425 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 6426 (((char *) m_platform_entry) + nPlatformEntrySize); 6427 pPlatformList = m_platform_list; 6428 pPlatformEntry = m_platform_entry; 6429 pPMEMInfo = m_pmem_info; 6430 6431 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 6432 6433 // Settting the entire storage nicely 6434 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); 6435 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 6436 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 6437 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6438 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 6439 // Set the values when we determine the right HxW param 6440 bufHdr->nAllocLen = bytes; 6441 bufHdr->nFilledLen = 0; 6442 bufHdr->pAppPrivate = appData; 6443 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 6444 // Platform specific PMEM Information 6445 // Initialize the Platform Entry 6446 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); 6447 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 6448 pPlatformEntry->entry = pPMEMInfo; 6449 // Initialize the Platform List 6450 pPlatformList->nEntries = 1; 6451 pPlatformList->entryList = pPlatformEntry; 6452 // Keep pBuffer NULL till vdec is opened 6453 bufHdr->pBuffer = NULL; 6454 bufHdr->nOffset = 0; 6455 6456 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; 6457 pPMEMInfo->pmem_fd = -1; 6458 bufHdr->pPlatformPrivate = pPlatformList; 6459 6460 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; 6461 m_pmem_info[i].pmem_fd = pmem_fd; 6462 #ifdef USE_ION 6463 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; 6464 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; 6465 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; 6466 #endif 6467 6468 /*Create a mapping between buffers*/ 6469 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 6470 drv_ctx.ptr_respbuffer[i].client_data = (void *)\ 6471 &drv_ctx.ptr_outputbuffer[i]; 6472 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; 6473 drv_ctx.ptr_outputbuffer[i].bufferaddr = 6474 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); 6475 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 6476 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 6477 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 6478 6479 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p", 6480 pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset, 6481 drv_ctx.ptr_outputbuffer[i].bufferaddr); 6482 // Move the buffer and buffer header pointers 6483 bufHdr++; 6484 pPMEMInfo++; 6485 pPlatformEntry++; 6486 pPlatformList++; 6487 } 6488 } else { 6489 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 6490 m_out_mem_ptr, pPtr); 6491 if (m_out_mem_ptr) { 6492 free(m_out_mem_ptr); 6493 m_out_mem_ptr = NULL; 6494 } 6495 if (pPtr) { 6496 free(pPtr); 6497 pPtr = NULL; 6498 } 6499 if (drv_ctx.ptr_outputbuffer) { 6500 free(drv_ctx.ptr_outputbuffer); 6501 drv_ctx.ptr_outputbuffer = NULL; 6502 } 6503 if (drv_ctx.ptr_respbuffer) { 6504 free(drv_ctx.ptr_respbuffer); 6505 drv_ctx.ptr_respbuffer = NULL; 6506 } 6507 #ifdef USE_ION 6508 if (drv_ctx.op_buf_ion_info) { 6509 DEBUG_PRINT_LOW("Free o/p ion context"); 6510 free(drv_ctx.op_buf_ion_info); 6511 drv_ctx.op_buf_ion_info = NULL; 6512 } 6513 #endif 6514 eRet = OMX_ErrorInsufficientResources; 6515 } 6516 if (eRet == OMX_ErrorNone) 6517 eRet = allocate_extradata(); 6518 } 6519 6520 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 6521 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 6522 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i); 6523 break; 6524 } 6525 } 6526 6527 if (eRet == OMX_ErrorNone) { 6528 if (i < drv_ctx.op_buf.actualcount) { 6529 struct v4l2_buffer buf; 6530 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 6531 int rc; 6532 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 6533 6534 drv_ctx.ptr_outputbuffer[i].buffer_len = 6535 drv_ctx.op_buf.buffer_size; 6536 6537 *bufferHdr = (m_out_mem_ptr + i ); 6538 if (secure_mode) { 6539 #ifdef USE_ION 6540 drv_ctx.ptr_outputbuffer[i].bufferaddr = 6541 (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 6542 #else 6543 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 6544 #endif 6545 } 6546 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; 6547 6548 buf.index = i; 6549 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6550 buf.memory = V4L2_MEMORY_USERPTR; 6551 plane[0].length = drv_ctx.op_buf.buffer_size; 6552 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 6553 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 6554 #ifdef USE_ION 6555 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 6556 #endif 6557 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 6558 plane[0].data_offset = 0; 6559 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 6560 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 6561 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 6562 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 6563 #ifdef USE_ION 6564 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 6565 #endif 6566 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 6567 plane[extra_idx].data_offset = 0; 6568 } else if (extra_idx >= VIDEO_MAX_PLANES) { 6569 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx); 6570 return OMX_ErrorBadParameter; 6571 } 6572 buf.m.planes = plane; 6573 buf.length = drv_ctx.num_planes; 6574 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr); 6575 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 6576 if (rc) { 6577 /*TODO: How to handle this case */ 6578 return OMX_ErrorInsufficientResources; 6579 } 6580 6581 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { 6582 enum v4l2_buf_type buf_type; 6583 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6584 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 6585 if (rc) { 6586 return OMX_ErrorInsufficientResources; 6587 } else { 6588 streaming[CAPTURE_PORT] = true; 6589 DEBUG_PRINT_LOW("STREAMON Successful"); 6590 } 6591 6592 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 6593 request_perf_level(VIDC_TURBO); 6594 } 6595 6596 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; 6597 (*bufferHdr)->pAppPrivate = appData; 6598 BITMASK_SET(&m_out_bm_count,i); 6599 } else { 6600 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient"); 6601 eRet = OMX_ErrorInsufficientResources; 6602 } 6603 } 6604 6605 return eRet; 6606 } 6607 6608 6609 // AllocateBuffer -- API Call 6610 /* ====================================================================== 6611 FUNCTION 6612 omx_vdec::AllocateBuffer 6613 6614 DESCRIPTION 6615 Returns zero if all the buffers released.. 6616 6617 PARAMETERS 6618 None. 6619 6620 RETURN VALUE 6621 true/false 6622 6623 ========================================================================== */ 6624 OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 6625 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6626 OMX_IN OMX_U32 port, 6627 OMX_IN OMX_PTR appData, 6628 OMX_IN OMX_U32 bytes) 6629 { 6630 unsigned i = 0; 6631 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 6632 6633 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); 6634 if (m_state == OMX_StateInvalid) { 6635 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State"); 6636 return OMX_ErrorInvalidState; 6637 } 6638 6639 if (port == OMX_CORE_INPUT_PORT_INDEX) { 6640 if (arbitrary_bytes) { 6641 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 6642 } else { 6643 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 6644 } 6645 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 6646 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, 6647 appData,bytes); 6648 } else { 6649 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 6650 eRet = OMX_ErrorBadPortIndex; 6651 } 6652 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 6653 if (eRet == OMX_ErrorNone) { 6654 if (allocate_done()) { 6655 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 6656 // Send the callback now 6657 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 6658 post_event(OMX_CommandStateSet,OMX_StateIdle, 6659 OMX_COMPONENT_GENERATE_EVENT); 6660 } 6661 } 6662 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) { 6663 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 6664 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 6665 post_event(OMX_CommandPortEnable, 6666 OMX_CORE_INPUT_PORT_INDEX, 6667 OMX_COMPONENT_GENERATE_EVENT); 6668 } 6669 } 6670 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) { 6671 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 6672 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 6673 post_event(OMX_CommandPortEnable, 6674 OMX_CORE_OUTPUT_PORT_INDEX, 6675 OMX_COMPONENT_GENERATE_EVENT); 6676 } 6677 } 6678 } 6679 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); 6680 return eRet; 6681 } 6682 6683 // Free Buffer - API call 6684 /* ====================================================================== 6685 FUNCTION 6686 omx_vdec::FreeBuffer 6687 6688 DESCRIPTION 6689 6690 PARAMETERS 6691 None. 6692 6693 RETURN VALUE 6694 true/false 6695 6696 ========================================================================== */ 6697 OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 6698 OMX_IN OMX_U32 port, 6699 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 6700 { 6701 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6702 unsigned int nPortIndex; 6703 (void) hComp; 6704 DEBUG_PRINT_LOW("In for decoder free_buffer"); 6705 6706 if (m_state == OMX_StateIdle && 6707 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 6708 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); 6709 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 6710 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) { 6711 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port); 6712 } else if ((port == OMX_CORE_INPUT_PORT_INDEX && 6713 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || 6714 (port == OMX_CORE_OUTPUT_PORT_INDEX && 6715 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) { 6716 DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port); 6717 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) { 6718 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled"); 6719 post_event(OMX_EventError, 6720 OMX_ErrorPortUnpopulated, 6721 OMX_COMPONENT_GENERATE_EVENT); 6722 6723 return OMX_ErrorIncorrectStateOperation; 6724 } else if (m_state != OMX_StateInvalid) { 6725 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers"); 6726 post_event(OMX_EventError, 6727 OMX_ErrorPortUnpopulated, 6728 OMX_COMPONENT_GENERATE_EVENT); 6729 } 6730 6731 if (port == OMX_CORE_INPUT_PORT_INDEX) { 6732 /*Check if arbitrary bytes*/ 6733 if (!arbitrary_bytes && !input_use_buffer) 6734 nPortIndex = buffer - m_inp_mem_ptr; 6735 else 6736 nPortIndex = buffer - m_inp_heap_ptr; 6737 6738 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); 6739 if (nPortIndex < drv_ctx.ip_buf.actualcount && 6740 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) { 6741 // Clear the bit associated with it. 6742 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 6743 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 6744 if (input_use_buffer == true) { 6745 6746 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); 6747 if (m_phdr_pmem_ptr) 6748 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 6749 } else { 6750 if (arbitrary_bytes) { 6751 if (m_phdr_pmem_ptr) 6752 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); 6753 else 6754 free_input_buffer(nPortIndex,NULL); 6755 } else 6756 free_input_buffer(buffer); 6757 } 6758 m_inp_bPopulated = OMX_FALSE; 6759 if(release_input_done()) 6760 release_buffers(this, VDEC_BUFFER_TYPE_INPUT); 6761 /*Free the Buffer Header*/ 6762 if (release_input_done()) { 6763 DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); 6764 free_input_buffer_header(); 6765 } 6766 } else { 6767 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid"); 6768 eRet = OMX_ErrorBadPortIndex; 6769 } 6770 6771 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 6772 && release_input_done()) { 6773 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 6774 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 6775 post_event(OMX_CommandPortDisable, 6776 OMX_CORE_INPUT_PORT_INDEX, 6777 OMX_COMPONENT_GENERATE_EVENT); 6778 } 6779 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 6780 // check if the buffer is valid 6781 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 6782 if (nPortIndex < drv_ctx.op_buf.actualcount && 6783 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) { 6784 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); 6785 // Clear the bit associated with it. 6786 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 6787 m_out_bPopulated = OMX_FALSE; 6788 client_buffers.free_output_buffer (buffer); 6789 6790 if(release_output_done()) { 6791 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT); 6792 } 6793 if (release_output_done()) { 6794 free_output_buffer_header(); 6795 } 6796 } else { 6797 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid"); 6798 eRet = OMX_ErrorBadPortIndex; 6799 } 6800 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 6801 && release_output_done()) { 6802 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); 6803 6804 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 6805 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 6806 #ifdef _ANDROID_ICS_ 6807 if (m_enable_android_native_buffers) { 6808 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); 6809 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 6810 } 6811 #endif 6812 6813 post_event(OMX_CommandPortDisable, 6814 OMX_CORE_OUTPUT_PORT_INDEX, 6815 OMX_COMPONENT_GENERATE_EVENT); 6816 } 6817 } else { 6818 eRet = OMX_ErrorBadPortIndex; 6819 } 6820 if ((eRet == OMX_ErrorNone) && 6821 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 6822 if (release_done()) { 6823 // Send the callback now 6824 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 6825 post_event(OMX_CommandStateSet, OMX_StateLoaded, 6826 OMX_COMPONENT_GENERATE_EVENT); 6827 } 6828 } 6829 return eRet; 6830 } 6831 6832 6833 /* ====================================================================== 6834 FUNCTION 6835 omx_vdec::EmptyThisBuffer 6836 6837 DESCRIPTION 6838 This routine is used to push the encoded video frames to 6839 the video decoder. 6840 6841 PARAMETERS 6842 None. 6843 6844 RETURN VALUE 6845 OMX Error None if everything went successful. 6846 6847 ========================================================================== */ 6848 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 6849 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 6850 { 6851 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 6852 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; 6853 6854 if (m_state != OMX_StateExecuting && 6855 m_state != OMX_StatePause && 6856 m_state != OMX_StateIdle) { 6857 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State"); 6858 return OMX_ErrorInvalidState; 6859 } 6860 6861 if (buffer == NULL) { 6862 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL"); 6863 return OMX_ErrorBadParameter; 6864 } 6865 6866 if (!m_inp_bEnabled) { 6867 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled."); 6868 return OMX_ErrorIncorrectStateOperation; 6869 } 6870 6871 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 6872 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex); 6873 return OMX_ErrorBadPortIndex; 6874 } 6875 6876 if (perf_flag) { 6877 if (!latency) { 6878 dec_time.stop(); 6879 latency = dec_time.processing_time_us(); 6880 dec_time.start(); 6881 } 6882 } 6883 6884 if (arbitrary_bytes) { 6885 nBufferIndex = buffer - m_inp_heap_ptr; 6886 } else { 6887 if (input_use_buffer == true) { 6888 nBufferIndex = buffer - m_inp_heap_ptr; 6889 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; 6890 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; 6891 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; 6892 buffer = &m_inp_mem_ptr[nBufferIndex]; 6893 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u", 6894 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen); 6895 } else { 6896 nBufferIndex = buffer - m_inp_mem_ptr; 6897 } 6898 } 6899 6900 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) { 6901 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid"); 6902 return OMX_ErrorBadParameter; 6903 } 6904 6905 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 6906 codec_config_flag = true; 6907 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); 6908 } 6909 6910 /* The client should not set this when codec is in arbitrary bytes mode */ 6911 if (m_input_pass_buffer_fd) { 6912 buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr; 6913 } 6914 6915 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)", 6916 buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen); 6917 if (arbitrary_bytes) { 6918 post_event ((unsigned long)hComp,(unsigned long)buffer, 6919 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 6920 } else { 6921 post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB); 6922 } 6923 time_stamp_dts.insert_timestamp(buffer); 6924 return OMX_ErrorNone; 6925 } 6926 6927 /* ====================================================================== 6928 FUNCTION 6929 omx_vdec::empty_this_buffer_proxy 6930 6931 DESCRIPTION 6932 This routine is used to push the encoded video frames to 6933 the video decoder. 6934 6935 PARAMETERS 6936 None. 6937 6938 RETURN VALUE 6939 OMX Error None if everything went successful. 6940 6941 ========================================================================== */ 6942 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 6943 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 6944 { 6945 (void) hComp; 6946 int push_cnt = 0,i=0; 6947 unsigned nPortIndex = 0; 6948 OMX_ERRORTYPE ret = OMX_ErrorNone; 6949 struct vdec_input_frameinfo frameinfo; 6950 struct vdec_bufferpayload *temp_buffer; 6951 struct vdec_seqheader seq_header; 6952 bool port_setting_changed = true; 6953 6954 /*Should we generate a Aync error event*/ 6955 if (buffer == NULL || buffer->pInputPortPrivate == NULL) { 6956 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid"); 6957 return OMX_ErrorBadParameter; 6958 } 6959 6960 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 6961 6962 if (nPortIndex > drv_ctx.ip_buf.actualcount) { 6963 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 6964 nPortIndex); 6965 return OMX_ErrorBadParameter; 6966 } 6967 6968 pending_input_buffers++; 6969 6970 /* return zero length and not an EOS buffer */ 6971 if (!arbitrary_bytes && (buffer->nFilledLen == 0) && 6972 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) { 6973 DEBUG_PRINT_HIGH("return zero legth buffer"); 6974 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 6975 OMX_COMPONENT_GENERATE_EBD); 6976 return OMX_ErrorNone; 6977 } 6978 6979 if (input_flush_progress == true) { 6980 DEBUG_PRINT_LOW("Flush in progress return buffer "); 6981 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 6982 OMX_COMPONENT_GENERATE_EBD); 6983 return OMX_ErrorNone; 6984 } 6985 6986 auto_lock l(buf_lock); 6987 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 6988 6989 if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) { 6990 return OMX_ErrorBadParameter; 6991 } 6992 /* If its first frame, H264 codec and reject is true, then parse the nal 6993 and get the profile. Based on this, reject the clip playback */ 6994 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 && 6995 m_reject_avc_1080p_mp) { 6996 first_frame = 1; 6997 DEBUG_PRINT_ERROR("Parse nal to get the profile"); 6998 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen, 6999 NALU_TYPE_SPS); 7000 m_profile = h264_parser->get_profile(); 7001 ret = is_video_session_supported(); 7002 if (ret) { 7003 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD); 7004 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT); 7005 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */ 7006 m_state = OMX_StateInvalid; 7007 return OMX_ErrorNone; 7008 } 7009 } 7010 7011 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 7012 /*for use buffer we need to memcpy the data*/ 7013 temp_buffer->buffer_len = buffer->nFilledLen; 7014 7015 if (input_use_buffer && temp_buffer->bufferaddr) { 7016 if (buffer->nFilledLen <= temp_buffer->buffer_len) { 7017 if (arbitrary_bytes) { 7018 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 7019 } else { 7020 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), 7021 buffer->nFilledLen); 7022 } 7023 } else { 7024 return OMX_ErrorBadParameter; 7025 } 7026 7027 } 7028 7029 frameinfo.bufferaddr = temp_buffer->bufferaddr; 7030 frameinfo.client_data = (void *) buffer; 7031 frameinfo.datalen = temp_buffer->buffer_len; 7032 frameinfo.flags = 0; 7033 frameinfo.offset = buffer->nOffset; 7034 frameinfo.pmem_fd = temp_buffer->pmem_fd; 7035 frameinfo.pmem_offset = temp_buffer->offset; 7036 frameinfo.timestamp = buffer->nTimeStamp; 7037 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) { 7038 DEBUG_PRINT_LOW("ETB: dmx enabled"); 7039 if (m_demux_entries == 0) { 7040 extract_demux_addr_offsets(buffer); 7041 } 7042 7043 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries); 7044 handle_demux_data(buffer); 7045 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; 7046 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; 7047 } else { 7048 frameinfo.desc_addr = NULL; 7049 frameinfo.desc_size = 0; 7050 } 7051 if (!arbitrary_bytes) { 7052 frameinfo.flags |= buffer->nFlags; 7053 } 7054 7055 #ifdef _ANDROID_ 7056 if (m_debug_timestamp) { 7057 if (arbitrary_bytes) { 7058 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7059 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7060 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7061 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7062 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7063 } 7064 } 7065 #endif 7066 7067 log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len); 7068 7069 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 7070 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7071 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7072 } 7073 7074 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7075 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); 7076 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 7077 h264_scratch.nFilledLen = 0; 7078 nal_count = 0; 7079 look_ahead_nal = false; 7080 frame_count = 0; 7081 if (m_frame_parser.mutils) 7082 m_frame_parser.mutils->initialize_frame_checking_environment(); 7083 m_frame_parser.flush(); 7084 h264_last_au_ts = LLONG_MAX; 7085 h264_last_au_flags = 0; 7086 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 7087 m_demux_entries = 0; 7088 } 7089 struct v4l2_buffer buf; 7090 struct v4l2_plane plane; 7091 memset( (void *)&buf, 0, sizeof(buf)); 7092 memset( (void *)&plane, 0, sizeof(plane)); 7093 int rc; 7094 unsigned long print_count; 7095 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7096 buf.flags = V4L2_QCOM_BUF_FLAG_EOS; 7097 DEBUG_PRINT_HIGH("INPUT EOS reached") ; 7098 } 7099 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7100 buf.index = nPortIndex; 7101 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7102 buf.memory = V4L2_MEMORY_USERPTR; 7103 plane.bytesused = temp_buffer->buffer_len; 7104 plane.length = drv_ctx.ip_buf.buffer_size; 7105 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - 7106 (unsigned long)temp_buffer->offset; 7107 plane.reserved[0] = temp_buffer->pmem_fd; 7108 plane.reserved[1] = temp_buffer->offset; 7109 plane.data_offset = 0; 7110 buf.m.planes = &plane; 7111 buf.length = 1; 7112 if (frameinfo.timestamp >= LLONG_MAX) { 7113 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; 7114 } 7115 //assumption is that timestamp is in milliseconds 7116 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; 7117 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); 7118 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; 7119 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0; 7120 7121 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 7122 DEBUG_PRINT_LOW("Increment codec_config buffer counter"); 7123 android_atomic_inc(&m_queued_codec_config_count); 7124 } 7125 7126 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 7127 if (rc) { 7128 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver"); 7129 return OMX_ErrorHardware; 7130 } 7131 7132 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7133 codec_config_flag = false; 7134 } 7135 if (!streaming[OUTPUT_PORT]) { 7136 enum v4l2_buf_type buf_type; 7137 int ret,r; 7138 7139 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7140 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 7141 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 7142 if (!ret) { 7143 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful"); 7144 streaming[OUTPUT_PORT] = true; 7145 } else if (errno == EBUSY) { 7146 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD"); 7147 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7148 OMX_COMPONENT_GENERATE_EBD); 7149 return OMX_ErrorInsufficientResources; 7150 } else { 7151 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT"); 7152 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); 7153 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7154 OMX_COMPONENT_GENERATE_EBD); 7155 return OMX_ErrorBadParameter; 7156 } 7157 } 7158 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)", 7159 frameinfo.bufferaddr, (long long)frameinfo.timestamp, 7160 (unsigned int)frameinfo.datalen); 7161 7162 return ret; 7163 } 7164 7165 /* ====================================================================== 7166 FUNCTION 7167 omx_vdec::FillThisBuffer 7168 7169 DESCRIPTION 7170 IL client uses this method to release the frame buffer 7171 after displaying them. 7172 7173 PARAMETERS 7174 None. 7175 7176 RETURN VALUE 7177 true/false 7178 7179 ========================================================================== */ 7180 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 7181 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7182 { 7183 if (m_state != OMX_StateExecuting && 7184 m_state != OMX_StatePause && 7185 m_state != OMX_StateIdle) { 7186 DEBUG_PRINT_ERROR("FTB in Invalid State"); 7187 return OMX_ErrorInvalidState; 7188 } 7189 7190 if (!m_out_bEnabled) { 7191 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); 7192 return OMX_ErrorIncorrectStateOperation; 7193 } 7194 7195 unsigned nPortIndex = 0; 7196 if (dynamic_buf_mode) { 7197 private_handle_t *handle = NULL; 7198 struct VideoDecoderOutputMetaData *meta; 7199 unsigned int nPortIndex = 0; 7200 7201 if (!buffer || !buffer->pBuffer) { 7202 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer); 7203 return OMX_ErrorBadParameter; 7204 } 7205 7206 //get the buffer type and fd info 7207 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer; 7208 handle = (private_handle_t *)meta->pHandle; 7209 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle); 7210 7211 if (!handle) { 7212 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle); 7213 return OMX_ErrorBadParameter; 7214 } 7215 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF 7216 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 7217 if (nPortIndex < drv_ctx.op_buf.actualcount && 7218 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 7219 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd; 7220 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer; 7221 7222 //Store private handle from GraphicBuffer 7223 native_buffer[nPortIndex].privatehandle = handle; 7224 native_buffer[nPortIndex].nativehandle = handle; 7225 } else { 7226 DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex); 7227 return OMX_ErrorBadParameter; 7228 } 7229 7230 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite 7231 //this with a more sane size so that we don't compensate in rest of code 7232 //We'll restore this size later on, so that it's transparent to client 7233 buffer->nFilledLen = 0; 7234 buffer->nAllocLen = handle->size; 7235 drv_ctx.op_buf.buffer_size = handle->size; 7236 } 7237 7238 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 7239 if (buffer == NULL || 7240 (nPortIndex >= drv_ctx.op_buf.actualcount)) { 7241 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 7242 nPortIndex, drv_ctx.op_buf.actualcount); 7243 return OMX_ErrorBadParameter; 7244 } 7245 7246 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 7247 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex); 7248 return OMX_ErrorBadPortIndex; 7249 } 7250 7251 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 7252 post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg); 7253 return OMX_ErrorNone; 7254 } 7255 /* ====================================================================== 7256 FUNCTION 7257 omx_vdec::fill_this_buffer_proxy 7258 7259 DESCRIPTION 7260 IL client uses this method to release the frame buffer 7261 after displaying them. 7262 7263 PARAMETERS 7264 None. 7265 7266 RETURN VALUE 7267 true/false 7268 7269 ========================================================================== */ 7270 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 7271 OMX_IN OMX_HANDLETYPE hComp, 7272 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 7273 { 7274 OMX_ERRORTYPE nRet = OMX_ErrorNone; 7275 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 7276 unsigned nPortIndex = 0; 7277 struct vdec_fillbuffer_cmd fillbuffer; 7278 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 7279 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 7280 7281 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 7282 7283 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) { 7284 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 7285 nPortIndex, drv_ctx.op_buf.actualcount); 7286 return OMX_ErrorBadParameter; 7287 } 7288 7289 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 7290 bufferAdd, bufferAdd->pBuffer); 7291 /*Return back the output buffer to client*/ 7292 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) { 7293 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); 7294 buffer->nFilledLen = 0; 7295 m_cb.FillBufferDone (hComp,m_app_data,buffer); 7296 return OMX_ErrorNone; 7297 } 7298 7299 if (dynamic_buf_mode) { 7300 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0; 7301 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen; 7302 buf_ref_add(nPortIndex); 7303 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen; 7304 } 7305 7306 pending_output_buffers++; 7307 buffer = client_buffers.get_dr_buf_hdr(bufferAdd); 7308 if (!buffer) { 7309 DEBUG_PRINT_ERROR("err: client_buffer ptr invalid"); 7310 return OMX_ErrorBadParameter; 7311 } 7312 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 7313 if (ptr_respbuffer) { 7314 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 7315 } 7316 7317 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) { 7318 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); 7319 buffer->nFilledLen = 0; 7320 m_cb.FillBufferDone (hComp,m_app_data,buffer); 7321 pending_output_buffers--; 7322 return OMX_ErrorBadParameter; 7323 } 7324 7325 int rc = 0; 7326 struct v4l2_buffer buf; 7327 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 7328 memset( (void *)&buf, 0, sizeof(buf)); 7329 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); 7330 unsigned int extra_idx = 0; 7331 7332 buf.index = nPortIndex; 7333 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7334 buf.memory = V4L2_MEMORY_USERPTR; 7335 plane[0].bytesused = buffer->nFilledLen; 7336 plane[0].length = buffer->nAllocLen; 7337 plane[0].m.userptr = 7338 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - 7339 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; 7340 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 7341 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 7342 plane[0].data_offset = 0; 7343 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 7344 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 7345 plane[extra_idx].bytesused = 0; 7346 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 7347 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); 7348 #ifdef USE_ION 7349 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 7350 #endif 7351 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; 7352 plane[extra_idx].data_offset = 0; 7353 } else if (extra_idx >= VIDEO_MAX_PLANES) { 7354 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx); 7355 return OMX_ErrorBadParameter; 7356 } 7357 buf.m.planes = plane; 7358 buf.length = drv_ctx.num_planes; 7359 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d", 7360 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress); 7361 7362 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 7363 if (rc) { 7364 /*TODO: How to handle this case */ 7365 DEBUG_PRINT_ERROR("Failed to qbuf to driver"); 7366 } 7367 return OMX_ErrorNone; 7368 } 7369 7370 /* ====================================================================== 7371 FUNCTION 7372 omx_vdec::SetCallbacks 7373 7374 DESCRIPTION 7375 Set the callbacks. 7376 7377 PARAMETERS 7378 None. 7379 7380 RETURN VALUE 7381 OMX Error None if everything successful. 7382 7383 ========================================================================== */ 7384 OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 7385 OMX_IN OMX_CALLBACKTYPE* callbacks, 7386 OMX_IN OMX_PTR appData) 7387 { 7388 (void) hComp; 7389 m_cb = *callbacks; 7390 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 7391 m_cb.EventHandler,m_cb.FillBufferDone); 7392 m_app_data = appData; 7393 return OMX_ErrorNotImplemented; 7394 } 7395 7396 /* ====================================================================== 7397 FUNCTION 7398 omx_vdec::ComponentDeInit 7399 7400 DESCRIPTION 7401 Destroys the component and release memory allocated to the heap. 7402 7403 PARAMETERS 7404 <TBD>. 7405 7406 RETURN VALUE 7407 OMX Error None if everything successful. 7408 7409 ========================================================================== */ 7410 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 7411 { 7412 (void) hComp; 7413 7414 unsigned i = 0; 7415 if (OMX_StateLoaded != m_state) { 7416 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\ 7417 m_state); 7418 DEBUG_PRINT_ERROR("Playback Ended - FAILED"); 7419 } else { 7420 DEBUG_PRINT_HIGH("Playback Ended - PASSED"); 7421 } 7422 7423 /*Check if the output buffers have to be cleaned up*/ 7424 if (m_out_mem_ptr) { 7425 DEBUG_PRINT_LOW("Freeing the Output Memory"); 7426 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) { 7427 if (BITMASK_PRESENT(&m_out_bm_count, i)) { 7428 BITMASK_CLEAR(&m_out_bm_count, i); 7429 client_buffers.free_output_buffer (&m_out_mem_ptr[i]); 7430 } 7431 7432 if (release_output_done()) { 7433 break; 7434 } 7435 } 7436 #ifdef _ANDROID_ICS_ 7437 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 7438 #endif 7439 } 7440 7441 /*Check if the input buffers have to be cleaned up*/ 7442 if (m_inp_mem_ptr || m_inp_heap_ptr) { 7443 DEBUG_PRINT_LOW("Freeing the Input Memory"); 7444 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) { 7445 7446 if (BITMASK_PRESENT(&m_inp_bm_count, i)) { 7447 BITMASK_CLEAR(&m_inp_bm_count, i); 7448 if (m_inp_mem_ptr) 7449 free_input_buffer (i,&m_inp_mem_ptr[i]); 7450 else 7451 free_input_buffer (i,NULL); 7452 } 7453 7454 if (release_input_done()) { 7455 break; 7456 } 7457 } 7458 } 7459 free_input_buffer_header(); 7460 free_output_buffer_header(); 7461 if (h264_scratch.pBuffer) { 7462 free(h264_scratch.pBuffer); 7463 h264_scratch.pBuffer = NULL; 7464 } 7465 7466 if (h264_parser) { 7467 delete h264_parser; 7468 h264_parser = NULL; 7469 } 7470 7471 if (m_frame_parser.mutils) { 7472 DEBUG_PRINT_LOW("Free utils parser"); 7473 delete (m_frame_parser.mutils); 7474 m_frame_parser.mutils = NULL; 7475 } 7476 7477 if (m_platform_list) { 7478 free(m_platform_list); 7479 m_platform_list = NULL; 7480 } 7481 if (m_vendor_config.pData) { 7482 free(m_vendor_config.pData); 7483 m_vendor_config.pData = NULL; 7484 } 7485 7486 // Reset counters in mesg queues 7487 m_ftb_q.m_size=0; 7488 m_cmd_q.m_size=0; 7489 m_etb_q.m_size=0; 7490 m_ftb_q.m_read = m_ftb_q.m_write =0; 7491 m_cmd_q.m_read = m_cmd_q.m_write =0; 7492 m_etb_q.m_read = m_etb_q.m_write =0; 7493 #ifdef _ANDROID_ 7494 if (m_debug_timestamp) { 7495 m_timestamp_list.reset_ts_list(); 7496 } 7497 #endif 7498 7499 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG"); 7500 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 7501 // NULL); 7502 DEBUG_PRINT_HIGH("Close the driver instance"); 7503 7504 if (m_debug.infile) { 7505 fclose(m_debug.infile); 7506 m_debug.infile = NULL; 7507 } 7508 if (m_debug.outfile) { 7509 fclose(m_debug.outfile); 7510 m_debug.outfile = NULL; 7511 } 7512 if (m_debug.out_ymeta_file) { 7513 fclose(m_debug.out_ymeta_file); 7514 m_debug.out_ymeta_file = NULL; 7515 } 7516 if (m_debug.out_uvmeta_file) { 7517 fclose(m_debug.out_uvmeta_file); 7518 m_debug.out_uvmeta_file = NULL; 7519 } 7520 #ifdef OUTPUT_EXTRADATA_LOG 7521 if (outputExtradataFile) 7522 fclose (outputExtradataFile); 7523 #endif 7524 DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete"); 7525 return OMX_ErrorNone; 7526 } 7527 7528 /* ====================================================================== 7529 FUNCTION 7530 omx_vdec::UseEGLImage 7531 7532 DESCRIPTION 7533 OMX Use EGL Image method implementation <TBD>. 7534 7535 PARAMETERS 7536 <TBD>. 7537 7538 RETURN VALUE 7539 Not Implemented error. 7540 7541 ========================================================================== */ 7542 OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 7543 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 7544 OMX_IN OMX_U32 port, 7545 OMX_IN OMX_PTR appData, 7546 OMX_IN void* eglImage) 7547 { 7548 (void) appData; 7549 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; 7550 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; 7551 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; 7552 7553 #ifdef USE_EGL_IMAGE_GPU 7554 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; 7555 EGLint fd = -1, offset = 0,pmemPtr = 0; 7556 #else 7557 int fd = -1, offset = 0; 7558 #endif 7559 DEBUG_PRINT_HIGH("use EGL image support for decoder"); 7560 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { 7561 DEBUG_PRINT_ERROR("Invalid EGL image"); 7562 } 7563 #ifdef USE_EGL_IMAGE_GPU 7564 if (m_display_id == NULL) { 7565 DEBUG_PRINT_ERROR("Display ID is not set by IL client"); 7566 return OMX_ErrorInsufficientResources; 7567 } 7568 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) 7569 eglGetProcAddress("eglQueryImageKHR"); 7570 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd); 7571 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset); 7572 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr); 7573 #else //with OMX test app 7574 struct temp_egl { 7575 int pmem_fd; 7576 int offset; 7577 }; 7578 struct temp_egl *temp_egl_id = NULL; 7579 void * pmemPtr = (void *) eglImage; 7580 temp_egl_id = (struct temp_egl *)eglImage; 7581 if (temp_egl_id != NULL) { 7582 fd = temp_egl_id->pmem_fd; 7583 offset = temp_egl_id->offset; 7584 } 7585 #endif 7586 if (fd < 0) { 7587 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd); 7588 return OMX_ErrorInsufficientResources; 7589 } 7590 pmem_info.pmem_fd = (OMX_U32) fd; 7591 pmem_info.offset = (OMX_U32) offset; 7592 pmem_entry.entry = (void *) &pmem_info; 7593 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 7594 pmem_list.entryList = &pmem_entry; 7595 pmem_list.nEntries = 1; 7596 ouput_egl_buffers = true; 7597 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, 7598 (void *)&pmem_list, drv_ctx.op_buf.buffer_size, 7599 (OMX_U8 *)pmemPtr)) { 7600 DEBUG_PRINT_ERROR("use buffer call failed for egl image"); 7601 return OMX_ErrorInsufficientResources; 7602 } 7603 return OMX_ErrorNone; 7604 } 7605 7606 /* ====================================================================== 7607 FUNCTION 7608 omx_vdec::ComponentRoleEnum 7609 7610 DESCRIPTION 7611 OMX Component Role Enum method implementation. 7612 7613 PARAMETERS 7614 <TBD>. 7615 7616 RETURN VALUE 7617 OMX Error None if everything is successful. 7618 ========================================================================== */ 7619 OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 7620 OMX_OUT OMX_U8* role, 7621 OMX_IN OMX_U32 index) 7622 { 7623 (void) hComp; 7624 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7625 7626 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 7627 if ((0 == index) && role) { 7628 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 7629 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7630 } else { 7631 eRet = OMX_ErrorNoMore; 7632 } 7633 } 7634 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 7635 if ((0 == index) && role) { 7636 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 7637 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7638 } else { 7639 eRet = OMX_ErrorNoMore; 7640 } 7641 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 7642 if ((0 == index) && role) { 7643 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 7644 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7645 } else { 7646 DEBUG_PRINT_LOW("No more roles"); 7647 eRet = OMX_ErrorNoMore; 7648 } 7649 } 7650 7651 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 7652 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) { 7653 if ((0 == index) && role) { 7654 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 7655 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7656 } else { 7657 DEBUG_PRINT_LOW("No more roles"); 7658 eRet = OMX_ErrorNoMore; 7659 } 7660 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 7661 if ((0 == index) && role) { 7662 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 7663 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7664 } else { 7665 DEBUG_PRINT_LOW("No more roles"); 7666 eRet = OMX_ErrorNoMore; 7667 } 7668 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 7669 if ((0 == index) && role) { 7670 strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 7671 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7672 } else { 7673 DEBUG_PRINT_LOW("No more roles"); 7674 eRet = OMX_ErrorNoMore; 7675 } 7676 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 7677 if ((0 == index) && role) { 7678 strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 7679 DEBUG_PRINT_LOW("component_role_enum: role %s", role); 7680 } else { 7681 DEBUG_PRINT_LOW("No more roles"); 7682 eRet = OMX_ErrorNoMore; 7683 } 7684 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 7685 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 7686 ) { 7687 if ((0 == index) && role) { 7688 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 7689 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7690 } else { 7691 DEBUG_PRINT_LOW("No more roles"); 7692 eRet = OMX_ErrorNoMore; 7693 } 7694 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 7695 if ((0 == index) && role) { 7696 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 7697 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7698 } else { 7699 DEBUG_PRINT_LOW("No more roles"); 7700 eRet = OMX_ErrorNoMore; 7701 } 7702 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 7703 if ((0 == index) && role) { 7704 strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 7705 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 7706 } else { 7707 DEBUG_PRINT_LOW("No more roles"); 7708 eRet = OMX_ErrorNoMore; 7709 } 7710 } else { 7711 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component"); 7712 eRet = OMX_ErrorInvalidComponentName; 7713 } 7714 return eRet; 7715 } 7716 7717 7718 7719 7720 /* ====================================================================== 7721 FUNCTION 7722 omx_vdec::AllocateDone 7723 7724 DESCRIPTION 7725 Checks if entire buffer pool is allocated by IL Client or not. 7726 Need this to move to IDLE state. 7727 7728 PARAMETERS 7729 None. 7730 7731 RETURN VALUE 7732 true/false. 7733 7734 ========================================================================== */ 7735 bool omx_vdec::allocate_done(void) 7736 { 7737 bool bRet = false; 7738 bool bRet_In = false; 7739 bool bRet_Out = false; 7740 7741 bRet_In = allocate_input_done(); 7742 bRet_Out = allocate_output_done(); 7743 7744 if (bRet_In && bRet_Out) { 7745 bRet = true; 7746 } 7747 7748 return bRet; 7749 } 7750 /* ====================================================================== 7751 FUNCTION 7752 omx_vdec::AllocateInputDone 7753 7754 DESCRIPTION 7755 Checks if I/P buffer pool is allocated by IL Client or not. 7756 7757 PARAMETERS 7758 None. 7759 7760 RETURN VALUE 7761 true/false. 7762 7763 ========================================================================== */ 7764 bool omx_vdec::allocate_input_done(void) 7765 { 7766 bool bRet = false; 7767 unsigned i=0; 7768 7769 if (m_inp_mem_ptr == NULL) { 7770 return bRet; 7771 } 7772 if (m_inp_mem_ptr ) { 7773 for (; i<drv_ctx.ip_buf.actualcount; i++) { 7774 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 7775 break; 7776 } 7777 } 7778 } 7779 if (i == drv_ctx.ip_buf.actualcount) { 7780 bRet = true; 7781 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers"); 7782 } 7783 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) { 7784 m_inp_bPopulated = OMX_TRUE; 7785 } 7786 return bRet; 7787 } 7788 /* ====================================================================== 7789 FUNCTION 7790 omx_vdec::AllocateOutputDone 7791 7792 DESCRIPTION 7793 Checks if entire O/P buffer pool is allocated by IL Client or not. 7794 7795 PARAMETERS 7796 None. 7797 7798 RETURN VALUE 7799 true/false. 7800 7801 ========================================================================== */ 7802 bool omx_vdec::allocate_output_done(void) 7803 { 7804 bool bRet = false; 7805 unsigned j=0; 7806 7807 if (m_out_mem_ptr == NULL) { 7808 return bRet; 7809 } 7810 7811 if (m_out_mem_ptr) { 7812 for (; j < drv_ctx.op_buf.actualcount; j++) { 7813 if (BITMASK_ABSENT(&m_out_bm_count,j)) { 7814 break; 7815 } 7816 } 7817 } 7818 7819 if (j == drv_ctx.op_buf.actualcount) { 7820 bRet = true; 7821 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers"); 7822 if (m_out_bEnabled) 7823 m_out_bPopulated = OMX_TRUE; 7824 } 7825 7826 return bRet; 7827 } 7828 7829 /* ====================================================================== 7830 FUNCTION 7831 omx_vdec::ReleaseDone 7832 7833 DESCRIPTION 7834 Checks if IL client has released all the buffers. 7835 7836 PARAMETERS 7837 None. 7838 7839 RETURN VALUE 7840 true/false 7841 7842 ========================================================================== */ 7843 bool omx_vdec::release_done(void) 7844 { 7845 bool bRet = false; 7846 7847 if (release_input_done()) { 7848 if (release_output_done()) { 7849 bRet = true; 7850 } 7851 } 7852 return bRet; 7853 } 7854 7855 7856 /* ====================================================================== 7857 FUNCTION 7858 omx_vdec::ReleaseOutputDone 7859 7860 DESCRIPTION 7861 Checks if IL client has released all the buffers. 7862 7863 PARAMETERS 7864 None. 7865 7866 RETURN VALUE 7867 true/false 7868 7869 ========================================================================== */ 7870 bool omx_vdec::release_output_done(void) 7871 { 7872 bool bRet = false; 7873 unsigned i=0,j=0; 7874 7875 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr); 7876 if (m_out_mem_ptr) { 7877 for (; j < drv_ctx.op_buf.actualcount ; j++) { 7878 if (BITMASK_PRESENT(&m_out_bm_count,j)) { 7879 break; 7880 } 7881 } 7882 if (j == drv_ctx.op_buf.actualcount) { 7883 m_out_bm_count = 0; 7884 bRet = true; 7885 } 7886 } else { 7887 m_out_bm_count = 0; 7888 bRet = true; 7889 } 7890 return bRet; 7891 } 7892 /* ====================================================================== 7893 FUNCTION 7894 omx_vdec::ReleaseInputDone 7895 7896 DESCRIPTION 7897 Checks if IL client has released all the buffers. 7898 7899 PARAMETERS 7900 None. 7901 7902 RETURN VALUE 7903 true/false 7904 7905 ========================================================================== */ 7906 bool omx_vdec::release_input_done(void) 7907 { 7908 bool bRet = false; 7909 unsigned i=0,j=0; 7910 7911 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 7912 if (m_inp_mem_ptr) { 7913 for (; j<drv_ctx.ip_buf.actualcount; j++) { 7914 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) { 7915 break; 7916 } 7917 } 7918 if (j==drv_ctx.ip_buf.actualcount) { 7919 bRet = true; 7920 } 7921 } else { 7922 bRet = true; 7923 } 7924 return bRet; 7925 } 7926 7927 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 7928 OMX_BUFFERHEADERTYPE * buffer) 7929 { 7930 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 7931 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) { 7932 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer); 7933 return OMX_ErrorBadParameter; 7934 } else if (output_flush_progress) { 7935 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); 7936 buffer->nFilledLen = 0; 7937 buffer->nTimeStamp = 0; 7938 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 7939 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7940 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; 7941 } 7942 7943 if (m_debug_extradata) { 7944 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 7945 DEBUG_PRINT_HIGH("***************************************************"); 7946 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received"); 7947 DEBUG_PRINT_HIGH("***************************************************"); 7948 } 7949 7950 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) { 7951 DEBUG_PRINT_HIGH("***************************************************"); 7952 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 7953 DEBUG_PRINT_HIGH("***************************************************"); 7954 } 7955 } 7956 7957 7958 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld", 7959 buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp); 7960 pending_output_buffers --; 7961 7962 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 7963 DEBUG_PRINT_HIGH("Output EOS has been reached"); 7964 if (!output_flush_progress) 7965 post_event((unsigned)NULL, (unsigned)NULL, 7966 OMX_COMPONENT_GENERATE_EOS_DONE); 7967 7968 if (psource_frame) { 7969 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); 7970 psource_frame = NULL; 7971 } 7972 if (pdest_frame) { 7973 pdest_frame->nFilledLen = 0; 7974 m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL, 7975 (unsigned)NULL); 7976 pdest_frame = NULL; 7977 } 7978 } 7979 7980 if (!output_flush_progress && (buffer->nFilledLen > 0)) { 7981 // set the default colorspace advised by client, since the bitstream may be 7982 // devoid of colorspace-info. 7983 if (m_enable_android_native_buffers) { 7984 ColorSpace_t color_space = ITU_R_601; 7985 7986 // Disabled ? 7987 // WA for VP8. Vp8 encoder does not embed color-info (yet!). 7988 // Encoding RGBA results in 601-LR for all resolutions. 7989 // This conflicts with the client't defaults which are based on resolution. 7990 // Eg: 720p will be encoded as 601-LR. Client will say 709. 7991 // Re-enable this code once vp8 encoder generates color-info and hence the 7992 // decoder will be able to override with the correct source color. 7993 #if 0 7994 switch (m_client_color_space.sAspects.mPrimaries) { 7995 case ColorAspects::PrimariesBT601_6_625: 7996 case ColorAspects::PrimariesBT601_6_525: 7997 { 7998 color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ? 7999 ITU_R_601_FR : ITU_R_601; 8000 break; 8001 } 8002 case ColorAspects::PrimariesBT709_5: 8003 { 8004 color_space = ITU_R_709; 8005 break; 8006 } 8007 default: 8008 { 8009 break; 8010 } 8011 } 8012 #endif 8013 DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)", 8014 color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); 8015 set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr); 8016 } 8017 DEBUG_PRINT_LOW("Processing extradata"); 8018 handle_extradata(buffer); 8019 } 8020 8021 #ifdef OUTPUT_EXTRADATA_LOG 8022 if (outputExtradataFile) { 8023 int buf_index = buffer - m_out_mem_ptr; 8024 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr); 8025 8026 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 8027 p_extra = (OMX_OTHER_EXTRADATATYPE *) 8028 ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3)); 8029 8030 while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) { 8031 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x", 8032 p_extra->nSize, p_extra->eType); 8033 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); 8034 8035 if (p_extra->eType == OMX_ExtraDataNone) { 8036 break; 8037 } 8038 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8039 } 8040 } 8041 #endif 8042 8043 /* For use buffer we need to copy the data */ 8044 if (!output_flush_progress) { 8045 /* This is the error check for non-recoverable errros */ 8046 bool is_duplicate_ts_valid = true; 8047 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive); 8048 8049 if (output_capability == V4L2_PIX_FMT_MPEG4 || 8050 output_capability == V4L2_PIX_FMT_MPEG2 || 8051 output_capability == V4L2_PIX_FMT_DIVX || 8052 output_capability == V4L2_PIX_FMT_DIVX_311) 8053 is_duplicate_ts_valid = false; 8054 8055 if ((output_capability == V4L2_PIX_FMT_H264 || 8056 output_capability == V4L2_PIX_FMT_H264_MVC) && 8057 is_interlaced) { 8058 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) { 8059 is_interlaced = false; 8060 } 8061 } 8062 8063 if (buffer->nFilledLen > 0) { 8064 time_stamp_dts.get_next_timestamp(buffer, 8065 is_interlaced && is_duplicate_ts_valid); 8066 if (m_debug_timestamp) { 8067 { 8068 OMX_TICKS expected_ts = 0; 8069 m_timestamp_list.pop_min_ts(expected_ts); 8070 if (is_interlaced && is_duplicate_ts_valid) { 8071 m_timestamp_list.pop_min_ts(expected_ts); 8072 } 8073 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", 8074 buffer->nTimeStamp, expected_ts); 8075 8076 if (buffer->nTimeStamp != expected_ts) { 8077 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check"); 8078 } 8079 } 8080 } 8081 } 8082 } 8083 8084 if (m_cb.FillBufferDone) { 8085 if (buffer->nFilledLen > 0) { 8086 if (arbitrary_bytes) 8087 adjust_timestamp(buffer->nTimeStamp); 8088 else 8089 set_frame_rate(buffer->nTimeStamp); 8090 8091 if (perf_flag) { 8092 if (!proc_frms) { 8093 dec_time.stop(); 8094 latency = dec_time.processing_time_us() - latency; 8095 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); 8096 dec_time.start(); 8097 fps_metrics.start(); 8098 } 8099 proc_frms++; 8100 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8101 OMX_U64 proc_time = 0; 8102 fps_metrics.stop(); 8103 proc_time = fps_metrics.processing_time_us(); 8104 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)", 8105 (unsigned int)proc_frms, (float)proc_time / 1e6, 8106 (float)(1e6 * proc_frms) / proc_time); 8107 proc_frms = 0; 8108 } 8109 } 8110 } 8111 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8112 prev_ts = LLONG_MAX; 8113 rst_prev_ts = true; 8114 } 8115 8116 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 8117 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 8118 buffer->pPlatformPrivate)->entryList->entry; 8119 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd); 8120 OMX_BUFFERHEADERTYPE *il_buffer; 8121 il_buffer = client_buffers.get_il_buf_hdr(buffer); 8122 OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator); 8123 8124 if (il_buffer && m_last_rendered_TS >= 0) { 8125 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS); 8126 8127 // Current frame can be send for rendering if 8128 // (a) current FPS is <= 60 8129 // (b) is the next frame after the frame with TS 0 8130 // (c) is the first frame after seek 8131 // (d) the delta TS b\w two consecutive frames is > 16 ms 8132 // (e) its TS is equal to previous frame TS 8133 // (f) if marked EOS 8134 8135 if(current_framerate <= 60 || m_last_rendered_TS == 0 || 8136 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 || 8137 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 8138 m_last_rendered_TS = il_buffer->nTimeStamp; 8139 } else { 8140 //mark for droping 8141 buffer->nFilledLen = 0; 8142 } 8143 8144 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)", 8145 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS, 8146 il_buffer->nTimeStamp,ts_delta); 8147 8148 //above code makes sure that delta b\w two consecutive frames is not 8149 //greater than 16ms, slow-mo feature, so cap fps to max 60 8150 if (current_framerate > 60 ) { 8151 current_framerate = 60; 8152 } 8153 } 8154 8155 // add current framerate to gralloc meta data 8156 if (m_enable_android_native_buffers && m_out_mem_ptr) { 8157 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8158 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 8159 UPDATE_REFRESH_RATE, (void*)¤t_framerate); 8160 } 8161 8162 if (il_buffer) { 8163 log_output_buffers(il_buffer); 8164 if (dynamic_buf_mode) { 8165 unsigned int nPortIndex = 0; 8166 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 8167 8168 // Since we're passing around handles, adjust nFilledLen and nAllocLen 8169 // to size of the handle. Do it _after_ log_output_buffers which 8170 // requires the respective sizes to be accurate. 8171 8172 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 8173 buffer->nFilledLen = buffer->nFilledLen ? 8174 sizeof(struct VideoDecoderOutputMetaData) : 0; 8175 8176 //Clear graphic buffer handles in dynamic mode 8177 if (nPortIndex < drv_ctx.op_buf.actualcount && 8178 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 8179 native_buffer[nPortIndex].privatehandle = NULL; 8180 native_buffer[nPortIndex].nativehandle = NULL; 8181 } else { 8182 DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex); 8183 return OMX_ErrorBadParameter; 8184 } 8185 } 8186 m_cb.FillBufferDone (hComp,m_app_data,il_buffer); 8187 } else { 8188 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); 8189 return OMX_ErrorBadParameter; 8190 } 8191 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd); 8192 } else { 8193 return OMX_ErrorBadParameter; 8194 } 8195 8196 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED 8197 if (m_smoothstreaming_mode && m_out_mem_ptr) { 8198 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8199 BufferDim_t dim; 8200 private_handle_t *private_handle = NULL; 8201 dim.sliceWidth = framesize.nWidth; 8202 dim.sliceHeight = framesize.nHeight; 8203 if (buf_index < drv_ctx.op_buf.actualcount && 8204 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 8205 native_buffer[buf_index].privatehandle) 8206 private_handle = native_buffer[buf_index].privatehandle; 8207 if (private_handle) { 8208 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d", 8209 dim.sliceWidth, dim.sliceHeight); 8210 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim); 8211 } 8212 } 8213 #endif 8214 8215 return OMX_ErrorNone; 8216 } 8217 8218 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 8219 OMX_BUFFERHEADERTYPE* buffer) 8220 { 8221 8222 int nBufferIndex = buffer - m_inp_mem_ptr; 8223 8224 if (buffer == NULL || (nBufferIndex > (int)drv_ctx.ip_buf.actualcount)) { 8225 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer); 8226 return OMX_ErrorBadParameter; 8227 } 8228 8229 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x", 8230 buffer, buffer->pBuffer, buffer->nFlags); 8231 pending_input_buffers--; 8232 8233 if (arbitrary_bytes) { 8234 if (pdest_frame == NULL && input_flush_progress == false) { 8235 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); 8236 pdest_frame = buffer; 8237 buffer->nFilledLen = 0; 8238 buffer->nTimeStamp = LLONG_MAX; 8239 push_input_buffer (hComp); 8240 } else { 8241 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); 8242 buffer->nFilledLen = 0; 8243 if (!m_input_free_q.insert_entry((unsigned long)buffer, 8244 (unsigned)NULL, (unsigned)NULL)) { 8245 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error"); 8246 } 8247 } 8248 } else if (m_cb.EmptyBufferDone) { 8249 buffer->nFilledLen = 0; 8250 if (input_use_buffer == true) { 8251 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; 8252 } 8253 8254 /* Restore the FD that we over-wrote in ETB */ 8255 if (m_input_pass_buffer_fd) { 8256 buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd; 8257 } 8258 8259 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 8260 } 8261 return OMX_ErrorNone; 8262 } 8263 8264 int omx_vdec::async_message_process (void *context, void* message) 8265 { 8266 omx_vdec* omx = NULL; 8267 struct vdec_msginfo *vdec_msg = NULL; 8268 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 8269 struct v4l2_buffer *v4l2_buf_ptr = NULL; 8270 struct vdec_output_frameinfo *output_respbuf = NULL; 8271 int rc=1; 8272 if (context == NULL || message == NULL) { 8273 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check"); 8274 return -1; 8275 } 8276 vdec_msg = (struct vdec_msginfo *)message; 8277 8278 omx = reinterpret_cast<omx_vdec*>(context); 8279 8280 switch (vdec_msg->msgcode) { 8281 8282 case VDEC_MSG_EVT_HW_ERROR: 8283 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8284 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 8285 break; 8286 8287 case VDEC_MSG_EVT_HW_OVERLOAD: 8288 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8289 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD); 8290 break; 8291 8292 case VDEC_MSG_EVT_HW_UNSUPPORTED: 8293 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8294 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); 8295 break; 8296 8297 case VDEC_MSG_RESP_START_DONE: 8298 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8299 OMX_COMPONENT_GENERATE_START_DONE); 8300 break; 8301 8302 case VDEC_MSG_RESP_STOP_DONE: 8303 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8304 OMX_COMPONENT_GENERATE_STOP_DONE); 8305 break; 8306 8307 case VDEC_MSG_RESP_RESUME_DONE: 8308 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8309 OMX_COMPONENT_GENERATE_RESUME_DONE); 8310 break; 8311 8312 case VDEC_MSG_RESP_PAUSE_DONE: 8313 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8314 OMX_COMPONENT_GENERATE_PAUSE_DONE); 8315 break; 8316 8317 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 8318 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8319 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 8320 break; 8321 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 8322 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8323 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 8324 break; 8325 case VDEC_MSG_RESP_INPUT_FLUSHED: 8326 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 8327 8328 /* omxhdr = (OMX_BUFFERHEADERTYPE* ) 8329 vdec_msg->msgdata.input_frame_clientdata; */ 8330 8331 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; 8332 if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL || 8333 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) { 8334 omxhdr = NULL; 8335 vdec_msg->status_code = VDEC_S_EFATAL; 8336 break; 8337 8338 } 8339 omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index; 8340 8341 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) { 8342 DEBUG_PRINT_HIGH("Unsupported input"); 8343 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8344 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 8345 } 8346 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 8347 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 8348 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; 8349 } 8350 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 8351 8352 DEBUG_PRINT_LOW("Decrement codec_config buffer counter"); 8353 android_atomic_dec(&omx->m_queued_codec_config_count); 8354 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) && 8355 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) { 8356 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer"); 8357 sem_post(&omx->m_safe_flush); 8358 } 8359 } 8360 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || 8361 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 8362 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 8363 } 8364 omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code, 8365 OMX_COMPONENT_GENERATE_EBD); 8366 break; 8367 case VDEC_MSG_EVT_INFO_FIELD_DROPPED: 8368 int64_t *timestamp; 8369 timestamp = (int64_t *) malloc(sizeof(int64_t)); 8370 if (timestamp) { 8371 *timestamp = vdec_msg->msgdata.output_frame.time_stamp; 8372 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code, 8373 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); 8374 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", 8375 (long long)vdec_msg->msgdata.output_frame.time_stamp); 8376 } 8377 break; 8378 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 8379 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 8380 8381 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; 8382 8383 if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL || 8384 v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) { 8385 omxhdr = NULL; 8386 vdec_msg->status_code = VDEC_S_EFATAL; 8387 break; 8388 } 8389 8390 omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index; 8391 8392 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)", 8393 omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp, 8394 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags, 8395 (unsigned int)vdec_msg->msgdata.output_frame.len, 8396 vdec_msg->msgdata.output_frame.framesize.left, 8397 vdec_msg->msgdata.output_frame.framesize.top, 8398 vdec_msg->msgdata.output_frame.framesize.right, 8399 vdec_msg->msgdata.output_frame.framesize.bottom); 8400 8401 if (omxhdr && omxhdr->pOutputPortPrivate && 8402 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) && 8403 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 8404 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) { 8405 8406 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) { 8407 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 8408 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 8409 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 8410 omxhdr->nFlags = 0; 8411 8412 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) { 8413 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; 8414 //rc = -1; 8415 } 8416 if (omxhdr->nFilledLen) { 8417 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; 8418 } 8419 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 8420 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 8421 } else { 8422 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; 8423 } 8424 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) { 8425 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 8426 } 8427 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) { 8428 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; 8429 } 8430 8431 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) { 8432 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF; 8433 } 8434 8435 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) { 8436 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY; 8437 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d", 8438 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd); 8439 } 8440 8441 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && 8442 !omx->output_flush_progress && 8443 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && 8444 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) { 8445 unsigned int index = v4l2_buf_ptr->index; 8446 unsigned int extra_idx = EXTRADATA_IDX(omx->drv_ctx.num_planes); 8447 struct v4l2_plane *plane = v4l2_buf_ptr->m.planes; 8448 omx->time_stamp_dts.remove_time_stamp( 8449 omxhdr->nTimeStamp, 8450 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 8451 ?true:false); 8452 plane[0].bytesused = 0; 8453 plane[0].m.userptr = 8454 (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].bufferaddr - 8455 (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].offset; 8456 plane[0].reserved[0] = omx->drv_ctx.ptr_outputbuffer[index].pmem_fd; 8457 plane[0].reserved[1] = omx->drv_ctx.ptr_outputbuffer[index].offset; 8458 plane[0].data_offset = 0; 8459 v4l2_buf_ptr->flags = 0x0; 8460 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 8461 plane[extra_idx].bytesused = 0; 8462 plane[extra_idx].length = omx->drv_ctx.extradata_info.buffer_size; 8463 plane[extra_idx].m.userptr = (long unsigned int) (omx->drv_ctx.extradata_info.uaddr + index * omx->drv_ctx.extradata_info.buffer_size); 8464 #ifdef USE_ION 8465 plane[extra_idx].reserved[0] = omx->drv_ctx.extradata_info.ion.fd_ion_data.fd; 8466 #endif 8467 plane[extra_idx].reserved[1] = v4l2_buf_ptr->index * omx->drv_ctx.extradata_info.buffer_size; 8468 plane[extra_idx].data_offset = 0; 8469 } else if (extra_idx >= VIDEO_MAX_PLANES) { 8470 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx); 8471 return -1; 8472 } 8473 8474 DEBUG_PRINT_LOW("SENDING FTB TO F/W from async_message_process - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d", 8475 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], omx->output_flush_progress); 8476 if(ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_QBUF, v4l2_buf_ptr)) { 8477 DEBUG_PRINT_ERROR("Failed to queue buffer back to driver: %d, %d, %d", v4l2_buf_ptr->length, v4l2_buf_ptr->m.planes[0].reserved[0], v4l2_buf_ptr->m.planes[1].reserved[0]); 8478 return -1; 8479 } 8480 break; 8481 } 8482 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 8483 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 8484 } 8485 vdec_msg->msgdata.output_frame.bufferaddr = 8486 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; 8487 8488 /* Post event if resolution OR crop changed */ 8489 /* filled length will be changed if resolution changed */ 8490 /* Crop parameters can be changed even without resolution change */ 8491 if (omxhdr->nFilledLen 8492 && ((omx->prev_n_filled_len != omxhdr->nFilledLen) 8493 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left) 8494 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top) 8495 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right) 8496 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom) 8497 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width) 8498 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) { 8499 8500 DEBUG_PRINT_HIGH("Paramters 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", 8501 omx->prev_n_filled_len, 8502 omx->drv_ctx.video_resolution.frame_width, 8503 omx->drv_ctx.video_resolution.frame_height, 8504 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top, 8505 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom, 8506 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width, 8507 vdec_msg->msgdata.output_frame.picsize.frame_height, 8508 vdec_msg->msgdata.output_frame.framesize.left, 8509 vdec_msg->msgdata.output_frame.framesize.top, 8510 vdec_msg->msgdata.output_frame.framesize.right, 8511 vdec_msg->msgdata.output_frame.framesize.bottom); 8512 8513 omx->drv_ctx.video_resolution.frame_width = 8514 vdec_msg->msgdata.output_frame.picsize.frame_width; 8515 omx->drv_ctx.video_resolution.frame_height = 8516 vdec_msg->msgdata.output_frame.picsize.frame_height; 8517 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 8518 omx->drv_ctx.video_resolution.stride = 8519 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width); 8520 omx->drv_ctx.video_resolution.scan_lines = 8521 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height); 8522 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 8523 omx->drv_ctx.video_resolution.stride = 8524 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width); 8525 omx->drv_ctx.video_resolution.scan_lines = 8526 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height); 8527 } 8528 8529 memcpy(&omx->drv_ctx.frame_size, 8530 &vdec_msg->msgdata.output_frame.framesize, 8531 sizeof(struct vdec_framesize)); 8532 8533 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX, 8534 OMX_IndexConfigCommonOutputCrop, 8535 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 8536 } 8537 8538 if (omxhdr->nFilledLen) 8539 omx->prev_n_filled_len = omxhdr->nFilledLen; 8540 8541 output_respbuf = (struct vdec_output_frameinfo *)\ 8542 omxhdr->pOutputPortPrivate; 8543 if (!output_respbuf) { 8544 DEBUG_PRINT_ERROR("async_message_process: invalid output buf received"); 8545 return -1; 8546 } 8547 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 8548 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 8549 8550 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) { 8551 output_respbuf->pic_type = PICTURE_TYPE_I; 8552 } 8553 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) { 8554 output_respbuf->pic_type = PICTURE_TYPE_P; 8555 } 8556 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { 8557 output_respbuf->pic_type = PICTURE_TYPE_B; 8558 } 8559 if (omxhdr && omxhdr->nFilledLen) { 8560 omx->request_perf_level(VIDC_NOMINAL); 8561 } 8562 if (omx->output_use_buffer && omxhdr->pBuffer && 8563 vdec_msg->msgdata.output_frame.bufferaddr) 8564 memcpy ( omxhdr->pBuffer, (void *) 8565 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + 8566 (unsigned long)vdec_msg->msgdata.output_frame.offset), 8567 vdec_msg->msgdata.output_frame.len); 8568 } else { 8569 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u", 8570 (unsigned int)vdec_msg->msgdata.output_frame.len, 8571 omxhdr->nAllocLen, omx->prev_n_filled_len); 8572 omxhdr->nFilledLen = 0; 8573 } 8574 8575 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code, 8576 OMX_COMPONENT_GENERATE_FBD); 8577 8578 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) { 8579 omx->post_event ((unsigned long)NULL, vdec_msg->status_code, 8580 OMX_COMPONENT_GENERATE_EOS_DONE); 8581 } else { 8582 omx->post_event ((unsigned int)NULL, vdec_msg->status_code, 8583 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 8584 } 8585 break; 8586 case VDEC_MSG_EVT_CONFIG_CHANGED: 8587 DEBUG_PRINT_HIGH("Port settings changed"); 8588 omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width; 8589 omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height; 8590 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, 8591 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 8592 omx->request_perf_level(VIDC_NOMINAL); 8593 break; 8594 default: 8595 break; 8596 } 8597 return rc; 8598 } 8599 8600 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 8601 OMX_HANDLETYPE hComp, 8602 OMX_BUFFERHEADERTYPE *buffer 8603 ) 8604 { 8605 unsigned address,p2,id; 8606 DEBUG_PRINT_LOW("Empty this arbitrary"); 8607 8608 if (buffer == NULL) { 8609 return OMX_ErrorBadParameter; 8610 } 8611 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 8612 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld", 8613 (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp); 8614 8615 /* return zero length and not an EOS buffer */ 8616 /* return buffer if input flush in progress */ 8617 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && 8618 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) { 8619 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); 8620 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 8621 return OMX_ErrorNone; 8622 } 8623 8624 if (psource_frame == NULL) { 8625 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp); 8626 psource_frame = buffer; 8627 DEBUG_PRINT_LOW("Try to Push One Input Buffer "); 8628 push_input_buffer (hComp); 8629 } else { 8630 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); 8631 if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL, 8632 (unsigned)NULL)) { 8633 return OMX_ErrorBadParameter; 8634 } 8635 } 8636 8637 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 8638 codec_config_flag = false; 8639 } 8640 return OMX_ErrorNone; 8641 } 8642 8643 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 8644 { 8645 unsigned long address,p2,id; 8646 OMX_ERRORTYPE ret = OMX_ErrorNone; 8647 8648 if (pdest_frame == NULL || psource_frame == NULL) { 8649 /*Check if we have a destination buffer*/ 8650 if (pdest_frame == NULL) { 8651 DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); 8652 if (m_input_free_q.m_size) { 8653 m_input_free_q.pop_entry(&address,&p2,&id); 8654 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 8655 pdest_frame->nFilledLen = 0; 8656 pdest_frame->nTimeStamp = LLONG_MAX; 8657 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); 8658 } 8659 } 8660 8661 /*Check if we have a destination buffer*/ 8662 if (psource_frame == NULL) { 8663 DEBUG_PRINT_LOW("Get a source buffer from the queue"); 8664 if (m_input_pending_q.m_size) { 8665 m_input_pending_q.pop_entry(&address,&p2,&id); 8666 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 8667 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 8668 psource_frame->nTimeStamp); 8669 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 8670 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 8671 8672 } 8673 } 8674 8675 } 8676 8677 while ((pdest_frame != NULL) && (psource_frame != NULL)) { 8678 switch (codec_type_parse) { 8679 case CODEC_TYPE_MPEG4: 8680 case CODEC_TYPE_H263: 8681 case CODEC_TYPE_MPEG2: 8682 ret = push_input_sc_codec(hComp); 8683 break; 8684 case CODEC_TYPE_H264: 8685 ret = push_input_h264(hComp); 8686 break; 8687 case CODEC_TYPE_HEVC: 8688 ret = push_input_hevc(hComp); 8689 break; 8690 case CODEC_TYPE_VC1: 8691 ret = push_input_vc1(hComp); 8692 break; 8693 default: 8694 break; 8695 } 8696 if (ret != OMX_ErrorNone) { 8697 DEBUG_PRINT_ERROR("Pushing input Buffer Failed"); 8698 omx_report_error (); 8699 break; 8700 } 8701 } 8702 8703 return ret; 8704 } 8705 8706 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 8707 { 8708 OMX_U32 partial_frame = 1; 8709 OMX_BOOL generate_ebd = OMX_TRUE; 8710 unsigned long address = 0, p2 = 0, id = 0; 8711 8712 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld", 8713 psource_frame,psource_frame->nTimeStamp); 8714 if (m_frame_parser.parse_sc_frame(psource_frame, 8715 pdest_frame,&partial_frame) == -1) { 8716 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 8717 return OMX_ErrorBadParameter; 8718 } 8719 8720 if (partial_frame == 0) { 8721 DEBUG_PRINT_LOW("Frame size %u source %p frame count %d", 8722 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count); 8723 8724 8725 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp); 8726 /*First Parsed buffer will have only header Hence skip*/ 8727 if (frame_count == 0) { 8728 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); 8729 8730 if (codec_type_parse == CODEC_TYPE_MPEG4 || 8731 codec_type_parse == CODEC_TYPE_DIVX) { 8732 mp4StreamType psBits; 8733 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; 8734 psBits.numBytes = pdest_frame->nFilledLen; 8735 mp4_headerparser.parseHeader(&psBits); 8736 } 8737 8738 frame_count++; 8739 } else { 8740 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 8741 if (pdest_frame->nFilledLen) { 8742 /*Push the frame to the Decoder*/ 8743 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 8744 return OMX_ErrorBadParameter; 8745 } 8746 frame_count++; 8747 pdest_frame = NULL; 8748 8749 if (m_input_free_q.m_size) { 8750 m_input_free_q.pop_entry(&address,&p2,&id); 8751 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 8752 pdest_frame->nFilledLen = 0; 8753 } 8754 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) { 8755 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL"); 8756 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL, 8757 (unsigned)NULL); 8758 pdest_frame = NULL; 8759 } 8760 } 8761 } else { 8762 DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen); 8763 /*Check if Destination Buffer is full*/ 8764 if (pdest_frame->nAllocLen == 8765 pdest_frame->nFilledLen + pdest_frame->nOffset) { 8766 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled"); 8767 return OMX_ErrorStreamCorrupt; 8768 } 8769 } 8770 8771 if (psource_frame->nFilledLen == 0) { 8772 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 8773 if (pdest_frame) { 8774 pdest_frame->nFlags |= psource_frame->nFlags; 8775 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld", 8776 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 8777 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 8778 (unsigned int)pdest_frame->nFilledLen,frame_count++); 8779 /*Push the frame to the Decoder*/ 8780 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 8781 return OMX_ErrorBadParameter; 8782 } 8783 frame_count++; 8784 pdest_frame = NULL; 8785 } else { 8786 DEBUG_PRINT_LOW("Last frame in else dest addr") ; 8787 generate_ebd = OMX_FALSE; 8788 } 8789 } 8790 if (generate_ebd) { 8791 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); 8792 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 8793 psource_frame = NULL; 8794 8795 if (m_input_pending_q.m_size) { 8796 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 8797 m_input_pending_q.pop_entry(&address,&p2,&id); 8798 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 8799 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 8800 psource_frame->nTimeStamp); 8801 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 8802 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 8803 } 8804 } 8805 } 8806 return OMX_ErrorNone; 8807 } 8808 8809 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 8810 { 8811 OMX_U32 partial_frame = 1; 8812 unsigned long address = 0, p2 = 0, id = 0; 8813 OMX_BOOL isNewFrame = OMX_FALSE; 8814 OMX_BOOL generate_ebd = OMX_TRUE; 8815 8816 if (h264_scratch.pBuffer == NULL) { 8817 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated"); 8818 return OMX_ErrorBadParameter; 8819 } 8820 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u " 8821 "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal); 8822 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen); 8823 if (h264_scratch.nFilledLen && look_ahead_nal) { 8824 look_ahead_nal = false; 8825 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 8826 h264_scratch.nFilledLen) { 8827 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 8828 h264_scratch.pBuffer,h264_scratch.nFilledLen); 8829 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 8830 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); 8831 h264_scratch.nFilledLen = 0; 8832 } else { 8833 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264"); 8834 return OMX_ErrorBadParameter; 8835 } 8836 } 8837 8838 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result 8839 in EOS flag getting associated with the destination 8840 */ 8841 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) && 8842 pdest_frame->nFilledLen) { 8843 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'"); 8844 generate_ebd = OMX_FALSE; 8845 } 8846 8847 if (nal_length == 0) { 8848 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); 8849 if (m_frame_parser.parse_sc_frame(psource_frame, 8850 &h264_scratch,&partial_frame) == -1) { 8851 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 8852 return OMX_ErrorBadParameter; 8853 } 8854 } else { 8855 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); 8856 if (m_frame_parser.parse_h264_nallength(psource_frame, 8857 &h264_scratch,&partial_frame) == -1) { 8858 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 8859 return OMX_ErrorBadParameter; 8860 } 8861 } 8862 8863 if (partial_frame == 0) { 8864 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 8865 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 8866 nal_count++; 8867 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 8868 h264_scratch.nFlags = psource_frame->nFlags; 8869 } else { 8870 DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen); 8871 if (h264_scratch.nFilledLen) { 8872 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, 8873 NALU_TYPE_SPS); 8874 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 8875 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 8876 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 8877 h264_scratch.nFilledLen, NALU_TYPE_SEI); 8878 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 8879 // If timeinfo is present frame info from SEI is already processed 8880 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 8881 h264_scratch.nFilledLen, NALU_TYPE_SEI); 8882 #endif 8883 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 8884 nal_count++; 8885 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { 8886 pdest_frame->nTimeStamp = h264_last_au_ts; 8887 pdest_frame->nFlags = h264_last_au_flags; 8888 #ifdef PANSCAN_HDLR 8889 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 8890 h264_parser->update_panscan_data(h264_last_au_ts); 8891 #endif 8892 } 8893 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || 8894 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { 8895 h264_last_au_ts = h264_scratch.nTimeStamp; 8896 h264_last_au_flags = h264_scratch.nFlags; 8897 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 8898 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 8899 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); 8900 if (!VALID_TS(h264_last_au_ts)) 8901 h264_last_au_ts = ts_in_sei; 8902 } 8903 #endif 8904 } else 8905 h264_last_au_ts = LLONG_MAX; 8906 } 8907 8908 if (!isNewFrame) { 8909 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 8910 h264_scratch.nFilledLen) { 8911 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u", 8912 (unsigned int)h264_scratch.nFilledLen); 8913 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 8914 h264_scratch.pBuffer,h264_scratch.nFilledLen); 8915 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 8916 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) 8917 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 8918 h264_scratch.nFilledLen = 0; 8919 } else { 8920 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264"); 8921 return OMX_ErrorBadParameter; 8922 } 8923 } else if(h264_scratch.nFilledLen) { 8924 look_ahead_nal = true; 8925 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu", 8926 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 8927 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 8928 (unsigned int)pdest_frame->nFilledLen,frame_count++); 8929 8930 if (pdest_frame->nFilledLen == 0) { 8931 DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); 8932 look_ahead_nal = false; 8933 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 8934 h264_scratch.nFilledLen) { 8935 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 8936 h264_scratch.pBuffer,h264_scratch.nFilledLen); 8937 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 8938 h264_scratch.nFilledLen = 0; 8939 } else { 8940 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264"); 8941 return OMX_ErrorBadParameter; 8942 } 8943 } else { 8944 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 8945 DEBUG_PRINT_LOW("Reset the EOS Flag"); 8946 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 8947 } 8948 /*Push the frame to the Decoder*/ 8949 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 8950 return OMX_ErrorBadParameter; 8951 } 8952 //frame_count++; 8953 pdest_frame = NULL; 8954 if (m_input_free_q.m_size) { 8955 m_input_free_q.pop_entry(&address,&p2,&id); 8956 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 8957 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); 8958 pdest_frame->nFilledLen = 0; 8959 pdest_frame->nFlags = 0; 8960 pdest_frame->nTimeStamp = LLONG_MAX; 8961 } 8962 } 8963 } 8964 } 8965 } else { 8966 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen); 8967 /*Check if Destination Buffer is full*/ 8968 if (h264_scratch.nAllocLen == 8969 h264_scratch.nFilledLen + h264_scratch.nOffset) { 8970 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 8971 return OMX_ErrorStreamCorrupt; 8972 } 8973 } 8974 8975 if (!psource_frame->nFilledLen) { 8976 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); 8977 8978 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 8979 if (pdest_frame) { 8980 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 8981 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 8982 h264_scratch.nFilledLen) { 8983 if(pdest_frame->nFilledLen == 0) { 8984 /* No residual frame from before, send whatever 8985 * we have left */ 8986 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen), 8987 h264_scratch.pBuffer, h264_scratch.nFilledLen); 8988 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 8989 h264_scratch.nFilledLen = 0; 8990 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 8991 } else { 8992 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 8993 if(!isNewFrame) { 8994 /* Have a residual frame, but we know that the 8995 * AU in this frame is belonging to whatever 8996 * frame we had left over. So append it */ 8997 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 8998 h264_scratch.pBuffer,h264_scratch.nFilledLen); 8999 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9000 h264_scratch.nFilledLen = 0; 9001 if (h264_last_au_ts != LLONG_MAX) 9002 pdest_frame->nTimeStamp = h264_last_au_ts; 9003 } else { 9004 /* Completely new frame, let's just push what 9005 * we have now. The resulting EBD would trigger 9006 * another push */ 9007 generate_ebd = OMX_FALSE; 9008 pdest_frame->nTimeStamp = h264_last_au_ts; 9009 h264_last_au_ts = h264_scratch.nTimeStamp; 9010 } 9011 } 9012 } else { 9013 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264"); 9014 return OMX_ErrorBadParameter; 9015 } 9016 9017 /* Iff we coalesced two buffers, inherit the flags of both bufs */ 9018 if(generate_ebd == OMX_TRUE) { 9019 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 9020 } 9021 9022 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu", 9023 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9024 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); 9025 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9026 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 9027 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); 9028 if (!VALID_TS(pdest_frame->nTimeStamp)) 9029 pdest_frame->nTimeStamp = ts_in_sei; 9030 } 9031 #endif 9032 /*Push the frame to the Decoder*/ 9033 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9034 return OMX_ErrorBadParameter; 9035 } 9036 frame_count++; 9037 pdest_frame = NULL; 9038 } else { 9039 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 9040 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 9041 generate_ebd = OMX_FALSE; 9042 } 9043 } 9044 } 9045 if (generate_ebd && !psource_frame->nFilledLen) { 9046 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 9047 psource_frame = NULL; 9048 if (m_input_pending_q.m_size) { 9049 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 9050 m_input_pending_q.pop_entry(&address,&p2,&id); 9051 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 9052 DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u", 9053 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9054 } 9055 } 9056 return OMX_ErrorNone; 9057 } 9058 9059 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) 9060 { 9061 OMX_ERRORTYPE rc = OMX_ErrorNone; 9062 if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) { 9063 memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); 9064 if (pDst->nTimeStamp == LLONG_MAX) { 9065 pDst->nTimeStamp = pSrc->nTimeStamp; 9066 DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp); 9067 } 9068 pDst->nFilledLen += pSrc->nFilledLen; 9069 pSrc->nFilledLen = 0; 9070 } else { 9071 DEBUG_PRINT_ERROR("Error: Destination buffer overflow"); 9072 rc = OMX_ErrorBadParameter; 9073 } 9074 return rc; 9075 } 9076 9077 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp) 9078 { 9079 OMX_U32 partial_frame = 1; 9080 unsigned long address,p2,id; 9081 OMX_BOOL isNewFrame = OMX_FALSE; 9082 OMX_BOOL generate_ebd = OMX_TRUE; 9083 OMX_ERRORTYPE rc = OMX_ErrorNone; 9084 if (h264_scratch.pBuffer == NULL) { 9085 DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated"); 9086 return OMX_ErrorBadParameter; 9087 } 9088 9089 DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \ 9090 pdest_frame nFilledLen %u nTimeStamp %lld", 9091 (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9092 9093 if (h264_scratch.nFilledLen && look_ahead_nal) { 9094 look_ahead_nal = false; 9095 rc = copy_buffer(pdest_frame, &h264_scratch); 9096 if (rc != OMX_ErrorNone) { 9097 return rc; 9098 } 9099 } 9100 9101 if (nal_length == 0) { 9102 if (m_frame_parser.parse_sc_frame(psource_frame, 9103 &h264_scratch,&partial_frame) == -1) { 9104 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9105 return OMX_ErrorBadParameter; 9106 } 9107 } else { 9108 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length); 9109 if (m_frame_parser.parse_h264_nallength(psource_frame, 9110 &h264_scratch,&partial_frame) == -1) { 9111 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 9112 return OMX_ErrorBadParameter; 9113 } 9114 } 9115 9116 if (partial_frame == 0) { 9117 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 9118 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 9119 nal_count++; 9120 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 9121 h264_scratch.nFlags = psource_frame->nFlags; 9122 } else { 9123 DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen); 9124 if (h264_scratch.nFilledLen) { 9125 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame); 9126 nal_count++; 9127 } 9128 9129 if (!isNewFrame) { 9130 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \ 9131 nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld", 9132 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp, 9133 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9134 rc = copy_buffer(pdest_frame, &h264_scratch); 9135 if (rc != OMX_ErrorNone) { 9136 return rc; 9137 } 9138 } else { 9139 look_ahead_nal = true; 9140 if (pdest_frame->nFilledLen == 0) { 9141 look_ahead_nal = false; 9142 DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer"); 9143 rc = copy_buffer(pdest_frame, &h264_scratch); 9144 if (rc != OMX_ErrorNone) { 9145 return OMX_ErrorBadParameter; 9146 } 9147 } else { 9148 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 9149 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9150 } 9151 DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \ 9152 nTimeStamp %lld, look_ahead_nal in h264_scratch \ 9153 nFilledLen %u nTimeStamp %lld", 9154 frame_count++, (unsigned int)pdest_frame->nFilledLen, 9155 pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen, 9156 h264_scratch.nTimeStamp); 9157 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 9158 return OMX_ErrorBadParameter; 9159 } 9160 pdest_frame = NULL; 9161 if (m_input_free_q.m_size) { 9162 m_input_free_q.pop_entry(&address, &p2, &id); 9163 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9164 DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame); 9165 pdest_frame->nFilledLen = 0; 9166 pdest_frame->nFlags = 0; 9167 pdest_frame->nTimeStamp = LLONG_MAX; 9168 } 9169 } 9170 } 9171 } 9172 } else { 9173 DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \ 9174 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \ 9175 nFilledLen %u nTimeStamp %lld", 9176 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp, 9177 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp, 9178 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp); 9179 9180 if (h264_scratch.nAllocLen == 9181 h264_scratch.nFilledLen + h264_scratch.nOffset) { 9182 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 9183 return OMX_ErrorStreamCorrupt; 9184 } 9185 } 9186 9187 if (!psource_frame->nFilledLen) { 9188 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame); 9189 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9190 if (pdest_frame) { 9191 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 9192 rc = copy_buffer(pdest_frame, &h264_scratch); 9193 if ( rc != OMX_ErrorNone ) { 9194 return rc; 9195 } 9196 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 9197 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 9198 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld", 9199 frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9200 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 9201 return OMX_ErrorBadParameter; 9202 } 9203 frame_count++; 9204 pdest_frame = NULL; 9205 } else { 9206 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 9207 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 9208 generate_ebd = OMX_FALSE; 9209 } 9210 } 9211 } 9212 9213 if (generate_ebd && !psource_frame->nFilledLen) { 9214 m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame); 9215 psource_frame = NULL; 9216 if (m_input_pending_q.m_size) { 9217 m_input_pending_q.pop_entry(&address, &p2, &id); 9218 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 9219 DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld", 9220 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp); 9221 } 9222 } 9223 return OMX_ErrorNone; 9224 } 9225 9226 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp) 9227 { 9228 OMX_U8 *buf, *pdest; 9229 OMX_U32 partial_frame = 1; 9230 OMX_U32 buf_len, dest_len; 9231 9232 if (first_frame == 0) { 9233 first_frame = 1; 9234 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); 9235 if (!m_vendor_config.pData) { 9236 DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); 9237 buf = psource_frame->pBuffer; 9238 buf_len = psource_frame->nFilledLen; 9239 9240 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 9241 VC1_SP_MP_START_CODE) { 9242 m_vc1_profile = VC1_SP_MP_RCV; 9243 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) { 9244 m_vc1_profile = VC1_AP; 9245 } else { 9246 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer"); 9247 return OMX_ErrorStreamCorrupt; 9248 } 9249 } else { 9250 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 9251 pdest_frame->nOffset; 9252 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 9253 pdest_frame->nOffset); 9254 9255 if (dest_len < m_vendor_config.nDataSize) { 9256 DEBUG_PRINT_ERROR("Destination buffer full"); 9257 return OMX_ErrorBadParameter; 9258 } else { 9259 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 9260 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 9261 } 9262 } 9263 } 9264 9265 switch (m_vc1_profile) { 9266 case VC1_AP: 9267 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); 9268 if (push_input_sc_codec(hComp) != OMX_ErrorNone) { 9269 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code"); 9270 return OMX_ErrorBadParameter; 9271 } 9272 break; 9273 9274 case VC1_SP_MP_RCV: 9275 default: 9276 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode"); 9277 return OMX_ErrorBadParameter; 9278 } 9279 return OMX_ErrorNone; 9280 } 9281 9282 #ifndef USE_ION 9283 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 9284 OMX_U32 alignment) 9285 { 9286 struct pmem_allocation allocation; 9287 allocation.size = buffer_size; 9288 allocation.align = clip2(alignment); 9289 if (allocation.align < 4096) { 9290 allocation.align = 4096; 9291 } 9292 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) { 9293 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)", 9294 allocation.align, allocation.size); 9295 return false; 9296 } 9297 return true; 9298 } 9299 #endif 9300 #ifdef USE_ION 9301 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, 9302 OMX_U32 alignment, struct ion_allocation_data *alloc_data, 9303 struct ion_fd_data *fd_data, int flag) 9304 { 9305 int fd = -EINVAL; 9306 int rc = -EINVAL; 9307 int ion_dev_flag; 9308 struct vdec_ion ion_buf_info; 9309 if (!alloc_data || buffer_size <= 0 || !fd_data) { 9310 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory"); 9311 return -EINVAL; 9312 } 9313 ion_dev_flag = O_RDONLY; 9314 fd = open (MEM_DEVICE, ion_dev_flag); 9315 if (fd < 0) { 9316 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd); 9317 return fd; 9318 } 9319 9320 alloc_data->flags = flag; 9321 alloc_data->len = buffer_size; 9322 alloc_data->align = clip2(alignment); 9323 if (alloc_data->align < 4096) { 9324 alloc_data->align = 4096; 9325 } 9326 9327 alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID); 9328 if (secure_mode && (alloc_data->flags & ION_SECURE)) { 9329 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 9330 } 9331 9332 /* Use secure display cma heap for obvious reasons. */ 9333 if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) { 9334 alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID); 9335 } 9336 9337 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); 9338 if (rc || !alloc_data->handle) { 9339 DEBUG_PRINT_ERROR("ION ALLOC memory failed"); 9340 alloc_data->handle = 0; 9341 close(fd); 9342 fd = -ENOMEM; 9343 return fd; 9344 } 9345 fd_data->handle = alloc_data->handle; 9346 rc = ioctl(fd,ION_IOC_MAP,fd_data); 9347 if (rc) { 9348 DEBUG_PRINT_ERROR("ION MAP failed "); 9349 ion_buf_info.ion_alloc_data = *alloc_data; 9350 ion_buf_info.ion_device_fd = fd; 9351 ion_buf_info.fd_ion_data = *fd_data; 9352 free_ion_memory(&ion_buf_info); 9353 fd_data->fd =-1; 9354 fd = -ENOMEM; 9355 } 9356 9357 return fd; 9358 } 9359 9360 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) 9361 { 9362 9363 if (!buf_ion_info) { 9364 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata"); 9365 return; 9366 } 9367 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 9368 &buf_ion_info->ion_alloc_data.handle)) { 9369 DEBUG_PRINT_ERROR("ION: free failed" ); 9370 } 9371 close(buf_ion_info->ion_device_fd); 9372 buf_ion_info->ion_device_fd = -1; 9373 buf_ion_info->ion_alloc_data.handle = 0; 9374 buf_ion_info->fd_ion_data.fd = -1; 9375 } 9376 #endif 9377 void omx_vdec::free_output_buffer_header() 9378 { 9379 DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); 9380 output_use_buffer = false; 9381 ouput_egl_buffers = false; 9382 9383 if (m_out_mem_ptr) { 9384 free (m_out_mem_ptr); 9385 m_out_mem_ptr = NULL; 9386 } 9387 9388 if (m_platform_list) { 9389 free(m_platform_list); 9390 m_platform_list = NULL; 9391 } 9392 9393 if (drv_ctx.ptr_respbuffer) { 9394 free (drv_ctx.ptr_respbuffer); 9395 drv_ctx.ptr_respbuffer = NULL; 9396 } 9397 if (drv_ctx.ptr_outputbuffer) { 9398 free (drv_ctx.ptr_outputbuffer); 9399 drv_ctx.ptr_outputbuffer = NULL; 9400 } 9401 #ifdef USE_ION 9402 if (drv_ctx.op_buf_ion_info) { 9403 DEBUG_PRINT_LOW("Free o/p ion context"); 9404 free(drv_ctx.op_buf_ion_info); 9405 drv_ctx.op_buf_ion_info = NULL; 9406 } 9407 #endif 9408 buf_ref_remove(); 9409 } 9410 9411 void omx_vdec::free_input_buffer_header() 9412 { 9413 input_use_buffer = false; 9414 if (arbitrary_bytes) { 9415 if (m_inp_heap_ptr) { 9416 DEBUG_PRINT_LOW("Free input Heap Pointer"); 9417 free (m_inp_heap_ptr); 9418 m_inp_heap_ptr = NULL; 9419 } 9420 9421 if (m_phdr_pmem_ptr) { 9422 DEBUG_PRINT_LOW("Free input pmem header Pointer"); 9423 free (m_phdr_pmem_ptr); 9424 m_phdr_pmem_ptr = NULL; 9425 } 9426 } 9427 if (m_inp_mem_ptr) { 9428 DEBUG_PRINT_LOW("Free input pmem Pointer area"); 9429 free (m_inp_mem_ptr); 9430 m_inp_mem_ptr = NULL; 9431 } 9432 /* We just freed all the buffer headers, every thing in m_input_free_q, 9433 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */ 9434 while (m_input_free_q.m_size) { 9435 unsigned long address, p2, id; 9436 m_input_free_q.pop_entry(&address, &p2, &id); 9437 } 9438 while (m_input_pending_q.m_size) { 9439 unsigned long address, p2, id; 9440 m_input_pending_q.pop_entry(&address, &p2, &id); 9441 } 9442 pdest_frame = NULL; 9443 psource_frame = NULL; 9444 if (drv_ctx.ptr_inputbuffer) { 9445 DEBUG_PRINT_LOW("Free Driver Context pointer"); 9446 free (drv_ctx.ptr_inputbuffer); 9447 drv_ctx.ptr_inputbuffer = NULL; 9448 } 9449 #ifdef USE_ION 9450 if (drv_ctx.ip_buf_ion_info) { 9451 DEBUG_PRINT_LOW("Free ion context"); 9452 free(drv_ctx.ip_buf_ion_info); 9453 drv_ctx.ip_buf_ion_info = NULL; 9454 } 9455 #endif 9456 } 9457 9458 int omx_vdec::stream_off(OMX_U32 port) 9459 { 9460 enum v4l2_buf_type btype; 9461 int rc = 0; 9462 enum v4l2_ports v4l2_port = OUTPUT_PORT; 9463 9464 if (port == OMX_CORE_INPUT_PORT_INDEX) { 9465 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9466 v4l2_port = OUTPUT_PORT; 9467 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 9468 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9469 v4l2_port = CAPTURE_PORT; 9470 } else if (port == OMX_ALL) { 9471 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); 9472 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 9473 9474 if (!rc_input) 9475 return rc_input; 9476 else 9477 return rc_output; 9478 } 9479 9480 if (!streaming[v4l2_port]) { 9481 // already streamed off, warn and move on 9482 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," 9483 " which is already streamed off", v4l2_port); 9484 return 0; 9485 } 9486 9487 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); 9488 9489 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); 9490 if (rc) { 9491 /*TODO: How to handle this case */ 9492 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port); 9493 } else { 9494 streaming[v4l2_port] = false; 9495 } 9496 9497 return rc; 9498 } 9499 9500 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) 9501 { 9502 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9503 struct v4l2_requestbuffers bufreq; 9504 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0; 9505 unsigned int final_extra_data_size = 0; 9506 struct v4l2_format fmt; 9507 int ret = 0; 9508 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 9509 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 9510 bufreq.memory = V4L2_MEMORY_USERPTR; 9511 bufreq.count = 1; 9512 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 9513 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9514 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9515 fmt.fmt.pix_mp.pixelformat = output_capability; 9516 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 9517 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9518 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9519 fmt.fmt.pix_mp.pixelformat = capture_capability; 9520 } else { 9521 eRet = OMX_ErrorBadParameter; 9522 } 9523 if (eRet==OMX_ErrorNone) { 9524 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 9525 } 9526 if (ret) { 9527 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 9528 /*TODO: How to handle this case */ 9529 eRet = OMX_ErrorInsufficientResources; 9530 return eRet; 9531 } else { 9532 buffer_prop->actualcount = bufreq.count; 9533 buffer_prop->mincount = bufreq.count; 9534 DEBUG_PRINT_HIGH("Count = %d",bufreq.count); 9535 } 9536 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 9537 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 9538 9539 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 9540 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 9541 9542 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 9543 9544 update_resolution(fmt.fmt.pix_mp.width, 9545 fmt.fmt.pix_mp.height, 9546 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, 9547 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); 9548 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 9549 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; 9550 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); 9551 9552 if (ret) { 9553 /*TODO: How to handle this case */ 9554 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 9555 eRet = OMX_ErrorInsufficientResources; 9556 } else { 9557 int extra_idx = 0; 9558 9559 eRet = is_video_session_supported(); 9560 if (eRet) 9561 return eRet; 9562 9563 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 9564 buf_size = buffer_prop->buffer_size; 9565 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 9566 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 9567 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 9568 } else if (extra_idx >= VIDEO_MAX_PLANES) { 9569 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 9570 return OMX_ErrorBadParameter; 9571 } 9572 9573 default_extra_data_size = VENUS_EXTRADATA_SIZE( 9574 drv_ctx.video_resolution.frame_height, 9575 drv_ctx.video_resolution.frame_width); 9576 final_extra_data_size = extra_data_size > default_extra_data_size ? 9577 extra_data_size : default_extra_data_size; 9578 9579 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) & 9580 (~(buffer_prop->alignment - 1)); 9581 9582 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size; 9583 drv_ctx.extradata_info.count = buffer_prop->actualcount; 9584 drv_ctx.extradata_info.buffer_size = final_extra_data_size; 9585 if (!secure_mode) 9586 buf_size += final_extra_data_size; 9587 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 9588 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)", 9589 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size); 9590 if (extra_data_size) 9591 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)", 9592 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size); 9593 9594 if (in_reconfig) // BufReq will be set to driver when port is disabled 9595 buffer_prop->buffer_size = buf_size; 9596 else if (buf_size != buffer_prop->buffer_size) { 9597 buffer_prop->buffer_size = buf_size; 9598 eRet = set_buffer_req(buffer_prop); 9599 } 9600 } 9601 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)", 9602 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 9603 return eRet; 9604 } 9605 9606 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) 9607 { 9608 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9609 unsigned buf_size = 0; 9610 struct v4l2_format fmt; 9611 struct v4l2_requestbuffers bufreq; 9612 int ret; 9613 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)", 9614 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 9615 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 9616 if (buf_size != buffer_prop->buffer_size) { 9617 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)", 9618 (unsigned int)buffer_prop->buffer_size, buf_size); 9619 eRet = OMX_ErrorBadParameter; 9620 } else { 9621 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 9622 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 9623 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 9624 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size; 9625 9626 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 9627 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9628 fmt.fmt.pix_mp.pixelformat = output_capability; 9629 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 9630 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9631 fmt.fmt.pix_mp.pixelformat = capture_capability; 9632 } else { 9633 eRet = OMX_ErrorBadParameter; 9634 } 9635 9636 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 9637 if (ret) { 9638 /*TODO: How to handle this case */ 9639 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); 9640 eRet = OMX_ErrorInsufficientResources; 9641 } 9642 9643 bufreq.memory = V4L2_MEMORY_USERPTR; 9644 bufreq.count = buffer_prop->actualcount; 9645 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 9646 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9647 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 9648 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9649 } else { 9650 eRet = OMX_ErrorBadParameter; 9651 } 9652 9653 if (eRet==OMX_ErrorNone) { 9654 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 9655 } 9656 9657 if (ret) { 9658 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); 9659 /*TODO: How to handle this case */ 9660 eRet = OMX_ErrorInsufficientResources; 9661 } else if (bufreq.count < buffer_prop->actualcount) { 9662 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" 9663 " on v4l2 port %d to %d (prefers %d)", bufreq.type, 9664 buffer_prop->actualcount, bufreq.count); 9665 eRet = OMX_ErrorInsufficientResources; 9666 } else { 9667 if (!client_buffers.update_buffer_req()) { 9668 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); 9669 eRet = OMX_ErrorInsufficientResources; 9670 } 9671 } 9672 } 9673 return eRet; 9674 } 9675 9676 OMX_ERRORTYPE omx_vdec::update_picture_resolution() 9677 { 9678 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9679 return eRet; 9680 } 9681 9682 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 9683 { 9684 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9685 struct v4l2_format fmt; 9686 if (!portDefn) { 9687 return OMX_ErrorBadParameter; 9688 } 9689 DEBUG_PRINT_LOW("omx_vdec::update_portdef"); 9690 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 9691 portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 9692 portDefn->eDomain = OMX_PortDomainVideo; 9693 if (drv_ctx.frame_rate.fps_denominator > 0) 9694 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator / 9695 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format 9696 else { 9697 DEBUG_PRINT_ERROR("Error: Divide by zero"); 9698 return OMX_ErrorBadParameter; 9699 } 9700 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 9701 if (0 == portDefn->nPortIndex) { 9702 portDefn->eDir = OMX_DirInput; 9703 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; 9704 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; 9705 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; 9706 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 9707 portDefn->format.video.eCompressionFormat = eCompressionFormat; 9708 portDefn->bEnabled = m_inp_bEnabled; 9709 portDefn->bPopulated = m_inp_bPopulated; 9710 9711 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 9712 fmt.fmt.pix_mp.pixelformat = output_capability; 9713 } else if (1 == portDefn->nPortIndex) { 9714 unsigned int buf_size = 0; 9715 if (!client_buffers.update_buffer_req()) { 9716 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed"); 9717 return OMX_ErrorHardware; 9718 } 9719 if (!client_buffers.get_buffer_req(buf_size)) { 9720 DEBUG_PRINT_ERROR("update buffer requirements"); 9721 return OMX_ErrorHardware; 9722 } 9723 portDefn->nBufferSize = buf_size; 9724 portDefn->eDir = OMX_DirOutput; 9725 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; 9726 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; 9727 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 9728 portDefn->bEnabled = m_out_bEnabled; 9729 portDefn->bPopulated = m_out_bPopulated; 9730 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { 9731 DEBUG_PRINT_ERROR("Error in getting color format"); 9732 return OMX_ErrorHardware; 9733 } 9734 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 9735 fmt.fmt.pix_mp.pixelformat = capture_capability; 9736 } else { 9737 portDefn->eDir = OMX_DirMax; 9738 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 9739 (int)portDefn->nPortIndex); 9740 eRet = OMX_ErrorBadPortIndex; 9741 } 9742 if (is_down_scalar_enabled) { 9743 int ret = 0; 9744 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 9745 if (ret) { 9746 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution"); 9747 return OMX_ErrorHardware; 9748 } else { 9749 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width; 9750 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height; 9751 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline; 9752 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0]; 9753 } 9754 } else { 9755 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; 9756 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; 9757 portDefn->format.video.nStride = drv_ctx.video_resolution.stride; 9758 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; 9759 } 9760 9761 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) || 9762 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) { 9763 portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16); 9764 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height; 9765 } 9766 DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d " 9767 "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u", 9768 (unsigned int)portDefn->nPortIndex, 9769 (unsigned int)portDefn->format.video.nFrameWidth, 9770 (unsigned int)portDefn->format.video.nFrameHeight, 9771 (int)portDefn->format.video.nStride, 9772 (unsigned int)portDefn->format.video.nSliceHeight, 9773 (unsigned int)portDefn->format.video.eColorFormat, 9774 (unsigned int)portDefn->nBufferSize, 9775 (unsigned int)portDefn->nBufferCountActual); 9776 9777 return eRet; 9778 } 9779 9780 OMX_ERRORTYPE omx_vdec::allocate_output_headers() 9781 { 9782 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9783 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 9784 unsigned i= 0; 9785 9786 if (!m_out_mem_ptr) { 9787 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); 9788 int nBufHdrSize = 0; 9789 int nPlatformEntrySize = 0; 9790 int nPlatformListSize = 0; 9791 int nPMEMInfoSize = 0; 9792 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 9793 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 9794 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 9795 9796 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", 9797 drv_ctx.op_buf.actualcount); 9798 nBufHdrSize = drv_ctx.op_buf.actualcount * 9799 sizeof(OMX_BUFFERHEADERTYPE); 9800 9801 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 9802 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 9803 nPlatformListSize = drv_ctx.op_buf.actualcount * 9804 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 9805 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 9806 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 9807 9808 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 9809 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 9810 nPMEMInfoSize, 9811 nPlatformListSize); 9812 DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize, 9813 m_out_bm_count); 9814 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 9815 // Alloc mem for platform specific info 9816 char *pPtr=NULL; 9817 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 9818 nPMEMInfoSize,1); 9819 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 9820 calloc (sizeof(struct vdec_bufferpayload), 9821 drv_ctx.op_buf.actualcount); 9822 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 9823 calloc (sizeof (struct vdec_output_frameinfo), 9824 drv_ctx.op_buf.actualcount); 9825 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 9826 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer"); 9827 return OMX_ErrorInsufficientResources; 9828 } 9829 9830 #ifdef USE_ION 9831 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ 9832 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); 9833 if (!drv_ctx.op_buf_ion_info) { 9834 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 9835 return OMX_ErrorInsufficientResources; 9836 } 9837 #endif 9838 if (dynamic_buf_mode) { 9839 out_dynamic_list = (struct dynamic_buf_list *) \ 9840 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount); 9841 if (out_dynamic_list) { 9842 for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++) 9843 out_dynamic_list[i].dup_fd = -1; 9844 } 9845 } 9846 9847 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 9848 && drv_ctx.ptr_respbuffer) { 9849 bufHdr = m_out_mem_ptr; 9850 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 9851 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 9852 (((char *) m_platform_list) + nPlatformListSize); 9853 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 9854 (((char *) m_platform_entry) + nPlatformEntrySize); 9855 pPlatformList = m_platform_list; 9856 pPlatformEntry = m_platform_entry; 9857 pPMEMInfo = m_pmem_info; 9858 9859 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 9860 9861 // Settting the entire storage nicely 9862 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, 9863 m_out_mem_ptr,pPlatformEntry); 9864 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 9865 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 9866 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 9867 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 9868 // Set the values when we determine the right HxW param 9869 bufHdr->nAllocLen = 0; 9870 bufHdr->nFilledLen = 0; 9871 bufHdr->pAppPrivate = NULL; 9872 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 9873 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 9874 pPlatformEntry->entry = pPMEMInfo; 9875 // Initialize the Platform List 9876 pPlatformList->nEntries = 1; 9877 pPlatformList->entryList = pPlatformEntry; 9878 // Keep pBuffer NULL till vdec is opened 9879 bufHdr->pBuffer = NULL; 9880 pPMEMInfo->offset = 0; 9881 pPMEMInfo->pmem_fd = -1; 9882 bufHdr->pPlatformPrivate = pPlatformList; 9883 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 9884 #ifdef USE_ION 9885 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 9886 #endif 9887 /*Create a mapping between buffers*/ 9888 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 9889 drv_ctx.ptr_respbuffer[i].client_data = (void *) \ 9890 &drv_ctx.ptr_outputbuffer[i]; 9891 // Move the buffer and buffer header pointers 9892 bufHdr++; 9893 pPMEMInfo++; 9894 pPlatformEntry++; 9895 pPlatformList++; 9896 } 9897 } else { 9898 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 9899 m_out_mem_ptr, pPtr); 9900 if (m_out_mem_ptr) { 9901 free(m_out_mem_ptr); 9902 m_out_mem_ptr = NULL; 9903 } 9904 if (pPtr) { 9905 free(pPtr); 9906 pPtr = NULL; 9907 } 9908 if (drv_ctx.ptr_outputbuffer) { 9909 free(drv_ctx.ptr_outputbuffer); 9910 drv_ctx.ptr_outputbuffer = NULL; 9911 } 9912 if (drv_ctx.ptr_respbuffer) { 9913 free(drv_ctx.ptr_respbuffer); 9914 drv_ctx.ptr_respbuffer = NULL; 9915 } 9916 #ifdef USE_ION 9917 if (drv_ctx.op_buf_ion_info) { 9918 DEBUG_PRINT_LOW("Free o/p ion context"); 9919 free(drv_ctx.op_buf_ion_info); 9920 drv_ctx.op_buf_ion_info = NULL; 9921 } 9922 #endif 9923 eRet = OMX_ErrorInsufficientResources; 9924 } 9925 } else { 9926 eRet = OMX_ErrorInsufficientResources; 9927 } 9928 return eRet; 9929 } 9930 9931 void omx_vdec::complete_pending_buffer_done_cbs() 9932 { 9933 unsigned long p1, p2, ident; 9934 omx_cmd_queue tmp_q, pending_bd_q; 9935 pthread_mutex_lock(&m_lock); 9936 // pop all pending GENERATE FDB from ftb queue 9937 while (m_ftb_q.m_size) { 9938 m_ftb_q.pop_entry(&p1,&p2,&ident); 9939 if (ident == OMX_COMPONENT_GENERATE_FBD) { 9940 pending_bd_q.insert_entry(p1,p2,ident); 9941 } else { 9942 tmp_q.insert_entry(p1,p2,ident); 9943 } 9944 } 9945 //return all non GENERATE FDB to ftb queue 9946 while (tmp_q.m_size) { 9947 tmp_q.pop_entry(&p1,&p2,&ident); 9948 m_ftb_q.insert_entry(p1,p2,ident); 9949 } 9950 // pop all pending GENERATE EDB from etb queue 9951 while (m_etb_q.m_size) { 9952 m_etb_q.pop_entry(&p1,&p2,&ident); 9953 if (ident == OMX_COMPONENT_GENERATE_EBD) { 9954 pending_bd_q.insert_entry(p1,p2,ident); 9955 } else { 9956 tmp_q.insert_entry(p1,p2,ident); 9957 } 9958 } 9959 //return all non GENERATE FDB to etb queue 9960 while (tmp_q.m_size) { 9961 tmp_q.pop_entry(&p1,&p2,&ident); 9962 m_etb_q.insert_entry(p1,p2,ident); 9963 } 9964 pthread_mutex_unlock(&m_lock); 9965 // process all pending buffer dones 9966 while (pending_bd_q.m_size) { 9967 pending_bd_q.pop_entry(&p1,&p2,&ident); 9968 switch (ident) { 9969 case OMX_COMPONENT_GENERATE_EBD: 9970 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 9971 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); 9972 omx_report_error (); 9973 } 9974 break; 9975 9976 case OMX_COMPONENT_GENERATE_FBD: 9977 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 9978 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); 9979 omx_report_error (); 9980 } 9981 break; 9982 } 9983 } 9984 } 9985 9986 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) 9987 { 9988 OMX_U32 new_frame_interval = 0; 9989 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts 9990 && llabs(act_timestamp - prev_ts) > 2000) { 9991 new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ? 9992 llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual); 9993 if (new_frame_interval != frm_int || frm_int == 0) { 9994 frm_int = new_frame_interval; 9995 if (frm_int) { 9996 drv_ctx.frame_rate.fps_numerator = 1e6; 9997 drv_ctx.frame_rate.fps_denominator = frm_int; 9998 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", 9999 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 10000 (float)drv_ctx.frame_rate.fps_denominator); 10001 m_perf_control.request_cores(frm_int); 10002 /* We need to report the difference between this FBD and the previous FBD 10003 * back to the driver for clock scaling purposes. */ 10004 struct v4l2_outputparm oparm; 10005 /*XXX: we're providing timing info as seconds per frame rather than frames 10006 * per second.*/ 10007 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 10008 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 10009 10010 struct v4l2_streamparm sparm; 10011 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10012 sparm.parm.output = oparm; 10013 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 10014 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 10015 performance might be affected"); 10016 } 10017 10018 } 10019 } 10020 } 10021 prev_ts = act_timestamp; 10022 } 10023 10024 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) 10025 { 10026 if (rst_prev_ts && VALID_TS(act_timestamp)) { 10027 prev_ts = act_timestamp; 10028 prev_ts_actual = act_timestamp; 10029 rst_prev_ts = false; 10030 } else if (VALID_TS(prev_ts)) { 10031 bool codec_cond = (drv_ctx.timestamp_adjust)? 10032 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) : 10033 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual); 10034 prev_ts_actual = act_timestamp; //unadjusted previous timestamp 10035 if (frm_int > 0 && codec_cond) { 10036 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); 10037 act_timestamp = prev_ts + frm_int; 10038 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); 10039 prev_ts = act_timestamp; 10040 } else { 10041 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) { 10042 // ensure that timestamps can never step backwards when in display order 10043 act_timestamp = prev_ts; 10044 } 10045 set_frame_rate(act_timestamp); 10046 } 10047 } else if (frm_int > 0) // In this case the frame rate was set along 10048 { // with the port definition, start ts with 0 10049 act_timestamp = prev_ts = 0; // and correct if a valid ts is received. 10050 rst_prev_ts = true; 10051 } 10052 } 10053 10054 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range, 10055 OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects) 10056 { 10057 switch (primaries) { 10058 case MSM_VIDC_BT709_5: 10059 *color_space = ITU_R_709; 10060 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 10061 break; 10062 case MSM_VIDC_BT470_6_M: 10063 aspects->mPrimaries = ColorAspects::PrimariesBT470_6M; 10064 break; 10065 case MSM_VIDC_BT601_6_625: 10066 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 10067 break; 10068 case MSM_VIDC_BT601_6_525: 10069 *color_space = range ? ITU_R_601_FR : ITU_R_601; 10070 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525; 10071 break; 10072 case MSM_VIDC_GENERIC_FILM: 10073 aspects->mPrimaries = ColorAspects::PrimariesGenericFilm; 10074 break; 10075 case MSM_VIDC_BT2020: 10076 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 10077 break; 10078 case MSM_VIDC_UNSPECIFIED: 10079 //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default 10080 default: 10081 //aspects->mPrimaries = ColorAspects::PrimariesOther; 10082 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10083 break; 10084 } 10085 10086 aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited; 10087 10088 switch (transfer) { 10089 case MSM_VIDC_TRANSFER_BT709_5: 10090 case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625: 10091 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10092 break; 10093 case MSM_VIDC_TRANSFER_BT_470_6_M: 10094 aspects->mTransfer = ColorAspects::TransferGamma22; 10095 break; 10096 case MSM_VIDC_TRANSFER_BT_470_6_BG: 10097 aspects->mTransfer = ColorAspects::TransferGamma28; 10098 break; 10099 case MSM_VIDC_TRANSFER_SMPTE_240M: 10100 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 10101 break; 10102 case MSM_VIDC_TRANSFER_LINEAR: 10103 aspects->mTransfer = ColorAspects::TransferLinear; 10104 break; 10105 case MSM_VIDC_TRANSFER_IEC_61966: 10106 aspects->mTransfer = ColorAspects::TransferXvYCC; 10107 break; 10108 case MSM_VIDC_TRANSFER_BT_1361: 10109 aspects->mTransfer = ColorAspects::TransferBT1361; 10110 break; 10111 case MSM_VIDC_TRANSFER_SRGB: 10112 aspects->mTransfer = ColorAspects::TransferSRGB; 10113 break; 10114 default: 10115 //aspects->mTransfer = ColorAspects::TransferOther; 10116 aspects->mTransfer = m_client_color_space.sAspects.mTransfer; 10117 break; 10118 } 10119 10120 switch (matrix) { 10121 case MSM_VIDC_MATRIX_BT_709_5: 10122 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10123 break; 10124 case MSM_VIDC_MATRIX_FCC_47: 10125 aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M; 10126 break; 10127 case MSM_VIDC_MATRIX_601_6_625: 10128 case MSM_VIDC_MATRIX_601_6_525: 10129 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 10130 break; 10131 case MSM_VIDC_MATRIX_SMPTE_240M: 10132 aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M; 10133 break; 10134 case MSM_VIDC_MATRIX_BT_2020: 10135 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 10136 break; 10137 case MSM_VIDC_MATRIX_BT_2020_CONST: 10138 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant; 10139 break; 10140 default: 10141 //aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 10142 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 10143 break; 10144 } 10145 } 10146 10147 void omx_vdec::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) { 10148 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d", 10149 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs); 10150 } 10151 10152 void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index) 10153 { 10154 ColorSpace_t color_space = ITU_R_601; 10155 ColorAspects tempAspects; 10156 memset(&tempAspects, 0x0, sizeof(ColorAspects)); 10157 ColorAspects *aspects = &tempAspects; 10158 10159 switch(output_capability) { 10160 case V4L2_PIX_FMT_MPEG2: 10161 { 10162 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload; 10163 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data; 10164 10165 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to 10166 * understand this code */ 10167 10168 if (seqdisp_payload && seqdisp_payload->color_descp) { 10169 10170 convert_color_space_info(seqdisp_payload->color_primaries, 1, 10171 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs, 10172 &color_space,aspects); 10173 m_disp_hor_size = seqdisp_payload->disp_width; 10174 m_disp_vert_size = seqdisp_payload->disp_height; 10175 } 10176 } 10177 break; 10178 case V4L2_PIX_FMT_H264: 10179 case V4L2_PIX_FMT_HEVC: 10180 { 10181 struct msm_vidc_vui_display_info_payload *display_info_payload; 10182 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data; 10183 10184 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */ 10185 10186 if (display_info_payload->video_signal_present_flag && 10187 display_info_payload->color_description_present_flag) { 10188 convert_color_space_info(display_info_payload->color_primaries, 10189 display_info_payload->video_full_range_flag, 10190 display_info_payload->transfer_characteristics, 10191 display_info_payload->matrix_coefficients, 10192 &color_space,aspects); 10193 } 10194 } 10195 break; 10196 case V4L2_PIX_FMT_VC1_ANNEX_G: 10197 case V4L2_PIX_FMT_VC1_ANNEX_L: 10198 { 10199 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload; 10200 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data; 10201 10202 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23 10203 * SMPTE 421M to understand this code */ 10204 10205 if (m_enable_android_native_buffers && 10206 vc1_seq_disp_payload->color_primaries) { 10207 10208 convert_color_space_info(vc1_seq_disp_payload->color_primaries, 10209 1, 10210 vc1_seq_disp_payload->transfer_char, 10211 vc1_seq_disp_payload->matrix_coeffs, 10212 &color_space,aspects); 10213 } 10214 } 10215 break; 10216 case V4L2_PIX_FMT_VP8: 10217 { 10218 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 10219 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 10220 10221 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011 10222 * to understand this code */ 10223 10224 if (vpx_color_space_payload->color_space == 0) { 10225 color_space = ITU_R_601; 10226 } else { 10227 DEBUG_PRINT_ERROR("Unsupported Color space for VP8"); 10228 break; 10229 } 10230 } 10231 break; 10232 case V4L2_PIX_FMT_VP9: 10233 { 10234 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 10235 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 10236 10237 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016 10238 * to understand this code */ 10239 10240 switch(vpx_color_space_payload->color_space) { 10241 case MSM_VIDC_CS_BT_601: 10242 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 10243 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10244 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 10245 aspects->mRange = m_client_color_space.sAspects.mRange; 10246 break; 10247 case MSM_VIDC_CS_BT_709: 10248 color_space = ITU_R_709; 10249 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10250 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10251 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 10252 aspects->mRange = m_client_color_space.sAspects.mRange; 10253 break; 10254 case MSM_VIDC_CS_SMPTE_170: 10255 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10256 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10257 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10258 aspects->mRange = m_client_color_space.sAspects.mRange; 10259 break; 10260 case MSM_VIDC_CS_SMPTE_240: 10261 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 10262 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 10263 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10264 aspects->mRange = m_client_color_space.sAspects.mRange; 10265 break; 10266 case MSM_VIDC_CS_BT_2020: 10267 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 10268 aspects->mTransfer = ColorAspects:: TransferSMPTE170M; 10269 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 10270 aspects->mRange = m_client_color_space.sAspects.mRange; 10271 break; 10272 case MSM_VIDC_CS_RESERVED: 10273 aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 10274 aspects->mTransfer = ColorAspects::TransferOther; 10275 aspects->mPrimaries = ColorAspects::PrimariesOther; 10276 aspects->mRange = m_client_color_space.sAspects.mRange; 10277 break; 10278 case MSM_VIDC_CS_RGB: 10279 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10280 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10281 aspects->mPrimaries = ColorAspects::PrimariesOther; 10282 aspects->mRange = m_client_color_space.sAspects.mRange; 10283 break; 10284 default: 10285 break; 10286 } 10287 } 10288 break; 10289 default: 10290 break; 10291 } 10292 if (m_enable_android_native_buffers) { 10293 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); 10294 set_colorspace_in_handle(color_space, buf_index); 10295 } 10296 print_debug_color_aspects(aspects, "Bitstream"); 10297 10298 if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries || 10299 m_internal_color_space.sAspects.mTransfer != aspects->mTransfer || 10300 m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs || 10301 m_internal_color_space.sAspects.mRange != aspects->mRange) { 10302 memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects)); 10303 m_internal_color_space.bDataSpaceChanged = OMX_TRUE; 10304 10305 DEBUG_PRINT_HIGH("Initiating PORT Reconfig"); 10306 print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal"); 10307 print_debug_color_aspects(&(m_client_color_space.sAspects), "Client"); 10308 10309 post_event(OMX_CORE_OUTPUT_PORT_INDEX, 10310 OMX_QTIIndexConfigDescribeColorAspects, 10311 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 10312 } 10313 } 10314 10315 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) { 10316 private_handle_t *private_handle = NULL; 10317 if (buf_index < drv_ctx.op_buf.actualcount && 10318 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 10319 native_buffer[buf_index].privatehandle) { 10320 private_handle = native_buffer[buf_index].privatehandle; 10321 } 10322 if (private_handle) { 10323 setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space); 10324 } 10325 } 10326 10327 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) 10328 { 10329 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; 10330 OMX_U32 num_conceal_MB = 0; 10331 OMX_TICKS time_stamp = 0; 10332 OMX_U32 frame_rate = 0; 10333 unsigned long consumed_len = 0; 10334 OMX_U32 num_MB_in_frame; 10335 OMX_U32 recovery_sei_flags = 1; 10336 int enable = 0; 10337 10338 int buf_index = p_buf_hdr - m_out_mem_ptr; 10339 if (buf_index >= drv_ctx.extradata_info.count) { 10340 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)", 10341 buf_index, drv_ctx.extradata_info.count); 10342 return; 10343 } 10344 struct msm_vidc_panscan_window_payload *panscan_payload = NULL; 10345 10346 if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) { 10347 DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL"); 10348 return; 10349 } 10350 10351 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + 10352 p_buf_hdr->nOffset; 10353 10354 if (!drv_ctx.extradata_info.uaddr) { 10355 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr"); 10356 return; 10357 } 10358 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) { 10359 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data"); 10360 p_extra = NULL; 10361 return; 10362 } 10363 if (!secure_mode) 10364 p_extra = (OMX_OTHER_EXTRADATATYPE *) 10365 ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); 10366 else 10367 p_extra = m_other_extradata; 10368 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; 10369 10370 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 10371 p_extra = NULL; 10372 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 10373 return; 10374 } 10375 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; 10376 if (data && p_extra) { 10377 while ((consumed_len < drv_ctx.extradata_info.buffer_size) 10378 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) { 10379 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) { 10380 DEBUG_PRINT_LOW("Invalid extra data size"); 10381 break; 10382 } 10383 10384 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 10385 p_extra = NULL; 10386 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 10387 return; 10388 } 10389 10390 DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType); 10391 switch ((unsigned long)data->eType) { 10392 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO: 10393 struct msm_vidc_interlace_payload *payload; 10394 OMX_U32 interlace_color_format; 10395 payload = (struct msm_vidc_interlace_payload *)(void *)data->data; 10396 if (payload) { 10397 enable = 1; 10398 switch (payload->format) { 10399 case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE: 10400 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 10401 enable = 0; 10402 break; 10403 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST: 10404 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 10405 break; 10406 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST: 10407 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst; 10408 break; 10409 default: 10410 DEBUG_PRINT_LOW("default case - set interlace to topfield"); 10411 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 10412 } 10413 switch (payload->color_format) { 10414 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12: 10415 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 10416 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 10417 break; 10418 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC: 10419 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 10420 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC; 10421 break; 10422 default: 10423 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 10424 DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame"); 10425 } 10426 } 10427 10428 if (m_enable_android_native_buffers) { 10429 DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d", 10430 payload->format, interlace_color_format ,enable, 10431 (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false); 10432 10433 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 10434 PP_PARAM_INTERLACED, (void*)&enable); 10435 10436 if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 10437 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 10438 LINEAR_FORMAT, (void*)&interlace_color_format); 10439 } 10440 } 10441 if (client_extradata & OMX_INTERLACE_EXTRADATA) { 10442 append_interlace_extradata(p_extra, payload->format, 10443 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF); 10444 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10445 } 10446 break; 10447 case MSM_VIDC_EXTRADATA_FRAME_RATE: 10448 struct msm_vidc_framerate_payload *frame_rate_payload; 10449 frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data; 10450 frame_rate = frame_rate_payload->frame_rate; 10451 break; 10452 case MSM_VIDC_EXTRADATA_TIMESTAMP: 10453 struct msm_vidc_ts_payload *time_stamp_payload; 10454 time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data; 10455 time_stamp = time_stamp_payload->timestamp_lo; 10456 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); 10457 p_buf_hdr->nTimeStamp = time_stamp; 10458 break; 10459 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB: 10460 struct msm_vidc_concealmb_payload *conceal_mb_payload; 10461 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data; 10462 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 10463 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 10464 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); 10465 break; 10466 case MSM_VIDC_EXTRADATA_INDEX: 10467 int *etype; 10468 etype = (int *)(void *)data->data; 10469 if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) { 10470 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; 10471 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype); 10472 if (aspect_ratio_payload) { 10473 ((struct vdec_output_frameinfo *) 10474 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; 10475 ((struct vdec_output_frameinfo *) 10476 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; 10477 } 10478 } 10479 break; 10480 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI: 10481 struct msm_vidc_recoverysei_payload *recovery_sei_payload; 10482 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data; 10483 recovery_sei_flags = recovery_sei_payload->flags; 10484 if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) { 10485 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 10486 DEBUG_PRINT_HIGH("***************************************************"); 10487 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 10488 DEBUG_PRINT_HIGH("***************************************************"); 10489 } 10490 break; 10491 case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW: 10492 panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data; 10493 if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) { 10494 DEBUG_PRINT_ERROR("Panscan windows are more than supported\n"); 10495 DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n", 10496 MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows); 10497 return; 10498 } 10499 break; 10500 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP: 10501 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO: 10502 case MSM_VIDC_EXTRADATA_VC1_SEQDISP: 10503 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO: 10504 handle_color_space_info((void *)data->data, buf_index); 10505 break; 10506 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING: 10507 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload; 10508 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data; 10509 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) { 10510 append_framepack_extradata(p_extra, s3d_frame_packing_payload); 10511 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10512 } 10513 break; 10514 case MSM_VIDC_EXTRADATA_FRAME_QP: 10515 struct msm_vidc_frame_qp_payload *qp_payload; 10516 qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data; 10517 if (client_extradata & OMX_QP_EXTRADATA) { 10518 append_qp_extradata(p_extra, qp_payload); 10519 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10520 } 10521 break; 10522 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO: 10523 struct msm_vidc_frame_bits_info_payload *bits_info_payload; 10524 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data; 10525 if (client_extradata & OMX_BITSINFO_EXTRADATA) { 10526 append_bitsinfo_extradata(p_extra, bits_info_payload); 10527 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10528 } 10529 break; 10530 case MSM_VIDC_EXTRADATA_STREAM_USERDATA: 10531 if (client_extradata & OMX_EXTNUSER_EXTRADATA) { 10532 append_user_extradata(p_extra, data); 10533 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10534 } 10535 break; 10536 case MSM_VIDC_EXTRADATA_VQZIP_SEI: 10537 struct msm_vidc_vqzip_sei_payload *vqzip_payload; 10538 vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data; 10539 if (client_extradata & OMX_VQZIPSEI_EXTRADATA) { 10540 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 10541 append_vqzip_extradata(p_extra, vqzip_payload); 10542 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10543 } 10544 break; 10545 default: 10546 DEBUG_PRINT_LOW("Unrecognized extradata"); 10547 goto unrecognized_extradata; 10548 } 10549 consumed_len += data->nSize; 10550 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 10551 } 10552 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) { 10553 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 10554 append_frame_info_extradata(p_extra, 10555 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 10556 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *) 10557 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 10558 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10559 } 10560 if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) { 10561 append_frame_dimension_extradata(p_extra); 10562 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 10563 } 10564 } 10565 unrecognized_extradata: 10566 if (client_extradata && p_extra) { 10567 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 10568 append_terminator_extradata(p_extra); 10569 } 10570 if (secure_mode && p_extradata && m_other_extradata) { 10571 struct vdec_output_frameinfo *ptr_extradatabuff = NULL; 10572 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size); 10573 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate; 10574 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata; 10575 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size; 10576 } 10577 return; 10578 } 10579 10580 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, 10581 bool is_internal, bool enable) 10582 { 10583 OMX_ERRORTYPE ret = OMX_ErrorNone; 10584 struct v4l2_control control; 10585 if (m_state != OMX_StateLoaded) { 10586 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); 10587 return OMX_ErrorIncorrectStateOperation; 10588 } 10589 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d", 10590 (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal); 10591 10592 if (!is_internal) { 10593 if (enable) 10594 client_extradata |= requested_extradata; 10595 else 10596 client_extradata = client_extradata & ~requested_extradata; 10597 } 10598 10599 if (enable) { 10600 if (requested_extradata & OMX_INTERLACE_EXTRADATA) { 10601 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10602 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; 10603 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10604 DEBUG_PRINT_HIGH("Failed to set interlaced extradata." 10605 " Quality of interlaced clips might be impacted."); 10606 } 10607 } 10608 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) { 10609 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10610 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; 10611 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10612 DEBUG_PRINT_HIGH("Failed to set framerate extradata"); 10613 } 10614 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10615 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; 10616 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10617 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata"); 10618 } 10619 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10620 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; 10621 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10622 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata"); 10623 } 10624 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10625 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; 10626 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10627 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 10628 } 10629 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10630 control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO; 10631 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10632 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 10633 } 10634 if (output_capability == V4L2_PIX_FMT_MPEG2) { 10635 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10636 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 10637 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10638 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 10639 } 10640 } 10641 } 10642 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) { 10643 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10644 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; 10645 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10646 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata"); 10647 } 10648 } 10649 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) { 10650 if (output_capability == V4L2_PIX_FMT_H264) { 10651 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA"); 10652 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10653 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING; 10654 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10655 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata"); 10656 } 10657 } else { 10658 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only"); 10659 } 10660 } 10661 if (requested_extradata & OMX_QP_EXTRADATA) { 10662 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10663 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 10664 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10665 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 10666 } 10667 } 10668 if (requested_extradata & OMX_BITSINFO_EXTRADATA) { 10669 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10670 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO; 10671 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10672 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata"); 10673 } 10674 } 10675 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) { 10676 if (secure_mode) { 10677 DEBUG_PRINT_HIGH("ExtnUser Extra Data not supported for secure sessions"); 10678 return OMX_ErrorUnsupportedSetting; 10679 } 10680 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10681 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA; 10682 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10683 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata"); 10684 } 10685 } 10686 if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) { 10687 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10688 control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI; 10689 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10690 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata"); 10691 } 10692 client_extradata |= OMX_VQZIPSEI_EXTRADATA; 10693 10694 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10695 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 10696 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10697 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 10698 } 10699 client_extradata |= OMX_QP_EXTRADATA; 10700 } 10701 if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) { 10702 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 10703 switch(output_capability) { 10704 case V4L2_PIX_FMT_H264: 10705 case V4L2_PIX_FMT_HEVC: 10706 control.value = V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY; 10707 break; 10708 case CODEC_TYPE_MPEG2: 10709 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 10710 break; 10711 case V4L2_PIX_FMT_VP8: 10712 case V4L2_PIX_FMT_VP9: 10713 control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE; 10714 break; 10715 case V4L2_PIX_FMT_VC1_ANNEX_G: 10716 case V4L2_PIX_FMT_VC1_ANNEX_L: 10717 control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP; 10718 break; 10719 default: 10720 DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind); 10721 return ret; 10722 } 10723 10724 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 10725 DEBUG_PRINT_HIGH("Failed to set Display info extradata"); 10726 } 10727 } 10728 } 10729 ret = get_buffer_req(&drv_ctx.op_buf); 10730 return ret; 10731 } 10732 10733 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) 10734 { 10735 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; 10736 OMX_U8 *data_ptr = extra->data, data = 0; 10737 while (byte_count < extra->nDataSize) { 10738 data = *data_ptr; 10739 while (data) { 10740 num_MB += (data&0x01); 10741 data >>= 1; 10742 } 10743 data_ptr++; 10744 byte_count++; 10745 } 10746 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 10747 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 10748 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); 10749 } 10750 10751 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) 10752 { 10753 if (!m_debug_extradata || !extra) 10754 return; 10755 10756 10757 DEBUG_PRINT_HIGH( 10758 "============== Extra Data ==============\n" 10759 " Size: %u\n" 10760 " Version: %u\n" 10761 " PortIndex: %u\n" 10762 " Type: %x\n" 10763 " DataSize: %u", 10764 (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion, 10765 (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize); 10766 10767 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) { 10768 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 10769 DEBUG_PRINT_HIGH( 10770 "------ Interlace Format ------\n" 10771 " Size: %u\n" 10772 " Version: %u\n" 10773 " PortIndex: %u\n" 10774 " Is Interlace Format: %d\n" 10775 " Interlace Formats: %u\n" 10776 "=========== End of Interlace ===========", 10777 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex, 10778 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats); 10779 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) { 10780 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 10781 10782 DEBUG_PRINT_HIGH( 10783 "-------- Frame Format --------\n" 10784 " Picture Type: %d\n" 10785 " Interlace Type: %d\n" 10786 " Pan Scan Total Frame Num: %u\n" 10787 " Concealed Macro Blocks: %u\n" 10788 " frame rate: %u\n" 10789 " Time Stamp: %llu\n" 10790 " Aspect Ratio X: %u\n" 10791 " Aspect Ratio Y: %u", 10792 fminfo->ePicType, 10793 fminfo->interlaceType, 10794 (unsigned int)fminfo->panScan.numWindows, 10795 (unsigned int)fminfo->nConcealedMacroblocks, 10796 (unsigned int)fminfo->nFrameRate, 10797 fminfo->nTimeStamp, 10798 (unsigned int)fminfo->aspectRatio.aspectRatioX, 10799 (unsigned int)fminfo->aspectRatio.aspectRatioY); 10800 10801 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) { 10802 DEBUG_PRINT_HIGH( 10803 "------------------------------" 10804 " Pan Scan Frame Num: %u\n" 10805 " Rectangle x: %d\n" 10806 " Rectangle y: %d\n" 10807 " Rectangle dx: %d\n" 10808 " Rectangle dy: %d", 10809 (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y, 10810 (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy); 10811 } 10812 10813 DEBUG_PRINT_HIGH("========= End of Frame Format =========="); 10814 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) { 10815 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 10816 DEBUG_PRINT_HIGH( 10817 "------------------ Framepack Format ----------\n" 10818 " id: %u \n" 10819 " cancel_flag: %u \n" 10820 " type: %u \n" 10821 " quincunx_sampling_flagFormat: %u \n" 10822 " content_interpretation_type: %u \n" 10823 " spatial_flipping_flag: %u \n" 10824 " frame0_flipped_flag: %u \n" 10825 " field_views_flag: %u \n" 10826 " current_frame_is_frame0_flag: %u \n" 10827 " frame0_self_contained_flag: %u \n" 10828 " frame1_self_contained_flag: %u \n" 10829 " frame0_grid_position_x: %u \n" 10830 " frame0_grid_position_y: %u \n" 10831 " frame1_grid_position_x: %u \n" 10832 " frame1_grid_position_y: %u \n" 10833 " reserved_byte: %u \n" 10834 " repetition_period: %u \n" 10835 " extension_flag: %u \n" 10836 "================== End of Framepack ===========", 10837 (unsigned int)framepack->id, 10838 (unsigned int)framepack->cancel_flag, 10839 (unsigned int)framepack->type, 10840 (unsigned int)framepack->quincunx_sampling_flag, 10841 (unsigned int)framepack->content_interpretation_type, 10842 (unsigned int)framepack->spatial_flipping_flag, 10843 (unsigned int)framepack->frame0_flipped_flag, 10844 (unsigned int)framepack->field_views_flag, 10845 (unsigned int)framepack->current_frame_is_frame0_flag, 10846 (unsigned int)framepack->frame0_self_contained_flag, 10847 (unsigned int)framepack->frame1_self_contained_flag, 10848 (unsigned int)framepack->frame0_grid_position_x, 10849 (unsigned int)framepack->frame0_grid_position_y, 10850 (unsigned int)framepack->frame1_grid_position_x, 10851 (unsigned int)framepack->frame1_grid_position_y, 10852 (unsigned int)framepack->reserved_byte, 10853 (unsigned int)framepack->repetition_period, 10854 (unsigned int)framepack->extension_flag); 10855 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) { 10856 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 10857 DEBUG_PRINT_HIGH( 10858 "---- QP (Frame quantization parameter) ----\n" 10859 " Frame QP: %u \n" 10860 "================ End of QP ================\n", 10861 (unsigned int)qp->nQP); 10862 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) { 10863 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data; 10864 DEBUG_PRINT_HIGH( 10865 "--------- Input bits information --------\n" 10866 " Header bits: %u \n" 10867 " Frame bits: %u \n" 10868 "===== End of Input bits information =====\n", 10869 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits); 10870 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) { 10871 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data; 10872 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data; 10873 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type); 10874 OMX_U32 i = 0; 10875 DEBUG_PRINT_HIGH( 10876 "-------------- Userdata -------------\n" 10877 " Stream userdata type: %u\n" 10878 " userdata size: %u\n" 10879 " STREAM_USERDATA:", 10880 (unsigned int)userdata->type, (unsigned int)userdata_size); 10881 for (i = 0; i < userdata_size; i+=4) { 10882 DEBUG_PRINT_HIGH(" %x %x %x %x", 10883 data_ptr[i], data_ptr[i+1], 10884 data_ptr[i+2], data_ptr[i+3]); 10885 } 10886 DEBUG_PRINT_HIGH( 10887 "=========== End of Userdata ==========="); 10888 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) { 10889 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 10890 DEBUG_PRINT_HIGH( 10891 "-------------- VQZip -------------\n" 10892 " Size: %u\n", 10893 (unsigned int)vq->nSize); 10894 DEBUG_PRINT_HIGH( "=========== End of VQZip ==========="); 10895 } else if (extra->eType == OMX_ExtraDataNone) { 10896 DEBUG_PRINT_HIGH("========== End of Terminator ==========="); 10897 } else { 10898 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); 10899 } 10900 } 10901 10902 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, 10903 OMX_U32 interlaced_format_type, bool is_mbaff) 10904 { 10905 OMX_STREAMINTERLACEFORMAT *interlace_format; 10906 10907 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { 10908 return; 10909 } 10910 if (!extra) { 10911 DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input"); 10912 return; 10913 } 10914 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; 10915 extra->nVersion.nVersion = OMX_SPEC_VERSION; 10916 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10917 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; 10918 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); 10919 interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 10920 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); 10921 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; 10922 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10923 10924 if ((interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) { 10925 interlace_format->bInterlaceFormat = OMX_FALSE; 10926 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 10927 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 10928 } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) { 10929 interlace_format->bInterlaceFormat = OMX_TRUE; 10930 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 10931 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 10932 } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) { 10933 interlace_format->bInterlaceFormat = OMX_TRUE; 10934 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst; 10935 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 10936 } else { 10937 interlace_format->bInterlaceFormat = OMX_TRUE; 10938 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 10939 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 10940 } 10941 print_debug_extradata(extra); 10942 } 10943 10944 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra) 10945 { 10946 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension; 10947 if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) { 10948 return; 10949 } 10950 extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE; 10951 extra->nVersion.nVersion = OMX_SPEC_VERSION; 10952 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10953 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension; 10954 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION); 10955 frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data; 10956 frame_dimension->nDecWidth = rectangle.nLeft; 10957 frame_dimension->nDecHeight = rectangle.nTop; 10958 frame_dimension->nActualWidth = rectangle.nWidth; 10959 frame_dimension->nActualHeight = rectangle.nHeight; 10960 } 10961 10962 void omx_vdec::fill_aspect_ratio_info( 10963 struct vdec_aspectratioinfo *aspect_ratio_info, 10964 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 10965 { 10966 m_extradata = frame_info; 10967 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; 10968 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; 10969 DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX, 10970 (unsigned int)m_extradata->aspectRatio.aspectRatioY); 10971 } 10972 10973 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, 10974 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, 10975 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload, 10976 struct vdec_aspectratioinfo *aspect_ratio_info) 10977 { 10978 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; 10979 struct msm_vidc_panscan_window *panscan_window; 10980 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { 10981 return; 10982 } 10983 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; 10984 extra->nVersion.nVersion = OMX_SPEC_VERSION; 10985 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10986 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; 10987 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); 10988 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 10989 switch (picture_type) { 10990 case PICTURE_TYPE_I: 10991 frame_info->ePicType = OMX_VIDEO_PictureTypeI; 10992 break; 10993 case PICTURE_TYPE_P: 10994 frame_info->ePicType = OMX_VIDEO_PictureTypeP; 10995 break; 10996 case PICTURE_TYPE_B: 10997 frame_info->ePicType = OMX_VIDEO_PictureTypeB; 10998 break; 10999 default: 11000 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; 11001 } 11002 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 11003 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 11004 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 11005 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 11006 else 11007 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; 11008 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); 11009 frame_info->nConcealedMacroblocks = num_conceal_mb; 11010 frame_info->nFrameRate = frame_rate; 11011 frame_info->nTimeStamp = time_stamp; 11012 frame_info->panScan.numWindows = 0; 11013 if (output_capability == V4L2_PIX_FMT_MPEG2) { 11014 if (m_disp_hor_size && m_disp_vert_size) { 11015 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; 11016 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; 11017 } else { 11018 frame_info->displayAspectRatio.displayHorizontalSize = 0; 11019 frame_info->displayAspectRatio.displayVerticalSize = 0; 11020 } 11021 } 11022 11023 if (panscan_payload) { 11024 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; 11025 panscan_window = &panscan_payload->wnd[0]; 11026 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) { 11027 frame_info->panScan.window[i].x = panscan_window->panscan_window_width; 11028 frame_info->panScan.window[i].y = panscan_window->panscan_window_height; 11029 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; 11030 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; 11031 panscan_window++; 11032 } 11033 } 11034 fill_aspect_ratio_info(aspect_ratio_info, frame_info); 11035 print_debug_extradata(extra); 11036 } 11037 11038 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11039 { 11040 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; 11041 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; 11042 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11043 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11044 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; 11045 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 11046 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data; 11047 *portDefn = m_port_def; 11048 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u " 11049 "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight, 11050 (unsigned int)portDefn->format.video.nFrameWidth, 11051 (unsigned int)portDefn->format.video.nStride, 11052 (unsigned int)portDefn->format.video.nSliceHeight); 11053 } 11054 11055 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11056 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload) 11057 { 11058 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack; 11059 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) { 11060 DEBUG_PRINT_ERROR("frame packing size mismatch"); 11061 return; 11062 } 11063 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE; 11064 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11065 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11066 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement; 11067 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 11068 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 11069 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 11070 framepack->nVersion.nVersion = OMX_SPEC_VERSION; 11071 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11072 memcpy(&framepack->id, s3d_frame_packing_payload, 11073 sizeof(struct msm_vidc_s3d_frame_packing_payload)); 11074 memcpy(&m_frame_pack_arrangement, framepack, 11075 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 11076 print_debug_extradata(extra); 11077 } 11078 11079 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11080 struct msm_vidc_frame_qp_payload *qp_payload) 11081 { 11082 OMX_QCOM_EXTRADATA_QP * qp = NULL; 11083 if (!qp_payload) { 11084 DEBUG_PRINT_ERROR("QP payload is NULL"); 11085 return; 11086 } 11087 extra->nSize = OMX_QP_EXTRADATA_SIZE; 11088 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11089 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11090 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP; 11091 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP); 11092 qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 11093 qp->nQP = qp_payload->frame_qp; 11094 print_debug_extradata(extra); 11095 } 11096 11097 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11098 struct msm_vidc_frame_bits_info_payload *bits_payload) 11099 { 11100 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL; 11101 if (!bits_payload) { 11102 DEBUG_PRINT_ERROR("bits info payload is NULL"); 11103 return; 11104 } 11105 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE; 11106 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11107 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11108 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo; 11109 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO); 11110 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data; 11111 bits->frame_bits = bits_payload->frame_bits; 11112 bits->header_bits = bits_payload->header_bits; 11113 print_debug_extradata(extra); 11114 } 11115 11116 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11117 OMX_OTHER_EXTRADATATYPE *p_user) 11118 { 11119 int userdata_size = 0; 11120 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL; 11121 userdata_payload = 11122 (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data; 11123 userdata_size = p_user->nDataSize; 11124 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size; 11125 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11126 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11127 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData; 11128 extra->nDataSize = userdata_size; 11129 if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize)) 11130 memcpy(extra->data, p_user->data, extra->nDataSize); 11131 print_debug_extradata(extra); 11132 } 11133 11134 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11135 { 11136 if (!client_extradata) { 11137 return; 11138 } 11139 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 11140 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11141 extra->eType = OMX_ExtraDataNone; 11142 extra->nDataSize = 0; 11143 extra->data[0] = 0; 11144 11145 print_debug_extradata(extra); 11146 } 11147 11148 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11149 struct msm_vidc_vqzip_sei_payload *vqzip_payload) 11150 { 11151 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL; 11152 11153 extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size; 11154 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11155 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11156 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI; 11157 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size; 11158 11159 vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 11160 vq->nSize = vqzip_payload->size; 11161 memcpy(vq->data, vqzip_payload->data, vqzip_payload->size); 11162 11163 print_debug_extradata(extra); 11164 } 11165 11166 OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) 11167 { 11168 OMX_ERRORTYPE eRet = OMX_ErrorNone; 11169 if (index >= drv_ctx.ip_buf.actualcount) { 11170 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found"); 11171 return OMX_ErrorInsufficientResources; 11172 } 11173 if (m_desc_buffer_ptr == NULL) { 11174 m_desc_buffer_ptr = (desc_buffer_hdr*) \ 11175 calloc( (sizeof(desc_buffer_hdr)), 11176 drv_ctx.ip_buf.actualcount); 11177 if (m_desc_buffer_ptr == NULL) { 11178 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed "); 11179 return OMX_ErrorInsufficientResources; 11180 } 11181 } 11182 11183 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); 11184 if (m_desc_buffer_ptr[index].buf_addr == NULL) { 11185 DEBUG_PRINT_ERROR("desc buffer Allocation failed "); 11186 return OMX_ErrorInsufficientResources; 11187 } 11188 11189 return eRet; 11190 } 11191 11192 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) 11193 { 11194 DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries); 11195 if (m_demux_entries < 8192) { 11196 m_demux_offsets[m_demux_entries++] = address_offset; 11197 } 11198 return; 11199 } 11200 11201 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) 11202 { 11203 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; 11204 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; 11205 OMX_U32 index = 0; 11206 11207 m_demux_entries = 0; 11208 11209 while (index < bytes_to_parse) { 11210 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 11211 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || 11212 ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 11213 (buf[index+2] == 0x01)) ) { 11214 //Found start code, insert address offset 11215 insert_demux_addr_offset(index); 11216 if (buf[index+2] == 0x01) // 3 byte start code 11217 index += 3; 11218 else //4 byte start code 11219 index += 4; 11220 } else 11221 index++; 11222 } 11223 DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries); 11224 return; 11225 } 11226 11227 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) 11228 { 11229 //fix this, handle 3 byte start code, vc1 terminator entry 11230 OMX_U8 *p_demux_data = NULL; 11231 OMX_U32 desc_data = 0; 11232 OMX_U32 start_addr = 0; 11233 OMX_U32 nal_size = 0; 11234 OMX_U32 suffix_byte = 0; 11235 OMX_U32 demux_index = 0; 11236 OMX_U32 buffer_index = 0; 11237 11238 if (m_desc_buffer_ptr == NULL) { 11239 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); 11240 return OMX_ErrorBadParameter; 11241 } 11242 11243 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 11244 if (buffer_index > drv_ctx.ip_buf.actualcount) { 11245 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index); 11246 return OMX_ErrorBadParameter; 11247 } 11248 11249 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; 11250 11251 if ( ((OMX_U8*)p_demux_data == NULL) || 11252 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) { 11253 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); 11254 return OMX_ErrorBadParameter; 11255 } else { 11256 for (; demux_index < m_demux_entries; demux_index++) { 11257 desc_data = 0; 11258 start_addr = m_demux_offsets[demux_index]; 11259 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) { 11260 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; 11261 } else { 11262 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; 11263 } 11264 if (demux_index < (m_demux_entries - 1)) { 11265 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; 11266 } else { 11267 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; 11268 } 11269 DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)", 11270 (unsigned int)start_addr, 11271 (unsigned int)suffix_byte, 11272 (unsigned int)nal_size, 11273 (unsigned int)demux_index); 11274 desc_data = (start_addr >> 3) << 1; 11275 desc_data |= (start_addr & 7) << 21; 11276 desc_data |= suffix_byte << 24; 11277 11278 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 11279 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); 11280 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 11281 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 11282 11283 p_demux_data += 16; 11284 } 11285 if (codec_type_parse == CODEC_TYPE_VC1) { 11286 DEBUG_PRINT_LOW("VC1 terminator entry"); 11287 desc_data = 0; 11288 desc_data = 0x82 << 24; 11289 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 11290 memset(p_demux_data + 4, 0, sizeof(OMX_U32)); 11291 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 11292 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 11293 p_demux_data += 16; 11294 m_demux_entries++; 11295 } 11296 //Add zero word to indicate end of descriptors 11297 memset(p_demux_data, 0, sizeof(OMX_U32)); 11298 11299 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); 11300 DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size); 11301 } 11302 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 11303 m_demux_entries = 0; 11304 DEBUG_PRINT_LOW("Demux table complete!"); 11305 return OMX_ErrorNone; 11306 } 11307 11308 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level) 11309 { 11310 struct v4l2_control control; 11311 char property_value[PROPERTY_VALUE_MAX] = {0}; 11312 11313 property_get("vidc.debug.turbo", property_value, "0"); 11314 memset(&control, 0, sizeof(v4l2_control)); 11315 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 11316 switch (perf_level) { 11317 case VIDC_NOMINAL: 11318 if (atoi(property_value)) 11319 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 11320 else 11321 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 11322 break; 11323 case VIDC_TURBO: 11324 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 11325 break; 11326 default: 11327 DEBUG_PRINT_ERROR("Requested PERF level not supported"); 11328 break; 11329 } 11330 if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig) 11331 return; 11332 11333 DEBUG_PRINT_HIGH("changing performance level to %d", control.value); 11334 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11335 current_perf_level = control.value; 11336 } else { 11337 DEBUG_PRINT_ERROR("Failed to set PERF level"); 11338 } 11339 } 11340 11341 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() 11342 { 11343 enabled = false; 11344 omx = NULL; 11345 init_members(); 11346 ColorFormat = OMX_COLOR_FormatMax; 11347 dest_format = YCbCr420P; 11348 } 11349 11350 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) 11351 { 11352 omx = reinterpret_cast<omx_vdec*>(client); 11353 } 11354 11355 void omx_vdec::allocate_color_convert_buf::init_members() 11356 { 11357 allocated_count = 0; 11358 buffer_size_req = 0; 11359 buffer_alignment_req = 0; 11360 memset(m_platform_list_client,0,sizeof(m_platform_list_client)); 11361 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); 11362 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); 11363 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); 11364 #ifdef USE_ION 11365 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); 11366 #endif 11367 for (int i = 0; i < MAX_COUNT; i++) 11368 pmem_fd[i] = -1; 11369 } 11370 11371 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() 11372 { 11373 c2d.destroy(); 11374 } 11375 11376 bool omx_vdec::allocate_color_convert_buf::update_buffer_req() 11377 { 11378 bool status = true; 11379 unsigned int src_size = 0, destination_size = 0; 11380 OMX_COLOR_FORMATTYPE drv_color_format; 11381 if (!omx) { 11382 DEBUG_PRINT_ERROR("Invalid client in color convert"); 11383 return false; 11384 } 11385 if (!enabled) { 11386 DEBUG_PRINT_HIGH("No color conversion required"); 11387 return status; 11388 } 11389 pthread_mutex_lock(&omx->c_lock); 11390 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && 11391 ColorFormat != OMX_COLOR_FormatYUV420Planar) { 11392 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion"); 11393 status = false; 11394 goto fail_update_buf_req; 11395 } 11396 c2d.close(); 11397 status = c2d.open(omx->drv_ctx.video_resolution.frame_height, 11398 omx->drv_ctx.video_resolution.frame_width, 11399 NV12_128m,dest_format); 11400 if (status) { 11401 status = c2d.get_buffer_size(C2D_INPUT,src_size); 11402 if (status) 11403 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); 11404 } 11405 if (status) { 11406 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || 11407 !destination_size) { 11408 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d" 11409 "driver size %u destination size %d", 11410 src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size, 11411 destination_size); 11412 status = false; 11413 c2d.close(); 11414 buffer_size_req = 0; 11415 } else { 11416 buffer_size_req = destination_size; 11417 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) 11418 buffer_size_req = omx->drv_ctx.op_buf.buffer_size; 11419 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 11420 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 11421 } 11422 } 11423 fail_update_buf_req: 11424 pthread_mutex_unlock(&omx->c_lock); 11425 return status; 11426 } 11427 11428 bool omx_vdec::allocate_color_convert_buf::set_color_format( 11429 OMX_COLOR_FORMATTYPE dest_color_format) 11430 { 11431 bool status = true; 11432 OMX_COLOR_FORMATTYPE drv_color_format; 11433 if (!omx) { 11434 DEBUG_PRINT_ERROR("Invalid client in color convert"); 11435 return false; 11436 } 11437 pthread_mutex_lock(&omx->c_lock); 11438 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 11439 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 11440 drv_color_format = (OMX_COLOR_FORMATTYPE) 11441 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 11442 else 11443 drv_color_format = (OMX_COLOR_FORMATTYPE) 11444 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11445 else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 11446 drv_color_format = (OMX_COLOR_FORMATTYPE) 11447 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 11448 } else { 11449 DEBUG_PRINT_ERROR("Incorrect color format"); 11450 status = false; 11451 } 11452 if (status && 11453 drv_color_format != dest_color_format && 11454 drv_color_format != (OMX_COLOR_FORMATTYPE) 11455 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView && 11456 drv_color_format != (OMX_COLOR_FORMATTYPE) 11457 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed && 11458 dest_color_format != (OMX_COLOR_FORMATTYPE) 11459 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 11460 DEBUG_PRINT_LOW("Enabling C2D"); 11461 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) && 11462 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) { 11463 DEBUG_PRINT_ERROR("Unsupported color format for c2d"); 11464 status = false; 11465 } else { 11466 ColorFormat = dest_color_format; 11467 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ? 11468 YCbCr420P : YCbCr420SP; 11469 if (enabled) 11470 c2d.destroy(); 11471 enabled = false; 11472 if (!c2d.init()) { 11473 DEBUG_PRINT_ERROR("open failed for c2d"); 11474 status = false; 11475 } else 11476 enabled = true; 11477 } 11478 } else { 11479 if (enabled) 11480 c2d.destroy(); 11481 enabled = false; 11482 } 11483 pthread_mutex_unlock(&omx->c_lock); 11484 return status; 11485 } 11486 11487 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() 11488 { 11489 if (!omx) { 11490 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 11491 return NULL; 11492 } 11493 if (!enabled) 11494 return omx->m_out_mem_ptr; 11495 return m_out_mem_ptr_client; 11496 } 11497 11498 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr 11499 (OMX_BUFFERHEADERTYPE *bufadd) 11500 { 11501 if (!omx) { 11502 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 11503 return NULL; 11504 } 11505 if (!enabled) 11506 return bufadd; 11507 11508 unsigned index = 0; 11509 index = bufadd - omx->m_out_mem_ptr; 11510 if (index < omx->drv_ctx.op_buf.actualcount) { 11511 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); 11512 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; 11513 bool status; 11514 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { 11515 pthread_mutex_lock(&omx->c_lock); 11516 cache_clean_buffer(index); 11517 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, 11518 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index], 11519 pmem_baseaddress[index], pmem_baseaddress[index]); 11520 if (!status) { 11521 DEBUG_PRINT_ERROR("Failed color conversion %d", status); 11522 m_out_mem_ptr_client[index].nFilledLen = 0; 11523 pthread_mutex_unlock(&omx->c_lock); 11524 return &m_out_mem_ptr_client[index]; 11525 } else { 11526 unsigned int filledLen = 0; 11527 c2d.get_output_filled_length(filledLen); 11528 m_out_mem_ptr_client[index].nFilledLen = filledLen; 11529 cache_clean_invalidate_buffer(index); 11530 } 11531 pthread_mutex_unlock(&omx->c_lock); 11532 } else 11533 m_out_mem_ptr_client[index].nFilledLen = 0; 11534 return &m_out_mem_ptr_client[index]; 11535 } 11536 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr"); 11537 return NULL; 11538 } 11539 11540 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr 11541 (OMX_BUFFERHEADERTYPE *bufadd) 11542 { 11543 if (!omx) { 11544 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 11545 return NULL; 11546 } 11547 if (!enabled) 11548 return bufadd; 11549 unsigned index = 0; 11550 index = bufadd - m_out_mem_ptr_client; 11551 if (index < omx->drv_ctx.op_buf.actualcount) { 11552 return &omx->m_out_mem_ptr[index]; 11553 } 11554 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr"); 11555 return NULL; 11556 } 11557 bool omx_vdec::allocate_color_convert_buf::get_buffer_req 11558 (unsigned int &buffer_size) 11559 { 11560 bool status = true; 11561 pthread_mutex_lock(&omx->c_lock); 11562 if (!enabled) 11563 buffer_size = omx->drv_ctx.op_buf.buffer_size; 11564 else { 11565 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { 11566 DEBUG_PRINT_ERROR("Get buffer size failed"); 11567 status = false; 11568 goto fail_get_buffer_size; 11569 } 11570 } 11571 if (buffer_size < omx->drv_ctx.op_buf.buffer_size) 11572 buffer_size = omx->drv_ctx.op_buf.buffer_size; 11573 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 11574 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 11575 fail_get_buffer_size: 11576 pthread_mutex_unlock(&omx->c_lock); 11577 return status; 11578 } 11579 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( 11580 OMX_BUFFERHEADERTYPE *bufhdr) 11581 { 11582 unsigned int index = 0; 11583 11584 if (!enabled) 11585 return omx->free_output_buffer(bufhdr); 11586 if (enabled && omx->is_component_secure()) 11587 return OMX_ErrorNone; 11588 if (!allocated_count || !bufhdr) { 11589 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); 11590 return OMX_ErrorBadParameter; 11591 } 11592 index = bufhdr - m_out_mem_ptr_client; 11593 if (index >= omx->drv_ctx.op_buf.actualcount) { 11594 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer"); 11595 return OMX_ErrorBadParameter; 11596 } 11597 if (pmem_fd[index] >= 0) { 11598 munmap(pmem_baseaddress[index], buffer_size_req); 11599 close(pmem_fd[index]); 11600 } 11601 pmem_fd[index] = -1; 11602 #ifdef USE_ION 11603 omx->free_ion_memory(&op_buf_ion_info[index]); 11604 #endif 11605 m_heap_ptr[index].video_heap_ptr = NULL; 11606 if (allocated_count > 0) 11607 allocated_count--; 11608 else 11609 allocated_count = 0; 11610 if (!allocated_count) { 11611 pthread_mutex_lock(&omx->c_lock); 11612 c2d.close(); 11613 init_members(); 11614 pthread_mutex_unlock(&omx->c_lock); 11615 } 11616 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); 11617 } 11618 11619 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, 11620 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) 11621 { 11622 OMX_ERRORTYPE eRet = OMX_ErrorNone; 11623 if (!enabled) { 11624 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 11625 return eRet; 11626 } 11627 if (enabled && omx->is_component_secure()) { 11628 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d", 11629 omx->is_component_secure()); 11630 return OMX_ErrorUnsupportedSetting; 11631 } 11632 if (!bufferHdr || bytes > buffer_size_req) { 11633 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr); 11634 DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u", 11635 (unsigned int)buffer_size_req, (unsigned int)bytes); 11636 return OMX_ErrorBadParameter; 11637 } 11638 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { 11639 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert"); 11640 return OMX_ErrorInsufficientResources; 11641 } 11642 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; 11643 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, 11644 port,appData,omx->drv_ctx.op_buf.buffer_size); 11645 if (eRet != OMX_ErrorNone || !temp_bufferHdr) { 11646 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert"); 11647 return eRet; 11648 } 11649 if ((temp_bufferHdr - omx->m_out_mem_ptr) >= 11650 (int)omx->drv_ctx.op_buf.actualcount) { 11651 DEBUG_PRINT_ERROR("Invalid header index %ld", 11652 (long int)(temp_bufferHdr - omx->m_out_mem_ptr)); 11653 return OMX_ErrorUndefined; 11654 } 11655 unsigned int i = allocated_count; 11656 #ifdef USE_ION 11657 // Allocate color-conversion buffers as cached to improve software-reading 11658 // performance of YUV (thumbnails). NOTE: These buffers will need an explicit 11659 // cache invalidation. 11660 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( 11661 buffer_size_req,buffer_alignment_req, 11662 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, 11663 ION_FLAG_CACHED); 11664 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; 11665 if (op_buf_ion_info[i].ion_device_fd < 0) { 11666 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert"); 11667 return OMX_ErrorInsufficientResources; 11668 } 11669 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, 11670 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); 11671 11672 if (pmem_baseaddress[i] == MAP_FAILED) { 11673 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req); 11674 close(pmem_fd[i]); 11675 omx->free_ion_memory(&op_buf_ion_info[i]); 11676 return OMX_ErrorInsufficientResources; 11677 } 11678 m_heap_ptr[i].video_heap_ptr = new VideoHeap ( 11679 op_buf_ion_info[i].ion_device_fd,buffer_size_req, 11680 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); 11681 #endif 11682 m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get(); 11683 m_pmem_info_client[i].offset = 0; 11684 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; 11685 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 11686 m_platform_list_client[i].nEntries = 1; 11687 m_platform_list_client[i].entryList = &m_platform_entry_client[i]; 11688 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; 11689 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; 11690 m_out_mem_ptr_client[i].nFilledLen = 0; 11691 m_out_mem_ptr_client[i].nFlags = 0; 11692 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11693 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); 11694 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; 11695 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; 11696 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; 11697 m_out_mem_ptr_client[i].pAppPrivate = appData; 11698 *bufferHdr = &m_out_mem_ptr_client[i]; 11699 DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr); 11700 allocated_count++; 11701 return eRet; 11702 } 11703 11704 bool omx_vdec::is_component_secure() 11705 { 11706 return secure_mode; 11707 } 11708 11709 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) 11710 { 11711 bool status = true; 11712 if (!enabled) { 11713 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 11714 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 11715 dest_color_format = (OMX_COLOR_FORMATTYPE) 11716 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 11717 else 11718 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11719 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){ 11720 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 11721 } else 11722 status = false; 11723 } else { 11724 if (ColorFormat == OMX_COLOR_FormatYUV420Planar || 11725 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 11726 dest_color_format = ColorFormat; 11727 } else 11728 status = false; 11729 } 11730 return status; 11731 } 11732 11733 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops( 11734 unsigned int index, unsigned int cmd) 11735 { 11736 if (!enabled) { 11737 return OMX_ErrorNone; 11738 } 11739 11740 if (!omx || index >= omx->drv_ctx.op_buf.actualcount) { 11741 DEBUG_PRINT_ERROR("%s: Invalid param", __func__); 11742 return OMX_ErrorBadParameter; 11743 } 11744 11745 struct ion_flush_data flush_data; 11746 struct ion_custom_data custom_data; 11747 11748 memset(&flush_data, 0x0, sizeof(flush_data)); 11749 memset(&custom_data, 0x0, sizeof(custom_data)); 11750 11751 flush_data.vaddr = pmem_baseaddress[index]; 11752 flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd; 11753 flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle; 11754 flush_data.length = buffer_size_req; 11755 custom_data.cmd = cmd; 11756 custom_data.arg = (unsigned long)&flush_data; 11757 11758 DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d", 11759 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 11760 flush_data.fd, flush_data.handle, flush_data.vaddr, 11761 flush_data.length); 11762 int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data); 11763 if (ret < 0) { 11764 DEBUG_PRINT_ERROR("Cache %s failed: %s\n", 11765 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 11766 strerror(errno)); 11767 return OMX_ErrorUndefined; 11768 } 11769 return OMX_ErrorNone; 11770 } 11771 11772 void omx_vdec::buf_ref_add(int nPortIndex) 11773 { 11774 unsigned long i = 0; 11775 bool buf_present = false; 11776 long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 11777 OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 11778 11779 if (!dynamic_buf_mode || !out_dynamic_list) { 11780 return; 11781 } 11782 11783 pthread_mutex_lock(&m_lock); 11784 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 11785 //check the buffer fd, offset, uv addr with list contents 11786 //If present increment reference. 11787 if ((out_dynamic_list[i].fd == fd) && 11788 (out_dynamic_list[i].offset == offset)) { 11789 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u", 11790 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 11791 if (!secure_mode) { 11792 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr; 11793 } 11794 buf_present = true; 11795 break; 11796 } 11797 } 11798 if (!buf_present) { 11799 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 11800 //search for a entry to insert details of the new buffer 11801 if (out_dynamic_list[i].dup_fd < 0) { 11802 out_dynamic_list[i].fd = fd; 11803 out_dynamic_list[i].offset = offset; 11804 out_dynamic_list[i].dup_fd = dup(fd); 11805 out_dynamic_list[i].ref_count++; 11806 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u", 11807 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 11808 11809 if (!secure_mode) { 11810 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = 11811 (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len, 11812 PROT_READ|PROT_WRITE, MAP_SHARED, 11813 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0); 11814 //mmap returns (void *)-1 on failure and sets error code in errno. 11815 if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) { 11816 DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno); 11817 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL; 11818 break; 11819 } 11820 out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr; 11821 out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len; 11822 DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 11823 } 11824 break; 11825 } 11826 } 11827 } 11828 pthread_mutex_unlock(&m_lock); 11829 } 11830 11831 void omx_vdec::buf_ref_remove() 11832 { 11833 unsigned long i = 0; 11834 11835 if (!dynamic_buf_mode || !out_dynamic_list) { 11836 return; 11837 } 11838 11839 pthread_mutex_lock(&m_lock); 11840 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 11841 if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) { 11842 DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 11843 munmap(out_dynamic_list[i].buffaddr, 11844 out_dynamic_list[i].mapped_size); 11845 } 11846 11847 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u", 11848 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 11849 close(out_dynamic_list[i].dup_fd); 11850 out_dynamic_list[i].dup_fd = -1; 11851 } 11852 pthread_mutex_unlock(&m_lock); 11853 11854 if (out_dynamic_list) { 11855 free(out_dynamic_list); 11856 out_dynamic_list = NULL; 11857 } 11858 } 11859 11860 #ifdef _MSM8974_ 11861 void omx_vdec::send_codec_config() { 11862 if (codec_config_flag) { 11863 unsigned long p1 = 0; // Parameter - 1 11864 unsigned long p2 = 0; // Parameter - 2 11865 unsigned long ident = 0; 11866 pthread_mutex_lock(&m_lock); 11867 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n"); 11868 while (m_etb_q.m_size) { 11869 m_etb_q.pop_entry(&p1,&p2,&ident); 11870 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 11871 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 11872 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 11873 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 11874 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); 11875 omx_report_error(); 11876 } 11877 } else { 11878 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 11879 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 11880 } 11881 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 11882 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 11883 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 11884 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 11885 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); 11886 omx_report_error (); 11887 } 11888 } else { 11889 pending_input_buffers++; 11890 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 11891 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 11892 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 11893 } 11894 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 11895 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", 11896 (OMX_BUFFERHEADERTYPE *)p1); 11897 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 11898 } 11899 } 11900 pthread_mutex_unlock(&m_lock); 11901 } 11902 } 11903 #endif 11904 11905 omx_vdec::perf_control::perf_control() 11906 { 11907 m_perf_lib = NULL; 11908 m_perf_handle = 0; 11909 m_perf_lock_acquire = NULL; 11910 m_perf_lock_release = NULL; 11911 } 11912 11913 omx_vdec::perf_control::~perf_control() 11914 { 11915 if (m_perf_handle != 0 && m_perf_lock_release) { 11916 DEBUG_PRINT_LOW("NOTE2: release perf lock"); 11917 m_perf_lock_release(m_perf_handle); 11918 } 11919 if (m_perf_lib) { 11920 dlclose(m_perf_lib); 11921 } 11922 } 11923 11924 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0}; 11925 11926 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock; 11927 11928 void omx_vdec::perf_control::send_hint_to_mpctl(bool state) 11929 { 11930 if (load_lib() == false) { 11931 return; 11932 } 11933 m_perf_lock.lock(); 11934 /* 0x4401 maps to video decode playback hint 11935 * in perflock, enum number is 44 and state 11936 * being sent on perflock acquire is 01 (true) 11937 */ 11938 int arg = 0x4401; 11939 11940 if (state == true) { 11941 mpctl_obj.vid_inst_count++; 11942 } else if (state == false) { 11943 mpctl_obj.vid_inst_count--; 11944 } 11945 11946 if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) { 11947 mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int)); 11948 mpctl_obj.vid_acquired = true; 11949 DEBUG_PRINT_INFO("Video slvp perflock acquired"); 11950 } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) { 11951 m_perf_lock_release(mpctl_obj.vid_disp_handle); 11952 mpctl_obj.vid_acquired = false; 11953 DEBUG_PRINT_INFO("Video slvp perflock released"); 11954 } 11955 m_perf_lock.unlock(); 11956 } 11957 11958 void omx_vdec::perf_control::request_cores(int frame_duration_us) 11959 { 11960 if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) { 11961 return; 11962 } 11963 bool retVal = load_lib(); 11964 if (retVal && m_perf_lock_acquire && m_perf_handle == 0) { 11965 int arg = 0x700 /*base value*/ + 2 /*cores*/; 11966 m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int)); 11967 if (m_perf_handle) { 11968 DEBUG_PRINT_HIGH("perf lock acquired"); 11969 } 11970 } 11971 } 11972 11973 bool omx_vdec::perf_control::load_lib() 11974 { 11975 char perf_lib_path[PROPERTY_VALUE_MAX] = {0}; 11976 if (m_perf_lib) 11977 return true; 11978 11979 if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) { 11980 DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library"); 11981 goto handle_err; 11982 } 11983 11984 if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) { 11985 DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror()); 11986 goto handle_err; 11987 } else { 11988 m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq"); 11989 if (m_perf_lock_acquire == NULL) { 11990 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq"); 11991 goto handle_err; 11992 } 11993 m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel"); 11994 if (m_perf_lock_release == NULL) { 11995 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel"); 11996 goto handle_err; 11997 } 11998 } 11999 return true; 12000 12001 handle_err: 12002 if (m_perf_lib) { 12003 dlclose(m_perf_lib); 12004 } 12005 m_perf_lib = NULL; 12006 return false; 12007 } 12008 12009 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth, 12010 unsigned long nMaxFrameHeight) 12011 { 12012 12013 OMX_ERRORTYPE eRet = OMX_ErrorNone; 12014 int ret = 0; 12015 unsigned long min_res_buf_count = 0; 12016 12017 eRet = enable_smoothstreaming(); 12018 if (eRet != OMX_ErrorNone) { 12019 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver"); 12020 return eRet; 12021 } 12022 12023 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu", 12024 nMaxFrameWidth, 12025 nMaxFrameHeight); 12026 m_smoothstreaming_mode = true; 12027 m_smoothstreaming_width = nMaxFrameWidth; 12028 m_smoothstreaming_height = nMaxFrameHeight; 12029 12030 //Get upper limit buffer count for min supported resolution 12031 struct v4l2_format fmt; 12032 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 12033 fmt.fmt.pix_mp.height = m_decoder_capability.min_height; 12034 fmt.fmt.pix_mp.width = m_decoder_capability.min_width; 12035 fmt.fmt.pix_mp.pixelformat = output_capability; 12036 12037 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 12038 if (ret) { 12039 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u", 12040 m_decoder_capability.min_height, 12041 m_decoder_capability.min_width); 12042 return OMX_ErrorUnsupportedSetting; 12043 } 12044 12045 eRet = get_buffer_req(&drv_ctx.op_buf); 12046 if (eRet != OMX_ErrorNone) { 12047 DEBUG_PRINT_ERROR("failed to get_buffer_req"); 12048 return eRet; 12049 } 12050 12051 min_res_buf_count = drv_ctx.op_buf.mincount; 12052 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u", 12053 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width); 12054 12055 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height, 12056 m_smoothstreaming_width, m_smoothstreaming_height); 12057 eRet = is_video_session_supported(); 12058 if (eRet != OMX_ErrorNone) { 12059 DEBUG_PRINT_ERROR("video session is not supported"); 12060 return eRet; 12061 } 12062 12063 //Get upper limit buffer size for max smooth streaming resolution set 12064 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 12065 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 12066 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 12067 fmt.fmt.pix_mp.pixelformat = output_capability; 12068 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 12069 if (ret) { 12070 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback"); 12071 return OMX_ErrorUnsupportedSetting; 12072 } 12073 12074 eRet = get_buffer_req(&drv_ctx.op_buf); 12075 if (eRet != OMX_ErrorNone) { 12076 DEBUG_PRINT_ERROR("failed to get_buffer_req!!"); 12077 return eRet; 12078 } 12079 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u", 12080 (unsigned int)drv_ctx.op_buf.buffer_size); 12081 12082 drv_ctx.op_buf.mincount = min_res_buf_count; 12083 drv_ctx.op_buf.actualcount = min_res_buf_count; 12084 drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size; 12085 eRet = set_buffer_req(&drv_ctx.op_buf); 12086 if (eRet != OMX_ErrorNone) { 12087 DEBUG_PRINT_ERROR("failed to set_buffer_req"); 12088 return eRet; 12089 } 12090 12091 eRet = get_buffer_req(&drv_ctx.op_buf); 12092 if (eRet != OMX_ErrorNone) { 12093 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!"); 12094 return eRet; 12095 } 12096 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u", 12097 drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size); 12098 return eRet; 12099 } 12100 12101 //static 12102 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) { 12103 12104 #ifndef FLEXYUV_SUPPORTED 12105 return OMX_ErrorUndefined; 12106 #else 12107 12108 if (pParam == NULL) { 12109 DEBUG_PRINT_ERROR("describeColorFormat: invalid params"); 12110 return OMX_ErrorBadParameter; 12111 } 12112 12113 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam; 12114 12115 MediaImage *img = &(params->sMediaImage); 12116 switch(params->eColorFormat) { 12117 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: 12118 { 12119 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 12120 img->mNumPlanes = 3; 12121 // mWidth and mHeight represent the W x H of the largest plane 12122 // In our case, this happens to be the Stride x Scanlines of Y plane 12123 img->mWidth = params->nFrameWidth; 12124 img->mHeight = params->nFrameHeight; 12125 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 12126 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight); 12127 img->mBitDepth = 8; 12128 //Plane 0 (Y) 12129 img->mPlane[MediaImage::Y].mOffset = 0; 12130 img->mPlane[MediaImage::Y].mColInc = 1; 12131 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride 12132 img->mPlane[MediaImage::Y].mHorizSubsampling = 1; 12133 img->mPlane[MediaImage::Y].mVertSubsampling = 1; 12134 //Plane 1 (U) 12135 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight; 12136 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV 12137 img->mPlane[MediaImage::U].mRowInc = 12138 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 12139 img->mPlane[MediaImage::U].mHorizSubsampling = 2; 12140 img->mPlane[MediaImage::U].mVertSubsampling = 2; 12141 //Plane 2 (V) 12142 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1; 12143 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV 12144 img->mPlane[MediaImage::V].mRowInc = 12145 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 12146 img->mPlane[MediaImage::V].mHorizSubsampling = 2; 12147 img->mPlane[MediaImage::V].mVertSubsampling = 2; 12148 break; 12149 } 12150 12151 case OMX_COLOR_FormatYUV420Planar: 12152 case OMX_COLOR_FormatYUV420SemiPlanar: 12153 // We need not describe the standard OMX linear formats as these are 12154 // understood by client. Fail this deliberately to let client fill-in 12155 return OMX_ErrorUnsupportedSetting; 12156 12157 default: 12158 // Rest all formats which are non-linear cannot be described 12159 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat); 12160 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 12161 return OMX_ErrorNone; 12162 }; 12163 12164 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat); 12165 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight); 12166 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight); 12167 for (size_t i = 0; i < img->mNumPlanes; ++i) { 12168 DEBUG_PRINT_LOW(" Plane[%zd] : offset=%d / xStep=%d / yStep = %d", 12169 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc); 12170 } 12171 return OMX_ErrorNone; 12172 #endif //FLEXYUV_SUPPORTED 12173 } 12174 12175 void omx_vdec::prefetchNewBuffers() { 12176 12177 struct v4l2_decoder_cmd dec; 12178 uint32_t prefetch_count; 12179 uint32_t prefetch_size; 12180 uint32_t want_size; 12181 uint32_t have_size; 12182 int color_fmt, rc; 12183 uint32_t new_calculated_size; 12184 uint32_t new_buffer_size; 12185 uint32_t new_buffer_count; 12186 uint32_t old_buffer_size; 12187 uint32_t old_buffer_count; 12188 12189 memset((void *)&dec, 0 , sizeof(dec)); 12190 DEBUG_PRINT_LOW("Old size : %d, count : %d, width : %u, height : %u\n", 12191 (int)drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount, 12192 drv_ctx.video_resolution.frame_width, 12193 drv_ctx.video_resolution.frame_height); 12194 dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT; 12195 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 12196 DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno); 12197 } else { 12198 DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n", 12199 dec.raw.data[0], dec.raw.data[1]); 12200 } 12201 12202 switch ((int)drv_ctx.output_format) { 12203 case VDEC_YUV_FORMAT_NV12: 12204 color_fmt = COLOR_FMT_NV12; 12205 break; 12206 case VDEC_YUV_FORMAT_NV12_UBWC: 12207 color_fmt = COLOR_FMT_NV12_UBWC; 12208 break; 12209 default: 12210 color_fmt = -1; 12211 } 12212 12213 new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height); 12214 DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n", 12215 m_reconfig_width, m_reconfig_height, new_calculated_size); 12216 new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size; 12217 new_buffer_count = dec.raw.data[1]; 12218 old_buffer_size = drv_ctx.op_buf.buffer_size; 12219 old_buffer_count = drv_ctx.op_buf.actualcount; 12220 12221 new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count; 12222 12223 prefetch_count = new_buffer_count; 12224 prefetch_size = new_buffer_size - old_buffer_size; 12225 want_size = new_buffer_size * new_buffer_count; 12226 have_size = old_buffer_size * old_buffer_count; 12227 12228 if (want_size > have_size) { 12229 DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size); 12230 DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size); 12231 12232 int ion_fd = open(MEM_DEVICE, O_RDONLY); 12233 if (ion_fd < 0) { 12234 DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd); 12235 return; 12236 } 12237 12238 struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data)); 12239 struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data)); 12240 struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions)); 12241 size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count); 12242 12243 if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) { 12244 DEBUG_PRINT_ERROR("prefetch data allocation failed"); 12245 goto prefetch_exit; 12246 } 12247 12248 for (uint32_t i = 0; i < prefetch_count; i++) { 12249 sizes[i] = prefetch_size; 12250 } 12251 12252 regions[0].nr_sizes = prefetch_count; 12253 regions[0].sizes = sizes; 12254 regions[0].vmid = ION_FLAG_CP_PIXEL; 12255 12256 prefetch_data->nr_regions = 1; 12257 prefetch_data->regions = regions; 12258 prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID); 12259 12260 custom_data->cmd = ION_IOC_PREFETCH; 12261 custom_data->arg = (unsigned long )prefetch_data; 12262 12263 rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data); 12264 if (rc) { 12265 DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno); 12266 } 12267 12268 prefetch_exit: 12269 close(ion_fd); 12270 free(sizes); 12271 free(regions); 12272 free(prefetch_data); 12273 free(custom_data); 12274 } 12275 } 12276 12277