1/*-------------------------------------------------------------------------- 2Copyright (c) 2010 - 2017, The Linux Foundation. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, 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 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26ADVISED 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#if !defined(_ANDROID_) || defined(SYS_IOCTL) 59#include <sys/ioctl.h> 60#include <sys/mman.h> 61#endif 62 63#ifdef _ANDROID_ 64#include <cutils/properties.h> 65#undef USE_EGL_IMAGE_GPU 66 67#ifdef _QUERY_DISP_RES_ 68#include "display_config.h" 69#endif 70#endif 71 72#ifdef _USE_GLIB_ 73#include <glib.h> 74#define strlcpy g_strlcpy 75#endif 76 77#include <qdMetaData.h> 78#include <gralloc_priv.h> 79 80#ifdef ANDROID_JELLYBEAN_MR2 81#include "QComOMXMetadata.h" 82#endif 83 84#ifdef USE_EGL_IMAGE_GPU 85#include <EGL/egl.h> 86#include <EGL/eglQCOM.h> 87#define EGL_BUFFER_HANDLE 0x4F00 88#define EGL_BUFFER_OFFSET 0x4F01 89#endif 90 91#define BUFFER_LOG_LOC "/data/misc/media" 92 93#ifdef OUTPUT_EXTRADATA_LOG 94FILE *outputExtradataFile; 95char output_extradata_filename [] = "/data/misc/media/extradata"; 96#endif 97 98#define DEFAULT_FPS 30 99#define MAX_SUPPORTED_FPS 240 100#define DEFAULT_WIDTH_ALIGNMENT 128 101#define DEFAULT_HEIGHT_ALIGNMENT 32 102 103#define VC1_SP_MP_START_CODE 0xC5000000 104#define VC1_SP_MP_START_CODE_MASK 0xFF000000 105#define VC1_AP_SEQ_START_CODE 0x0F010000 106#define VC1_STRUCT_C_PROFILE_MASK 0xF0 107#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 108#define VC1_SIMPLE_PROFILE 0 109#define VC1_MAIN_PROFILE 1 110#define VC1_ADVANCE_PROFILE 3 111#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 112#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 113#define VC1_STRUCT_C_LEN 4 114#define VC1_STRUCT_C_POS 8 115#define VC1_STRUCT_A_POS 12 116#define VC1_STRUCT_B_POS 24 117#define VC1_SEQ_LAYER_SIZE 36 118#define POLL_TIMEOUT 0x7fffffff 119 120#define MEM_DEVICE "/dev/ion" 121 122#ifdef _ANDROID_ 123extern "C" { 124#include<utils/Log.h> 125} 126#endif//_ANDROID_ 127 128#define SZ_4K 0x1000 129#define SZ_1M 0x100000 130 131#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 132#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 133#define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0) 134#define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1)) 135 136#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_FRAMEPACK_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA \ 137 | OMX_DISPLAY_INFO_EXTRADATA | OMX_HDR_COLOR_INFO_EXTRADATA) 138#define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default 139 140#ifndef ION_FLAG_CP_BITSTREAM 141#define ION_FLAG_CP_BITSTREAM 0 142#endif 143 144#ifndef ION_FLAG_CP_PIXEL 145#define ION_FLAG_CP_PIXEL 0 146#endif 147 148#ifdef MASTER_SIDE_CP 149#define MEM_HEAP_ID ION_SECURE_HEAP_ID 150#define SECURE_ALIGN SZ_4K 151#define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM) 152#define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL) 153#else //SLAVE_SIDE_CP 154#define MEM_HEAP_ID ION_CP_MM_HEAP_ID 155#define SECURE_ALIGN SZ_1M 156#define SECURE_FLAGS_INPUT_BUFFER ION_SECURE 157#define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE 158#endif 159 160#define LUMINANCE_DIV_FACTOR 10000.0 161 162#define MIN(x,y) (((x) < (y)) ? (x) : (y)) 163#define MAX(x,y) (((x) > (y)) ? (x) : (y)) 164 165static OMX_U32 maxSmoothStreamingWidth = 1920; 166static OMX_U32 maxSmoothStreamingHeight = 1088; 167 168void* async_message_thread (void *input) 169{ 170 OMX_BUFFERHEADERTYPE *buffer; 171 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 172 struct pollfd pfds[2]; 173 struct v4l2_buffer v4l2_buf; 174 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 175 struct v4l2_event dqevent; 176 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 177 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 178 pfds[1].events = POLLIN | POLLERR; 179 pfds[0].fd = omx->drv_ctx.video_driver_fd; 180 pfds[1].fd = omx->m_poll_efd; 181 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; 182 DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); 183 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); 184 while (!omx->async_thread_force_stop) { 185 rc = poll(pfds, 2, POLL_TIMEOUT); 186 if (!rc) { 187 DEBUG_PRINT_ERROR("Poll timedout"); 188 break; 189 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) { 190 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno); 191 break; 192 } 193 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) { 194 DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited"); 195 break; 196 } 197 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) { 198 struct vdec_msginfo vdec_msg; 199 memset(&vdec_msg, 0, sizeof(vdec_msg)); 200 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 201 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 202 v4l2_buf.length = omx->drv_ctx.num_planes; 203 v4l2_buf.m.planes = plane; 204 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 205 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 206 vdec_msg.status_code=VDEC_S_SUCCESS; 207 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; 208 vdec_msg.msgdata.output_frame.len=plane[0].bytesused; 209 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; 210 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + 211 (uint64_t)v4l2_buf.timestamp.tv_usec; 212 213 if (omx->async_message_process(input,&vdec_msg) < 0) { 214 DEBUG_PRINT_HIGH("async_message_thread Exited"); 215 break; 216 } 217 } 218 } 219 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) { 220 struct vdec_msginfo vdec_msg; 221 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 222 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 223 v4l2_buf.length = 1; 224 v4l2_buf.m.planes = plane; 225 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 226 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; 227 vdec_msg.status_code=VDEC_S_SUCCESS; 228 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; 229 if (omx->async_message_process(input,&vdec_msg) < 0) { 230 DEBUG_PRINT_HIGH("async_message_thread Exited"); 231 break; 232 } 233 } 234 } 235 if (pfds[0].revents & POLLPRI) { 236 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent); 237 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { 238 struct vdec_msginfo vdec_msg; 239 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 240 241 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; 242 vdec_msg.status_code=VDEC_S_SUCCESS; 243 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0]; 244 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1]; 245 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient"); 246 if(ptr[2] & V4L2_EVENT_BITDEPTH_FLAG) { 247 omx->dpb_bit_depth = ptr[3]; 248 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", ptr[3]); 249 } 250 if(ptr[2] & V4L2_EVENT_PICSTRUCT_FLAG) { 251 omx->m_progressive = ptr[4]; 252 DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct change - %d", ptr[4]); 253 } 254 if(ptr[2] & V4L2_EVENT_COLOUR_SPACE_FLAG) { 255 if (ptr[5] == MSM_VIDC_BT2020) { 256 omx->m_color_space = omx_vdec::BT2020; 257 } else { 258 omx->m_color_space = omx_vdec::EXCEPT_BT2020; 259 } 260 DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace change - %d", omx->m_color_space); 261 } 262 if (omx->async_message_process(input,&vdec_msg) < 0) { 263 DEBUG_PRINT_HIGH("async_message_thread Exited"); 264 break; 265 } 266 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 267 struct vdec_msginfo vdec_msg; 268 uint32_t flush_type = *(uint32_t *)dqevent.u.data; 269 // Old driver doesn't send flushType information. 270 // To make this backward compatible fallback to old approach 271 // if the flush_type is not present. 272 vdec_msg.status_code=VDEC_S_SUCCESS; 273 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) { 274 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; 275 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved"); 276 if (omx->async_message_process(input,&vdec_msg) < 0) { 277 DEBUG_PRINT_HIGH("async_message_thread Exited"); 278 break; 279 } 280 } 281 282 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) { 283 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; 284 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved"); 285 if (omx->async_message_process(input,&vdec_msg) < 0) { 286 DEBUG_PRINT_HIGH("async_message_thread Exited"); 287 break; 288 } 289 } 290 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) { 291 struct vdec_msginfo vdec_msg; 292 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD; 293 vdec_msg.status_code=VDEC_S_SUCCESS; 294 DEBUG_PRINT_ERROR("HW Overload received"); 295 if (omx->async_message_process(input,&vdec_msg) < 0) { 296 DEBUG_PRINT_HIGH("async_message_thread Exited"); 297 break; 298 } 299 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) { 300 struct vdec_msginfo vdec_msg; 301 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED; 302 vdec_msg.status_code=VDEC_S_SUCCESS; 303 DEBUG_PRINT_ERROR("HW Unsupported received"); 304 if (omx->async_message_process(input,&vdec_msg) < 0) { 305 DEBUG_PRINT_HIGH("async_message_thread Exited"); 306 break; 307 } 308 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 309 struct vdec_msginfo vdec_msg; 310 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR; 311 vdec_msg.status_code = VDEC_S_SUCCESS; 312 DEBUG_PRINT_HIGH("SYS Error Recieved"); 313 if (omx->async_message_process(input,&vdec_msg) < 0) { 314 DEBUG_PRINT_HIGH("async_message_thread Exited"); 315 break; 316 } 317 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) { 318 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 319 320 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]); 321 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) { 322 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data; 323 struct vdec_msginfo vdec_msg; 324 325 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]); 326 327 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 328 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 329 v4l2_buf.length = omx->drv_ctx.num_planes; 330 v4l2_buf.m.planes = plane; 331 v4l2_buf.index = ptr[5]; 332 v4l2_buf.flags = 0; 333 334 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 335 vdec_msg.status_code = VDEC_S_SUCCESS; 336 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf; 337 vdec_msg.msgdata.output_frame.len = 0; 338 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2]; 339 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) + 340 (uint64_t)ptr[4]; 341 if (omx->async_message_process(input,&vdec_msg) < 0) { 342 DEBUG_PRINT_HIGH("async_message_thread Exitedn"); 343 break; 344 } 345 } else { 346 DEBUG_PRINT_HIGH("VIDC Some Event recieved"); 347 continue; 348 } 349 } 350 } 351 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); 352 return NULL; 353} 354 355void* message_thread_dec(void *input) 356{ 357 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 358 unsigned char id; 359 int n; 360 361 fd_set readFds; 362 int res = 0; 363 struct timeval tv; 364 365 DEBUG_PRINT_HIGH("omx_vdec: message thread start"); 366 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); 367 while (!omx->message_thread_stop) { 368 369 tv.tv_sec = 2; 370 tv.tv_usec = 0; 371 372 FD_ZERO(&readFds); 373 FD_SET(omx->m_pipe_in, &readFds); 374 375 res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv); 376 if (res < 0) { 377 DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno)); 378 continue; 379 } else if (res == 0 /*timeout*/ || omx->message_thread_stop) { 380 continue; 381 } 382 383 n = read(omx->m_pipe_in, &id, 1); 384 385 if (0 == n) { 386 break; 387 } 388 389 if (1 == n) { 390 omx->process_event_cb(omx, id); 391 } 392 393 if ((n < 0) && (errno != EINTR)) { 394 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno); 395 break; 396 } 397 } 398 DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); 399 return 0; 400} 401 402void post_message(omx_vdec *omx, unsigned char id) 403{ 404 int ret_value; 405 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); 406 ret_value = write(omx->m_pipe_out, &id, 1); 407 if (ret_value <= 0) { 408 DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno)); 409 } else { 410 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); 411 } 412} 413 414// omx_cmd_queue destructor 415omx_vdec::omx_cmd_queue::~omx_cmd_queue() 416{ 417 // Nothing to do 418} 419 420// omx cmd queue constructor 421omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 422{ 423 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 424} 425 426// omx cmd queue insert 427bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id) 428{ 429 bool ret = true; 430 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) { 431 m_q[m_write].id = id; 432 m_q[m_write].param1 = p1; 433 m_q[m_write].param2 = p2; 434 m_write++; 435 m_size ++; 436 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) { 437 m_write = 0; 438 } 439 } else { 440 ret = false; 441 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__); 442 } 443 return ret; 444} 445 446// omx cmd queue pop 447bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id) 448{ 449 bool ret = true; 450 if (m_size > 0) { 451 *id = m_q[m_read].id; 452 *p1 = m_q[m_read].param1; 453 *p2 = m_q[m_read].param2; 454 // Move the read pointer ahead 455 ++m_read; 456 --m_size; 457 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) { 458 m_read = 0; 459 } 460 } else { 461 ret = false; 462 } 463 return ret; 464} 465 466// Retrieve the first mesg type in the queue 467unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 468{ 469 return m_q[m_read].id; 470} 471 472#ifdef _ANDROID_ 473omx_vdec::ts_arr_list::ts_arr_list() 474{ 475 //initialize timestamps array 476 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); 477} 478omx_vdec::ts_arr_list::~ts_arr_list() 479{ 480 //free m_ts_arr_list? 481} 482 483bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) 484{ 485 bool ret = true; 486 bool duplicate_ts = false; 487 int idx = 0; 488 489 //insert at the first available empty location 490 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 491 if (!m_ts_arr_list[idx].valid) { 492 //found invalid or empty entry, save timestamp 493 m_ts_arr_list[idx].valid = true; 494 m_ts_arr_list[idx].timestamp = ts; 495 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", 496 ts, idx); 497 break; 498 } 499 } 500 501 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) { 502 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); 503 ret = false; 504 } 505 return ret; 506} 507 508bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) 509{ 510 bool ret = true; 511 int min_idx = -1; 512 OMX_TICKS min_ts = 0; 513 int idx = 0; 514 515 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 516 517 if (m_ts_arr_list[idx].valid) { 518 //found valid entry, save index 519 if (min_idx < 0) { 520 //first valid entry 521 min_ts = m_ts_arr_list[idx].timestamp; 522 min_idx = idx; 523 } else if (m_ts_arr_list[idx].timestamp < min_ts) { 524 min_ts = m_ts_arr_list[idx].timestamp; 525 min_idx = idx; 526 } 527 } 528 529 } 530 531 if (min_idx < 0) { 532 //no valid entries found 533 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); 534 ts = 0; 535 ret = false; 536 } else { 537 ts = m_ts_arr_list[min_idx].timestamp; 538 m_ts_arr_list[min_idx].valid = false; 539 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", 540 ts, min_idx); 541 } 542 543 return ret; 544 545} 546 547 548bool omx_vdec::ts_arr_list::reset_ts_list() 549{ 550 bool ret = true; 551 int idx = 0; 552 553 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); 554 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 555 m_ts_arr_list[idx].valid = false; 556 } 557 return ret; 558} 559#endif 560 561// factory function executed by the core to create instances 562void *get_omx_component_factory_fn(void) 563{ 564 return (new omx_vdec); 565} 566 567#ifdef _ANDROID_ 568#ifdef USE_ION 569VideoHeap::VideoHeap(int devicefd, size_t size, void* base, 570 ion_user_handle_t handle, int ionMapfd) 571{ 572 (void) devicefd; 573 (void) size; 574 (void) base; 575 (void) handle; 576 (void) ionMapfd; 577 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); 578} 579#else 580VideoHeap::VideoHeap(int fd, size_t size, void* base) 581{ 582 // dup file descriptor, map once, use pmem 583 init(dup(fd), base, size, 0 , MEM_DEVICE); 584} 585#endif 586#endif // _ANDROID_ 587 588bool is_platform_tp10capture_supported() 589{ 590 char platform_name[PROPERTY_VALUE_MAX] = {0}; 591 property_get("ro.board.platform", platform_name, "0"); 592 if (!strncmp(platform_name, "msm8998", 7)) { 593 DEBUG_PRINT_HIGH("TP10 on capture port is supported"); 594 return true; 595 } 596 DEBUG_PRINT_HIGH("TP10 on capture port is not supported"); 597 return false; 598} 599 600/* ====================================================================== 601 FUNCTION 602 omx_vdec::omx_vdec 603 604 DESCRIPTION 605 Constructor 606 607 PARAMETERS 608 None 609 610 RETURN VALUE 611 None. 612 ========================================================================== */ 613omx_vdec::omx_vdec(): m_error_propogated(false), 614 m_state(OMX_StateInvalid), 615 m_app_data(NULL), 616 m_inp_mem_ptr(NULL), 617 m_out_mem_ptr(NULL), 618 input_flush_progress (false), 619 output_flush_progress (false), 620 input_use_buffer (false), 621 output_use_buffer (false), 622 ouput_egl_buffers(false), 623 m_use_output_pmem(OMX_FALSE), 624 m_out_mem_region_smi(OMX_FALSE), 625 m_out_pvt_entry_pmem(OMX_FALSE), 626 pending_input_buffers(0), 627 pending_output_buffers(0), 628 m_out_bm_count(0), 629 m_inp_bm_count(0), 630 m_inp_bPopulated(OMX_FALSE), 631 m_out_bPopulated(OMX_FALSE), 632 m_flags(0), 633#ifdef _ANDROID_ 634 m_heap_ptr(NULL), 635#endif 636 m_inp_bEnabled(OMX_TRUE), 637 m_out_bEnabled(OMX_TRUE), 638 m_in_alloc_cnt(0), 639 m_platform_list(NULL), 640 m_platform_entry(NULL), 641 m_pmem_info(NULL), 642 h264_parser(NULL), 643 arbitrary_bytes (true), 644 psource_frame (NULL), 645 pdest_frame (NULL), 646 m_inp_heap_ptr (NULL), 647 m_phdr_pmem_ptr(NULL), 648 m_heap_inp_bm_count (0), 649 codec_type_parse ((codec_type)0), 650 first_frame_meta (true), 651 frame_count (0), 652 nal_count (0), 653 nal_length(0), 654 look_ahead_nal (false), 655 first_frame(0), 656 first_buffer(NULL), 657 first_frame_size (0), 658 m_device_file_ptr(NULL), 659 m_vc1_profile((vc1_profile_type)0), 660 h264_last_au_ts(LLONG_MAX), 661 h264_last_au_flags(0), 662 m_disp_hor_size(0), 663 m_disp_vert_size(0), 664 prev_ts(LLONG_MAX), 665 prev_ts_actual(LLONG_MAX), 666 rst_prev_ts(true), 667 frm_int(0), 668 m_fps_received(0), 669 m_fps_prev(0), 670 m_drc_enable(0), 671 in_reconfig(false), 672 m_display_id(NULL), 673 client_extradata(0), 674 m_reject_avc_1080p_mp (0), 675#ifdef _ANDROID_ 676 m_enable_android_native_buffers(OMX_FALSE), 677 m_use_android_native_buffers(OMX_FALSE), 678#endif 679 m_desc_buffer_ptr(NULL), 680 secure_mode(false), 681 allocate_native_handle(false), 682 m_other_extradata(NULL), 683 m_profile(0), 684 m_need_turbo(0), 685 client_set_fps(false), 686 stereo_output_mode(HAL_NO_3D), 687 m_last_rendered_TS(-1), 688 m_queued_codec_config_count(0), 689 current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL), 690 secure_scaling_to_non_secure_opb(false), 691 m_force_compressed_for_dpb(true), 692 m_is_display_session(false) 693{ 694 m_pipe_in = -1; 695 m_pipe_out = -1; 696 m_poll_efd = -1; 697 drv_ctx.video_driver_fd = -1; 698 drv_ctx.extradata_info.ion.fd_ion_data.fd = -1; 699 /* Assumption is that , to begin with , we have all the frames with decoder */ 700 DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8); 701 memset(&m_debug,0,sizeof(m_debug)); 702#ifdef _ANDROID_ 703 char property_value[PROPERTY_VALUE_MAX] = {0}; 704 property_get("vidc.debug.level", property_value, "1"); 705 debug_level = strtoul(property_value, NULL, 16); 706 property_value[0] = '\0'; 707 708 DEBUG_PRINT_HIGH("In OMX vdec Constructor"); 709 710 property_get("vidc.dec.debug.perf", property_value, "0"); 711 perf_flag = atoi(property_value); 712 if (perf_flag) { 713 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); 714 dec_time.start(); 715 } 716 proc_frms = latency = 0; 717 prev_n_filled_len = 0; 718 property_value[0] = '\0'; 719 property_get("vidc.dec.debug.ts", property_value, "0"); 720 m_debug_timestamp = atoi(property_value); 721 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); 722 if (m_debug_timestamp) { 723 time_stamp_dts.set_timestamp_reorder_mode(true); 724 time_stamp_dts.enable_debug_print(true); 725 } 726 727 property_value[0] = '\0'; 728 property_get("vidc.dec.debug.concealedmb", property_value, "0"); 729 m_debug_concealedmb = atoi(property_value); 730 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); 731 732 property_value[0] = '\0'; 733 property_get("vidc.dec.profile.check", property_value, "0"); 734 m_reject_avc_1080p_mp = atoi(property_value); 735 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp); 736 737 property_value[0] = '\0'; 738 property_get("vidc.dec.log.in", property_value, "0"); 739 m_debug.in_buffer_log = atoi(property_value); 740 741 property_value[0] = '\0'; 742 property_get("vidc.dec.log.out", property_value, "0"); 743 m_debug.out_buffer_log = atoi(property_value); 744 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 745 746 property_value[0] = '\0'; 747 property_get("vidc.dec.meta.log.out", property_value, "0"); 748 m_debug.out_meta_buffer_log = atoi(property_value); 749 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); 750 751 property_value[0] = '\0'; 752 property_get("vidc.log.loc", property_value, ""); 753 if (*property_value) 754 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX); 755 756 property_value[0] = '\0'; 757 property_get("vidc.dec.120fps.enabled", property_value, "0"); 758 759 //if this feature is not enabled then reset this value -ve 760 if(atoi(property_value)) { 761 DEBUG_PRINT_LOW("feature 120 FPS decode enabled"); 762 m_last_rendered_TS = 0; 763 } 764 765 property_value[0] = '\0'; 766 property_get("vidc.dec.debug.dyn.disabled", property_value, "0"); 767 m_disable_dynamic_buf_mode = atoi(property_value); 768 DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode); 769 770 property_value[0] = '\0'; 771 property_get("vidc.dec.drc.enable", property_value, "0"); 772 if (atoi(property_value)) { 773 m_drc_enable = true; 774 DEBUG_PRINT_HIGH("DRC enabled"); 775 } 776 777#ifdef _UBWC_ 778 property_value[0] = '\0'; 779 property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0"); 780 m_disable_ubwc_mode = atoi(property_value); 781 DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled"); 782#else 783 m_disable_ubwc_mode = true; 784#endif 785#endif 786 memset(&m_cmp,0,sizeof(m_cmp)); 787 memset(&m_cb,0,sizeof(m_cb)); 788 memset (&drv_ctx,0,sizeof(drv_ctx)); 789 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 790 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 791 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 792 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize)); 793 memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams)); 794 memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams)); 795 memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams)); 796 memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams)); 797 memset(&m_color_mdata, 0, sizeof(ColorMetaData)); 798 m_demux_entries = 0; 799 msg_thread_id = 0; 800 async_thread_id = 0; 801 msg_thread_created = false; 802 async_thread_created = false; 803 async_thread_force_stop = false; 804 message_thread_stop = false; 805#ifdef _ANDROID_ICS_ 806 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 807#endif 808 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 809 810 /* invalidate m_frame_pack_arrangement */ 811 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 812 m_frame_pack_arrangement.cancel_flag = 1; 813 814 drv_ctx.timestamp_adjust = false; 815 m_vendor_config.pData = NULL; 816 pthread_mutex_init(&m_lock, NULL); 817 pthread_mutex_init(&c_lock, NULL); 818 pthread_mutex_init(&buf_lock, NULL); 819 sem_init(&m_cmd_lock,0,0); 820 sem_init(&m_safe_flush, 0, 0); 821 streaming[CAPTURE_PORT] = 822 streaming[OUTPUT_PORT] = false; 823#ifdef _ANDROID_ 824 char extradata_value[PROPERTY_VALUE_MAX] = {0}; 825 property_get("vidc.dec.debug.extradata", extradata_value, "0"); 826 m_debug_extradata = atoi(extradata_value); 827 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); 828#endif 829 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; 830 client_buffers.set_vdec_client(this); 831 dynamic_buf_mode = false; 832 out_dynamic_list = NULL; 833 is_down_scalar_enabled = false; 834 m_enable_downscalar = 0; 835 m_downscalar_width = 0; 836 m_downscalar_height = 0; 837 m_force_down_scalar = 0; 838 m_reconfig_height = 0; 839 m_reconfig_width = 0; 840 m_smoothstreaming_mode = false; 841 m_smoothstreaming_width = 0; 842 m_smoothstreaming_height = 0; 843 is_q6_platform = false; 844 m_perf_control.send_hint_to_mpctl(true); 845 m_input_pass_buffer_fd = false; 846 memset(&m_extradata_info, 0, sizeof(m_extradata_info)); 847 m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX; 848 m_client_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 849 m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 850 m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 851 m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 852 853 m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 854 m_internal_color_space.sAspects.mRange = ColorAspects::RangeUnspecified; 855 m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified; 856 m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 857 m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified; 858 m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams); 859 860 m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX; 861 m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX; 862 m_change_client_hdr_info = false; 863 pthread_mutex_init(&m_hdr_info_client_lock, NULL); 864 865 char dither_value[PROPERTY_VALUE_MAX] = {0}; 866 property_get("vidc.dec.dither", dither_value, "0"); 867 if ((atoi(dither_value) > DITHER_ALL_COLORSPACE) || 868 (atoi(dither_value) < DITHER_DISABLE)) { 869 m_dither_config = DITHER_ALL_COLORSPACE; 870 } else { 871 m_dither_config = is_platform_tp10capture_supported() ? (dither_type)atoi(dither_value) : DITHER_ALL_COLORSPACE; 872 } 873 874 DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config); 875 m_color_space = EXCEPT_BT2020; 876} 877 878static const int event_type[] = { 879 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 880 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, 881 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, 882 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT, 883 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE, 884 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER, 885 V4L2_EVENT_MSM_VIDC_SYS_ERROR, 886 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD, 887 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED 888}; 889 890static OMX_ERRORTYPE subscribe_to_events(int fd) 891{ 892 OMX_ERRORTYPE eRet = OMX_ErrorNone; 893 struct v4l2_event_subscription sub; 894 int array_sz = sizeof(event_type)/sizeof(int); 895 int i,rc; 896 if (fd < 0) { 897 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 898 return OMX_ErrorBadParameter; 899 } 900 901 for (i = 0; i < array_sz; ++i) { 902 memset(&sub, 0, sizeof(sub)); 903 sub.type = event_type[i]; 904 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 905 if (rc) { 906 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 907 break; 908 } 909 } 910 if (i < array_sz) { 911 for (--i; i >=0 ; i--) { 912 memset(&sub, 0, sizeof(sub)); 913 sub.type = event_type[i]; 914 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 915 if (rc) 916 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 917 } 918 eRet = OMX_ErrorNotImplemented; 919 } 920 return eRet; 921} 922 923 924static OMX_ERRORTYPE unsubscribe_to_events(int fd) 925{ 926 OMX_ERRORTYPE eRet = OMX_ErrorNone; 927 struct v4l2_event_subscription sub; 928 int array_sz = sizeof(event_type)/sizeof(int); 929 int i,rc; 930 if (fd < 0) { 931 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 932 return OMX_ErrorBadParameter; 933 } 934 935 for (i = 0; i < array_sz; ++i) { 936 memset(&sub, 0, sizeof(sub)); 937 sub.type = event_type[i]; 938 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 939 if (rc) { 940 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 941 break; 942 } 943 } 944 return eRet; 945} 946 947/* ====================================================================== 948 FUNCTION 949 omx_vdec::~omx_vdec 950 951 DESCRIPTION 952 Destructor 953 954 PARAMETERS 955 None 956 957 RETURN VALUE 958 None. 959 ========================================================================== */ 960omx_vdec::~omx_vdec() 961{ 962 m_pmem_info = NULL; 963 DEBUG_PRINT_HIGH("In OMX vdec Destructor"); 964 if (msg_thread_created) { 965 DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread"); 966 message_thread_stop = true; 967 post_message(this, OMX_COMPONENT_CLOSE_MSG); 968 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); 969 pthread_join(msg_thread_id,NULL); 970 } 971 close(m_pipe_in); 972 close(m_pipe_out); 973 m_pipe_in = -1; 974 m_pipe_out = -1; 975 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); 976 if(eventfd_write(m_poll_efd, 1)) { 977 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno); 978 async_thread_force_stop = true; 979 } 980 981 if (async_thread_created) 982 pthread_join(async_thread_id,NULL); 983 unsubscribe_to_events(drv_ctx.video_driver_fd); 984 close(m_poll_efd); 985 close(drv_ctx.video_driver_fd); 986 pthread_mutex_destroy(&m_lock); 987 pthread_mutex_destroy(&c_lock); 988 pthread_mutex_destroy(&buf_lock); 989 sem_destroy(&m_cmd_lock); 990 pthread_mutex_destroy(&m_hdr_info_client_lock); 991 if (perf_flag) { 992 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); 993 dec_time.end(); 994 } 995 DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd); 996 m_perf_control.send_hint_to_mpctl(false); 997} 998 999int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) 1000{ 1001 struct v4l2_requestbuffers bufreq; 1002 int rc = 0; 1003 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 1004 bufreq.memory = V4L2_MEMORY_USERPTR; 1005 bufreq.count = 0; 1006 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1007 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 1008 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) { 1009 bufreq.memory = V4L2_MEMORY_USERPTR; 1010 bufreq.count = 0; 1011 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1012 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 1013 } 1014 return rc; 1015} 1016 1017OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format) 1018{ 1019 int rc = 0; 1020 struct v4l2_ext_control ctrl[2]; 1021 struct v4l2_ext_controls controls; 1022 1023 DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s", 1024 is_split_mode ? "split" : "combined", 1025 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc": 1026 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc": 1027 dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb": 1028 "unknown", 1029 capture_capability == V4L2_PIX_FMT_NV12 ? "nv12": 1030 capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc": 1031 capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC ? "nv12_10bit_ubwc": 1032 "unknown"); 1033 1034 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE; 1035 if (is_split_mode) { 1036 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY; 1037 } else { 1038 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY; 1039 } 1040 1041 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT; 1042 ctrl[1].value = dpb_color_format; 1043 1044 controls.count = 2; 1045 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 1046 controls.controls = ctrl; 1047 1048 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls); 1049 if (rc) { 1050 DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc); 1051 return OMX_ErrorUnsupportedSetting; 1052 } 1053 return OMX_ErrorNone; 1054} 1055 1056 1057OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool split_opb_dpb_with_same_color_fmt) 1058{ 1059 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1060 struct v4l2_format fmt; 1061 int rc = 0; 1062 bool cpu_access = (capture_capability != V4L2_PIX_FMT_NV12_UBWC) && 1063 capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC; 1064 bool tp10_enable = !cpu_access && 1065 dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10; 1066 bool dither_enable = true; 1067 1068 switch (m_dither_config) { 1069 case DITHER_DISABLE: 1070 dither_enable = false; 1071 break; 1072 case DITHER_COLORSPACE_EXCEPTBT2020: 1073 dither_enable = (m_color_space == EXCEPT_BT2020); 1074 break; 1075 case DITHER_ALL_COLORSPACE: 1076 dither_enable = true; 1077 break; 1078 default: 1079 DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config); 1080 } 1081 1082 if (tp10_enable && !dither_enable) { 1083 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC; 1084 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC; 1085 1086 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1087 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1088 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1089 if (rc) { 1090 DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__); 1091 return OMX_ErrorUnsupportedSetting; 1092 } 1093 fmt.fmt.pix_mp.pixelformat = capture_capability; 1094 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1095 if (rc) { 1096 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__); 1097 return OMX_ErrorUnsupportedSetting; 1098 } 1099 1100 } 1101 1102 1103 if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) && 1104 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 1105 DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split"); 1106 return eRet; 1107 } 1108 1109 1110 if (cpu_access) { 1111 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 1112 /* Disabled split mode for VP9. In split mode the DPB buffers are part of the internal 1113 * scratch buffers and the driver does not does the reference buffer management for 1114 * scratch buffers. In case of VP9 with spatial scalability, when a sequence changed 1115 * event is received with the new resolution, and when a flush is sent by the driver, it 1116 * releases all the references of internal scratch buffers. However as per the VP9 1117 * spatial scalability, even after the flush, the buffers which have not yet received 1118 * release reference event should not be unmapped and freed. Currently in driver, 1119 * reference buffer management of the internal scratch buffer is not implemented 1120 * and hence the DPB buffers get unmapped. For other codecs it does not matter 1121 * as with the new SPS/PPS, the DPB is flushed. 1122 */ 1123 bool is_not_vp9 = eCompressionFormat != OMX_VIDEO_CodingVP9; 1124 bool eligible_for_split_dpb_ubwc = 1125 m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE && //@ Due to Venus limitation for Interlaced, Split mode enabled only for Progressive. 1126 is_not_vp9 && //@ Split mode disabled for VP9. 1127 !drv_ctx.idr_only_decoding && //@ Split mode disabled for Thumbnail usecase. 1128 !m_disable_split_mode; //@ Set prop to disable split mode 1129 1130 //Since opb is linear, dpb should also be linear. 1131 if (split_opb_dpb_with_same_color_fmt) { 1132 eligible_for_split_dpb_ubwc = false; 1133 } 1134 1135 if (eligible_for_split_dpb_ubwc) { 1136 //split DPB-OPB 1137 //DPB -> UBWC , OPB -> Linear 1138 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1139 } else if (split_opb_dpb_with_same_color_fmt) { 1140 //DPB -> Linear, OPB -> Linear 1141 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1142 } else { 1143 //DPB-OPB combined linear 1144 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1145 } 1146 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1147 //split DPB-OPB 1148 //DPB -> UBWC, OPB -> Linear 1149 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1150 } 1151 } else { //no cpu access 1152 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) { 1153 if (split_opb_dpb_with_same_color_fmt) { 1154 //split DPB-OPB 1155 //DPB -> UBWC, OPB -> UBWC 1156 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC); 1157 } else { 1158 //DPB-OPB combined UBWC 1159 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE); 1160 } 1161 } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) { 1162 if (dither_enable) { 1163 //split DPB-OPB 1164 //DPB -> TP10UBWC, OPB -> UBWC 1165 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1166 } else { 1167 //combined DPB-OPB 1168 //DPB -> TP10UBWC, OPB -> TP10UBWC 1169 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC); 1170 } 1171 } 1172 } 1173 if (eRet) { 1174 DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet); 1175 } 1176 1177 1178 1179 return eRet; 1180} 1181 1182int omx_vdec::enable_downscalar() 1183{ 1184 int rc = 0; 1185 struct v4l2_control control; 1186 struct v4l2_format fmt; 1187 1188 if (is_down_scalar_enabled) { 1189 DEBUG_PRINT_LOW("%s: already enabled", __func__); 1190 return 0; 1191 } 1192 1193 DEBUG_PRINT_LOW("omx_vdec::enable_downscalar"); 1194 rc = decide_dpb_buffer_mode(true); 1195 if (rc) { 1196 DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__); 1197 return rc; 1198 } 1199 is_down_scalar_enabled = true; 1200 1201 memset(&control, 0x0, sizeof(struct v4l2_control)); 1202 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO; 1203 control.value = 1; 1204 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 1205 if (rc) { 1206 DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__); 1207 return rc; 1208 } 1209 1210 return 0; 1211} 1212 1213int omx_vdec::disable_downscalar() 1214{ 1215 int rc = 0; 1216 struct v4l2_control control; 1217 1218 if (!is_down_scalar_enabled) { 1219 DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled"); 1220 return 0; 1221 } 1222 1223 rc = decide_dpb_buffer_mode(false); 1224 if (rc < 0) { 1225 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__); 1226 return rc; 1227 } 1228 is_down_scalar_enabled = false; 1229 1230 return rc; 1231} 1232 1233int omx_vdec::decide_downscalar() 1234{ 1235 int rc = 0; 1236 struct v4l2_format fmt; 1237 enum color_fmts color_format; 1238 OMX_U32 width, height; 1239 OMX_BOOL isPortraitVideo = OMX_FALSE; 1240 1241 if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) { 1242 rc = disable_downscalar(); 1243 if (rc) { 1244 DEBUG_PRINT_ERROR("Disable downscalar failed!"); 1245 return rc; 1246 } 1247 return 0; 1248 } 1249 1250 if (!m_enable_downscalar) { 1251 DEBUG_PRINT_LOW("%s: downscalar not supported", __func__); 1252 return 0; 1253 } 1254 1255#ifdef _QUERY_DISP_RES_ 1256 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1257 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1258 fmt.fmt.pix_mp.pixelformat = capture_capability; 1259 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1260 if (rc < 0) { 1261 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 1262 return rc; 1263 } 1264 isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE; 1265 if (!m_downscalar_width || !m_downscalar_height) { 1266 qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {}; 1267 int prim_config, ext_config, virt_config; 1268 1269 prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY); 1270 dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY); 1271 DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d dpa.yres=%d dpa.xdpi = %f dpa.ydpi = %f ", 1272 __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi); 1273 1274 ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL); 1275 dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL); 1276 DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d dsa.yres = %d dsa.xdpi = %f dsa.ydpi = %f ", 1277 __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi); 1278 1279 virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL); 1280 dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL); 1281 DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d dva.yres = %d dva.xdpi = %f dva.ydpi = %f ", 1282 __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi); 1283 1284 /* Below logic takes care of following conditions: 1285 * 1. Choose display resolution as maximum resolution of all the connected 1286 * displays (secondary, primary, virtual), so that we do not downscale 1287 * unnecessarily which might be supported on one of the display losing quality. 1288 * 2. Displays connected might be in landscape or portrait mode, so the xres might 1289 * be smaller or greater than the yres. So we first take the max of the two 1290 * in width and min of two in height and then rotate it if below point is true. 1291 * 3. Video might also be in portrait mode, so invert the downscalar width and 1292 * height for such cases. 1293 */ 1294 if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) { 1295 m_downscalar_width = MAX(dsa.xres, dsa.yres); 1296 m_downscalar_height = MIN(dsa.xres, dsa.yres); 1297 } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) { 1298 m_downscalar_width = MAX(dva.xres, dva.yres); 1299 m_downscalar_height = MIN(dva.xres, dva.yres); 1300 1301 } else { 1302 m_downscalar_width = MAX(dpa.xres, dpa.yres); 1303 m_downscalar_height = MIN(dpa.xres, dpa.yres); 1304 } 1305 if (isPortraitVideo) { 1306 // Swap width and height 1307 m_downscalar_width = m_downscalar_width ^ m_downscalar_height; 1308 m_downscalar_height = m_downscalar_width ^ m_downscalar_height; 1309 m_downscalar_width = m_downscalar_width ^ m_downscalar_height; 1310 } 1311 } 1312 m_downscalar_width = ALIGN(m_downscalar_width, 128); 1313 m_downscalar_height = ALIGN(m_downscalar_height, 32); 1314#endif 1315 1316 if (!m_downscalar_width || !m_downscalar_height) { 1317 DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__); 1318 return 0; 1319 } 1320 1321 if (m_force_down_scalar) { 1322 DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar); 1323 return 0; 1324 } 1325 1326 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1327 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1328 fmt.fmt.pix_mp.pixelformat = capture_capability; 1329 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 1330 if (rc < 0) { 1331 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 1332 return rc; 1333 } 1334 1335 height = fmt.fmt.pix_mp.height; 1336 width = fmt.fmt.pix_mp.width; 1337 1338 DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__, 1339 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session); 1340 1341 if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) && 1342 m_is_display_session) { 1343 rc = enable_downscalar(); 1344 if (rc < 0) { 1345 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 1346 return rc; 1347 } 1348 1349 width = m_downscalar_width > fmt.fmt.pix_mp.width ? 1350 fmt.fmt.pix_mp.width : m_downscalar_width; 1351 height = m_downscalar_height > fmt.fmt.pix_mp.height ? 1352 fmt.fmt.pix_mp.height : m_downscalar_height; 1353 switch (capture_capability) { 1354 case V4L2_PIX_FMT_NV12: 1355 color_format = COLOR_FMT_NV12; 1356 break; 1357 case V4L2_PIX_FMT_NV12_UBWC: 1358 color_format = COLOR_FMT_NV12_UBWC; 1359 break; 1360 case V4L2_PIX_FMT_NV12_TP10_UBWC: 1361 color_format = COLOR_FMT_NV12_BPP10_UBWC; 1362 break; 1363 default: 1364 DEBUG_PRINT_ERROR("Color format not recognized\n"); 1365 rc = OMX_ErrorUndefined; 1366 return rc; 1367 } 1368 } else { 1369 1370 rc = disable_downscalar(); 1371 if (rc < 0) { 1372 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 1373 return rc; 1374 } 1375 } 1376 1377 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 1378 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1379 fmt.fmt.pix_mp.height = height; 1380 fmt.fmt.pix_mp.width = width; 1381 fmt.fmt.pix_mp.pixelformat = capture_capability; 1382 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1383 if (rc) { 1384 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__); 1385 return rc; 1386 } 1387 1388 rc = get_buffer_req(&drv_ctx.op_buf); 1389 if (rc) { 1390 DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__); 1391 return rc; 1392 } 1393 1394 return rc; 1395} 1396 1397/* ====================================================================== 1398 FUNCTION 1399 omx_vdec::OMXCntrlProcessMsgCb 1400 1401 DESCRIPTION 1402 IL Client callbacks are generated through this routine. The decoder 1403 provides the thread context for this routine. 1404 1405 PARAMETERS 1406 ctxt -- Context information related to the self. 1407 id -- Event identifier. This could be any of the following: 1408 1. Command completion event 1409 2. Buffer done callback event 1410 3. Frame done callback event 1411 1412 RETURN VALUE 1413 None. 1414 1415 ========================================================================== */ 1416void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 1417{ 1418 unsigned long p1; // Parameter - 1 1419 unsigned long p2; // Parameter - 2 1420 unsigned long ident; 1421 unsigned qsize=0; // qsize 1422 omx_vdec *pThis = (omx_vdec *) ctxt; 1423 1424 if (!pThis) { 1425 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out", 1426 __func__); 1427 return; 1428 } 1429 1430 // Protect the shared queue data structure 1431 do { 1432 /*Read the message id's from the queue*/ 1433 pthread_mutex_lock(&pThis->m_lock); 1434 qsize = pThis->m_cmd_q.m_size; 1435 if (qsize) { 1436 pThis->m_cmd_q.pop_entry(&p1, &p2, &ident); 1437 } 1438 1439 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1440 qsize = pThis->m_ftb_q.m_size; 1441 if (qsize) { 1442 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident); 1443 } 1444 } 1445 1446 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 1447 qsize = pThis->m_etb_q.m_size; 1448 if (qsize) { 1449 pThis->m_etb_q.pop_entry(&p1, &p2, &ident); 1450 } 1451 } 1452 pthread_mutex_unlock(&pThis->m_lock); 1453 1454 /*process message if we have one*/ 1455 if (qsize > 0) { 1456 id = ident; 1457 switch (id) { 1458 case OMX_COMPONENT_GENERATE_EVENT: 1459 if (pThis->m_cb.EventHandler) { 1460 switch (p1) { 1461 case OMX_CommandStateSet: 1462 pThis->m_state = (OMX_STATETYPE) p2; 1463 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", 1464 pThis->m_state); 1465 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1466 OMX_EventCmdComplete, p1, p2, NULL); 1467 break; 1468 1469 case OMX_EventError: 1470 if (p2 == OMX_StateInvalid) { 1471 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid"); 1472 pThis->m_state = (OMX_STATETYPE) p2; 1473 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1474 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 1475 } else if (p2 == (unsigned long)OMX_ErrorHardware) { 1476 pThis->omx_report_error(); 1477 } else { 1478 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1479 OMX_EventError, p2, (OMX_U32)NULL, NULL ); 1480 } 1481 break; 1482 1483 case OMX_CommandPortDisable: 1484 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2); 1485 if (BITMASK_PRESENT(&pThis->m_flags, 1486 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1487 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1488 break; 1489 } 1490 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) { 1491 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1492 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 1493 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) 1494 DEBUG_PRINT_HIGH("Failed to release output buffers"); 1495 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); 1496 if (eRet != OMX_ErrorNone) { 1497 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); 1498 pThis->omx_report_error(); 1499 break; 1500 } 1501 } 1502 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1503 OMX_EventCmdComplete, p1, p2, NULL ); 1504 break; 1505 case OMX_CommandPortEnable: 1506 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2); 1507 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 1508 OMX_EventCmdComplete, p1, p2, NULL ); 1509 pThis->in_reconfig = false; 1510 break; 1511 1512 default: 1513 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1514 OMX_EventCmdComplete, p1, p2, NULL ); 1515 break; 1516 1517 } 1518 } else { 1519 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1520 } 1521 break; 1522 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 1523 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 1524 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1525 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure"); 1526 pThis->omx_report_error (); 1527 } 1528 break; 1529 case OMX_COMPONENT_GENERATE_ETB: { 1530 OMX_ERRORTYPE iret; 1531 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2); 1532 if (iret == OMX_ErrorInsufficientResources) { 1533 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload"); 1534 pThis->omx_report_hw_overload (); 1535 } else if (iret != OMX_ErrorNone) { 1536 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); 1537 pThis->omx_report_error (); 1538 } 1539 } 1540 break; 1541 1542 case OMX_COMPONENT_GENERATE_FTB: 1543 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\ 1544 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) { 1545 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure"); 1546 pThis->omx_report_error (); 1547 } 1548 break; 1549 1550 case OMX_COMPONENT_GENERATE_COMMAND: 1551 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 1552 (OMX_U32)p2,(OMX_PTR)NULL); 1553 break; 1554 1555 case OMX_COMPONENT_GENERATE_EBD: 1556 1557 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) { 1558 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure"); 1559 pThis->omx_report_error (); 1560 } else { 1561 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) { 1562 pThis->time_stamp_dts.remove_time_stamp( 1563 ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp, 1564 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1565 ?true:false); 1566 } 1567 1568 if ( pThis->empty_buffer_done(&pThis->m_cmp, 1569 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) { 1570 DEBUG_PRINT_ERROR("empty_buffer_done failure"); 1571 pThis->omx_report_error (); 1572 } 1573 } 1574 break; 1575 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: { 1576 int64_t *timestamp = (int64_t *)(intptr_t)p1; 1577 if (p1) { 1578 pThis->time_stamp_dts.remove_time_stamp(*timestamp, 1579 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1580 ?true:false); 1581 free(timestamp); 1582 } 1583 } 1584 break; 1585 case OMX_COMPONENT_GENERATE_FBD: 1586 if (p2 != VDEC_S_SUCCESS) { 1587 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure"); 1588 pThis->omx_report_error (); 1589 } else if ( pThis->fill_buffer_done(&pThis->m_cmp, 1590 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) { 1591 DEBUG_PRINT_ERROR("fill_buffer_done failure"); 1592 pThis->omx_report_error (); 1593 } 1594 break; 1595 1596 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 1597 DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); 1598 if (!pThis->input_flush_progress) { 1599 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1600 } else { 1601 pThis->execute_input_flush(); 1602 if (pThis->m_cb.EventHandler) { 1603 if (p2 != VDEC_S_SUCCESS) { 1604 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 1605 pThis->omx_report_error (); 1606 } else { 1607 /*Check if we need generate event for Flush done*/ 1608 if (BITMASK_PRESENT(&pThis->m_flags, 1609 OMX_COMPONENT_INPUT_FLUSH_PENDING)) { 1610 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 1611 DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); 1612 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1613 OMX_EventCmdComplete,OMX_CommandFlush, 1614 OMX_CORE_INPUT_PORT_INDEX,NULL ); 1615 } 1616 if (BITMASK_PRESENT(&pThis->m_flags, 1617 OMX_COMPONENT_IDLE_PENDING)) { 1618 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { 1619 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port"); 1620 pThis->omx_report_error (); 1621 } else { 1622 pThis->streaming[OUTPUT_PORT] = false; 1623 } 1624 if (!pThis->output_flush_progress) { 1625 DEBUG_PRINT_LOW("Input flush done hence issue stop"); 1626 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1627 OMX_COMPONENT_GENERATE_STOP_DONE); 1628 } 1629 } 1630 } 1631 } else { 1632 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1633 } 1634 } 1635 break; 1636 1637 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 1638 DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); 1639 if (!pThis->output_flush_progress) { 1640 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 1641 } else { 1642 pThis->execute_output_flush(); 1643 if (pThis->m_cb.EventHandler) { 1644 if (p2 != VDEC_S_SUCCESS) { 1645 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 1646 pThis->omx_report_error (); 1647 } else { 1648 /*Check if we need generate event for Flush done*/ 1649 if (BITMASK_PRESENT(&pThis->m_flags, 1650 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) { 1651 DEBUG_PRINT_LOW("Notify Output Flush done"); 1652 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1653 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1654 OMX_EventCmdComplete,OMX_CommandFlush, 1655 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 1656 } 1657 if (BITMASK_PRESENT(&pThis->m_flags, 1658 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 1659 DEBUG_PRINT_LOW("Internal flush complete"); 1660 BITMASK_CLEAR (&pThis->m_flags, 1661 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 1662 if (BITMASK_PRESENT(&pThis->m_flags, 1663 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) { 1664 pThis->post_event(OMX_CommandPortDisable, 1665 OMX_CORE_OUTPUT_PORT_INDEX, 1666 OMX_COMPONENT_GENERATE_EVENT); 1667 BITMASK_CLEAR (&pThis->m_flags, 1668 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1669 BITMASK_CLEAR (&pThis->m_flags, 1670 OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1671 1672 } 1673 } 1674 1675 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) { 1676 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 1677 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port"); 1678 pThis->omx_report_error (); 1679 break; 1680 } 1681 pThis->streaming[CAPTURE_PORT] = false; 1682 if (!pThis->input_flush_progress) { 1683 DEBUG_PRINT_LOW("Output flush done hence issue stop"); 1684 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1685 OMX_COMPONENT_GENERATE_STOP_DONE); 1686 } 1687 } 1688 } 1689 } else { 1690 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1691 } 1692 } 1693 break; 1694 1695 case OMX_COMPONENT_GENERATE_START_DONE: 1696 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); 1697 1698 if (pThis->m_cb.EventHandler) { 1699 if (p2 != VDEC_S_SUCCESS) { 1700 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure"); 1701 pThis->omx_report_error (); 1702 } else { 1703 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); 1704 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1705 DEBUG_PRINT_LOW("Move to executing"); 1706 // Send the callback now 1707 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1708 pThis->m_state = OMX_StateExecuting; 1709 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1710 OMX_EventCmdComplete,OMX_CommandStateSet, 1711 OMX_StateExecuting, NULL); 1712 } else if (BITMASK_PRESENT(&pThis->m_flags, 1713 OMX_COMPONENT_PAUSE_PENDING)) { 1714 if (/*ioctl (pThis->drv_ctx.video_driver_fd, 1715 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) { 1716 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed"); 1717 pThis->omx_report_error (); 1718 } 1719 } 1720 } 1721 } else { 1722 DEBUG_PRINT_LOW("Event Handler callback is NULL"); 1723 } 1724 break; 1725 1726 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 1727 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 1728 if (pThis->m_cb.EventHandler) { 1729 if (p2 != VDEC_S_SUCCESS) { 1730 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 1731 pThis->omx_report_error (); 1732 } else { 1733 pThis->complete_pending_buffer_done_cbs(); 1734 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) { 1735 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 1736 //Send the callback now 1737 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 1738 pThis->m_state = OMX_StatePause; 1739 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1740 OMX_EventCmdComplete,OMX_CommandStateSet, 1741 OMX_StatePause, NULL); 1742 } 1743 } 1744 } else { 1745 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1746 } 1747 1748 break; 1749 1750 case OMX_COMPONENT_GENERATE_RESUME_DONE: 1751 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 1752 if (pThis->m_cb.EventHandler) { 1753 if (p2 != VDEC_S_SUCCESS) { 1754 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 1755 pThis->omx_report_error (); 1756 } else { 1757 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1758 DEBUG_PRINT_LOW("Moving the decoder to execute state"); 1759 // Send the callback now 1760 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1761 pThis->m_state = OMX_StateExecuting; 1762 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1763 OMX_EventCmdComplete,OMX_CommandStateSet, 1764 OMX_StateExecuting,NULL); 1765 } 1766 } 1767 } else { 1768 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1769 } 1770 1771 break; 1772 1773 case OMX_COMPONENT_GENERATE_STOP_DONE: 1774 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 1775 if (pThis->m_cb.EventHandler) { 1776 if (p2 != VDEC_S_SUCCESS) { 1777 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 1778 pThis->omx_report_error (); 1779 } else { 1780 pThis->complete_pending_buffer_done_cbs(); 1781 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) { 1782 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); 1783 // Send the callback now 1784 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 1785 pThis->m_state = OMX_StateIdle; 1786 DEBUG_PRINT_LOW("Move to Idle State"); 1787 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 1788 OMX_EventCmdComplete,OMX_CommandStateSet, 1789 OMX_StateIdle,NULL); 1790 } 1791 } 1792 } else { 1793 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1794 } 1795 1796 break; 1797 1798 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 1799 if (p2 == OMX_IndexParamPortDefinition) { 1800 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition"); 1801 pThis->in_reconfig = true; 1802 pThis->m_need_turbo &= ~TURBO_MODE_HIGH_FPS; 1803 } else if (p2 == OMX_IndexConfigCommonOutputCrop) { 1804 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop"); 1805 1806 /* Check if resolution is changed in smooth streaming mode */ 1807 if (pThis->m_smoothstreaming_mode && 1808 (pThis->framesize.nWidth != 1809 pThis->drv_ctx.video_resolution.frame_width) || 1810 (pThis->framesize.nHeight != 1811 pThis->drv_ctx.video_resolution.frame_height)) { 1812 1813 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d", 1814 pThis->framesize.nWidth, 1815 pThis->framesize.nHeight, 1816 pThis->drv_ctx.video_resolution.frame_width, 1817 pThis->drv_ctx.video_resolution.frame_height); 1818 1819 /* Update new resolution */ 1820 pThis->framesize.nWidth = 1821 pThis->drv_ctx.video_resolution.frame_width; 1822 pThis->framesize.nHeight = 1823 pThis->drv_ctx.video_resolution.frame_height; 1824 1825 /* Update C2D with new resolution */ 1826 if (!pThis->client_buffers.update_buffer_req()) { 1827 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed"); 1828 } 1829 } 1830 1831 /* Update new crop information */ 1832 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left; 1833 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top; 1834 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right; 1835 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom; 1836 1837 /* Validate the new crop information */ 1838 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth > 1839 pThis->drv_ctx.video_resolution.frame_width) { 1840 1841 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]", 1842 pThis->rectangle.nLeft, pThis->rectangle.nWidth, 1843 pThis->drv_ctx.video_resolution.frame_width); 1844 pThis->rectangle.nLeft = 0; 1845 1846 if (pThis->rectangle.nWidth > 1847 pThis->drv_ctx.video_resolution.frame_width) { 1848 1849 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]", 1850 pThis->rectangle.nWidth, 1851 pThis->drv_ctx.video_resolution.frame_width); 1852 pThis->rectangle.nWidth = 1853 pThis->drv_ctx.video_resolution.frame_width; 1854 } 1855 } 1856 if (pThis->rectangle.nTop + pThis->rectangle.nHeight > 1857 pThis->drv_ctx.video_resolution.frame_height) { 1858 1859 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]", 1860 pThis->rectangle.nTop, pThis->rectangle.nHeight, 1861 pThis->drv_ctx.video_resolution.frame_height); 1862 pThis->rectangle.nTop = 0; 1863 1864 if (pThis->rectangle.nHeight > 1865 pThis->drv_ctx.video_resolution.frame_height) { 1866 1867 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]", 1868 pThis->rectangle.nHeight, 1869 pThis->drv_ctx.video_resolution.frame_height); 1870 pThis->rectangle.nHeight = 1871 pThis->drv_ctx.video_resolution.frame_height; 1872 } 1873 } 1874 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u", 1875 pThis->rectangle.nLeft, pThis->rectangle.nTop, 1876 pThis->rectangle.nWidth, pThis->rectangle.nHeight); 1877 } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) { 1878 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects"); 1879 } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) { 1880 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo"); 1881 } else { 1882 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2); 1883 break; 1884 } 1885 if (pThis->m_debug.outfile) { 1886 fclose(pThis->m_debug.outfile); 1887 pThis->m_debug.outfile = NULL; 1888 } 1889 if (pThis->m_debug.out_ymeta_file) { 1890 fclose(pThis->m_debug.out_ymeta_file); 1891 pThis->m_debug.out_ymeta_file = NULL; 1892 } 1893 if (pThis->m_debug.out_uvmeta_file) { 1894 fclose(pThis->m_debug.out_uvmeta_file); 1895 pThis->m_debug.out_uvmeta_file = NULL; 1896 } 1897 1898 if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) { 1899 pThis->prefetchNewBuffers(); 1900 } 1901 1902 if (pThis->m_cb.EventHandler) { 1903 uint32_t frame_data[4]; 1904 frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ? 1905 pThis->m_reconfig_height : pThis->rectangle.nHeight; 1906 frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ? 1907 pThis->m_reconfig_width : pThis->rectangle.nWidth; 1908 1909 frame_data[2] = (p2 == OMX_IndexParamPortDefinition) ? 1910 frame_data[0] : pThis->drv_ctx.video_resolution.frame_height; 1911 1912 frame_data[3] = (p2 == OMX_IndexParamPortDefinition) ? 1913 frame_data[1] : pThis->drv_ctx.video_resolution.frame_width; 1914 1915 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1916 OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data ); 1917 } else { 1918 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1919 } 1920 break; 1921 1922 case OMX_COMPONENT_GENERATE_EOS_DONE: 1923 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); 1924 if (pThis->m_cb.EventHandler) { 1925 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, 1926 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); 1927 } else { 1928 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1929 } 1930 pThis->prev_ts = LLONG_MAX; 1931 pThis->rst_prev_ts = true; 1932 break; 1933 1934 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 1935 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 1936 pThis->omx_report_error(); 1937 break; 1938 1939 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: 1940 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING"); 1941 pThis->omx_report_unsupported_setting(); 1942 break; 1943 1944 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD: 1945 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD"); 1946 pThis->omx_report_hw_overload(); 1947 break; 1948 1949 default: 1950 break; 1951 } 1952 } 1953 pthread_mutex_lock(&pThis->m_lock); 1954 qsize = pThis->m_cmd_q.m_size; 1955 if (pThis->m_state != OMX_StatePause) 1956 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); 1957 pthread_mutex_unlock(&pThis->m_lock); 1958 } while (qsize>0); 1959 1960} 1961 1962int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) 1963{ 1964 int format_changed = 0; 1965 if ((height != (int)drv_ctx.video_resolution.frame_height) || 1966 (width != (int)drv_ctx.video_resolution.frame_width)) { 1967 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)", 1968 width, drv_ctx.video_resolution.frame_width, 1969 height,drv_ctx.video_resolution.frame_height); 1970 format_changed = 1; 1971 } 1972 drv_ctx.video_resolution.frame_height = height; 1973 drv_ctx.video_resolution.frame_width = width; 1974 drv_ctx.video_resolution.scan_lines = scan_lines; 1975 drv_ctx.video_resolution.stride = stride; 1976 1977 if (!is_down_scalar_enabled) { 1978 rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft; 1979 rectangle.nTop = m_extradata_info.output_crop_rect.nTop; 1980 rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth; 1981 rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight; 1982 } 1983 return format_changed; 1984} 1985 1986OMX_ERRORTYPE omx_vdec::is_video_session_supported() 1987{ 1988 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 1989 OMX_MAX_STRINGNAME_SIZE) && 1990 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) { 1991 m_decoder_capability.max_width = 1280; 1992 m_decoder_capability.max_height = 720; 1993 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP"); 1994 } 1995 1996 if ((drv_ctx.video_resolution.frame_width * 1997 drv_ctx.video_resolution.frame_height > 1998 m_decoder_capability.max_width * 1999 m_decoder_capability.max_height) || 2000 (drv_ctx.video_resolution.frame_width* 2001 drv_ctx.video_resolution.frame_height < 2002 m_decoder_capability.min_width * 2003 m_decoder_capability.min_height)) { 2004 DEBUG_PRINT_ERROR( 2005 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", 2006 drv_ctx.video_resolution.frame_width, 2007 drv_ctx.video_resolution.frame_height, 2008 m_decoder_capability.min_width, 2009 m_decoder_capability.min_height, 2010 m_decoder_capability.max_width, 2011 m_decoder_capability.max_height); 2012 return OMX_ErrorUnsupportedSetting; 2013 } 2014 DEBUG_PRINT_HIGH("video session supported"); 2015 return OMX_ErrorNone; 2016} 2017 2018int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len) 2019{ 2020 if (m_debug.in_buffer_log && !m_debug.infile) { 2021 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 2022 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v", 2023 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2024 } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 2025 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, 2026 drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2027 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 2028 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263", 2029 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2030 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) || 2031 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 2032 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264", 2033 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2034 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 2035 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265", 2036 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2037 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 2038 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 2039 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2040 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) { 2041 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1", 2042 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2043 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 2044 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 2045 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2046 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2047 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf", 2048 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2049 } else { 2050 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx", 2051 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2052 } 2053 m_debug.infile = fopen (m_debug.infile_name, "ab"); 2054 if (!m_debug.infile) { 2055 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); 2056 m_debug.infile_name[0] = '\0'; 2057 return -1; 2058 } 2059 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 2060 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2061 struct ivf_file_header { 2062 OMX_U8 signature[4]; //='DKIF'; 2063 OMX_U8 version ; //= 0; 2064 OMX_U8 headersize ; //= 32; 2065 OMX_U32 FourCC; 2066 OMX_U8 width; 2067 OMX_U8 height; 2068 OMX_U32 rate; 2069 OMX_U32 scale; 2070 OMX_U32 length; 2071 OMX_U8 unused[4]; 2072 } file_header; 2073 2074 memset((void *)&file_header,0,sizeof(file_header)); 2075 file_header.signature[0] = 'D'; 2076 file_header.signature[1] = 'K'; 2077 file_header.signature[2] = 'I'; 2078 file_header.signature[3] = 'F'; 2079 file_header.version = 0; 2080 file_header.headersize = 32; 2081 switch (drv_ctx.decoder_format) { 2082 case VDEC_CODECTYPE_VP8: 2083 file_header.FourCC = 0x30385056; 2084 break; 2085 case VDEC_CODECTYPE_VP9: 2086 file_header.FourCC = 0x30395056; 2087 break; 2088 default: 2089 DEBUG_PRINT_ERROR("unsupported format for VP8/VP9"); 2090 break; 2091 } 2092 fwrite((const char *)&file_header, 2093 sizeof(file_header),1,m_debug.infile); 2094 } 2095 } 2096 if (m_debug.infile && buffer_addr && buffer_len) { 2097 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 2098 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 2099 struct vpx_ivf_frame_header { 2100 OMX_U32 framesize; 2101 OMX_U32 timestamp_lo; 2102 OMX_U32 timestamp_hi; 2103 } vpx_frame_header; 2104 vpx_frame_header.framesize = buffer_len; 2105 /* Currently FW doesn't use timestamp values */ 2106 vpx_frame_header.timestamp_lo = 0; 2107 vpx_frame_header.timestamp_hi = 0; 2108 fwrite((const char *)&vpx_frame_header, 2109 sizeof(vpx_frame_header),1,m_debug.infile); 2110 } 2111 fwrite(buffer_addr, buffer_len, 1, m_debug.infile); 2112 } 2113 return 0; 2114} 2115 2116int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) { 2117 int buf_index = 0; 2118 char *temp = NULL; 2119 2120 if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen) 2121 return 0; 2122 2123 if (m_debug.out_buffer_log && !m_debug.outfile) { 2124 snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv", 2125 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2126 m_debug.outfile = fopen (m_debug.outfile_name, "ab"); 2127 if (!m_debug.outfile) { 2128 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc); 2129 m_debug.outfile_name[0] = '\0'; 2130 return -1; 2131 } 2132 } 2133 2134 if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) { 2135 snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta", 2136 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2137 snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta", 2138 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); 2139 m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab"); 2140 m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab"); 2141 if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) { 2142 DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc); 2143 m_debug.out_ymetafile_name[0] = '\0'; 2144 m_debug.out_uvmetafile_name[0] = '\0'; 2145 return -1; 2146 } 2147 } 2148 2149 buf_index = buffer - m_out_mem_ptr; 2150 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 2151 2152 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC || 2153 drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 2154 DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)", 2155 drv_ctx.video_resolution.frame_width, 2156 drv_ctx.video_resolution.frame_height); 2157 2158 if (m_debug.outfile) 2159 fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile); 2160 2161 if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) { 2162 unsigned int width = 0, height = 0; 2163 unsigned int y_plane, y_meta_plane; 2164 int y_stride = 0, y_sclines = 0; 2165 int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0; 2166 int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC; 2167 int i; 2168 int bytes_written = 0; 2169 2170 width = drv_ctx.video_resolution.frame_width; 2171 height = drv_ctx.video_resolution.frame_height; 2172 y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); 2173 y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); 2174 y_stride = VENUS_Y_STRIDE(color_fmt, width); 2175 y_sclines = VENUS_Y_SCANLINES(color_fmt, height); 2176 uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); 2177 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); 2178 2179 y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096); 2180 y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); 2181 2182 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 2183 for (i = 0; i < y_meta_scanlines; i++) { 2184 bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file); 2185 temp += y_meta_stride; 2186 } 2187 2188 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane; 2189 for(i = 0; i < uv_meta_scanlines; i++) { 2190 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file); 2191 temp += uv_meta_stride; 2192 } 2193 } 2194 } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 2195 int stride = drv_ctx.video_resolution.stride; 2196 int scanlines = drv_ctx.video_resolution.scan_lines; 2197 if (m_smoothstreaming_mode) { 2198 stride = drv_ctx.video_resolution.frame_width; 2199 scanlines = drv_ctx.video_resolution.frame_height; 2200 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1)); 2201 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1)); 2202 } 2203 unsigned i; 2204 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)", 2205 drv_ctx.video_resolution.frame_width, 2206 drv_ctx.video_resolution.frame_height, stride, scanlines); 2207 int bytes_written = 0; 2208 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { 2209 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 2210 temp += stride; 2211 } 2212 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; 2213 int stride_c = stride; 2214 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { 2215 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); 2216 temp += stride_c; 2217 } 2218 } 2219 return 0; 2220} 2221 2222/* ====================================================================== 2223 FUNCTION 2224 omx_vdec::ComponentInit 2225 2226 DESCRIPTION 2227 Initialize the component. 2228 2229 PARAMETERS 2230 ctxt -- Context information related to the self. 2231 id -- Event identifier. This could be any of the following: 2232 1. Command completion event 2233 2. Buffer done callback event 2234 3. Frame done callback event 2235 2236 RETURN VALUE 2237 None. 2238 2239 ========================================================================== */ 2240OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 2241{ 2242 2243 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2244 struct v4l2_fmtdesc fdesc; 2245 struct v4l2_format fmt; 2246 struct v4l2_requestbuffers bufreq; 2247 struct v4l2_control control; 2248 struct v4l2_frmsizeenum frmsize; 2249 unsigned int alignment = 0,buffer_size = 0; 2250 int fds[2]; 2251 int r,ret=0; 2252 bool codec_ambiguous = false; 2253 OMX_STRING device_name = (OMX_STRING)"/dev/video32"; 2254 char property_value[PROPERTY_VALUE_MAX] = {0}; 2255 FILE *soc_file = NULL; 2256 char buffer[10]; 2257 2258#ifdef _ANDROID_ 2259 char platform_name[PROPERTY_VALUE_MAX]; 2260 property_get("ro.board.platform", platform_name, "0"); 2261 if (!strncmp(platform_name, "msm8610", 7)) { 2262 device_name = (OMX_STRING)"/dev/video/q6_dec"; 2263 is_q6_platform = true; 2264 maxSmoothStreamingWidth = 1280; 2265 maxSmoothStreamingHeight = 720; 2266 } 2267#endif 2268 2269 is_thulium_v1 = false; 2270 soc_file = fopen("/sys/devices/soc0/soc_id", "r"); 2271 if (soc_file) { 2272 fread(buffer, 1, 4, soc_file); 2273 fclose(soc_file); 2274 if (atoi(buffer) == 246) { 2275 soc_file = fopen("/sys/devices/soc0/revision", "r"); 2276 if (soc_file) { 2277 fread(buffer, 1, 4, soc_file); 2278 fclose(soc_file); 2279 if (atoi(buffer) == 1) { 2280 is_thulium_v1 = true; 2281 DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE"); 2282 } 2283 } 2284 } 2285 } 2286 2287#ifdef _ANDROID_ 2288 /* 2289 * turn off frame parsing for Android by default. 2290 * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode 2291 */ 2292 arbitrary_bytes = false; 2293 property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 2294 if (atoi(property_value)) { 2295 DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command"); 2296 arbitrary_bytes = true; 2297 } 2298#endif 2299 2300 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure", 2301 OMX_MAX_STRINGNAME_SIZE)) { 2302 secure_mode = true; 2303 arbitrary_bytes = false; 2304 role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; 2305 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure", 2306 OMX_MAX_STRINGNAME_SIZE)) { 2307 secure_mode = true; 2308 arbitrary_bytes = false; 2309 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2"; 2310 } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure", 2311 OMX_MAX_STRINGNAME_SIZE)) { 2312 secure_mode = true; 2313 arbitrary_bytes = false; 2314 role = (OMX_STRING)"OMX.qcom.video.decoder.hevc"; 2315 } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure", 2316 OMX_MAX_STRINGNAME_SIZE)) { 2317 secure_mode = true; 2318 arbitrary_bytes = false; 2319 role = (OMX_STRING)"OMX.qcom.video.decoder.vc1"; 2320 } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure", 2321 OMX_MAX_STRINGNAME_SIZE)) { 2322 secure_mode = true; 2323 arbitrary_bytes = false; 2324 role = (OMX_STRING)"OMX.qcom.video.decoder.wmv"; 2325 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure", 2326 OMX_MAX_STRINGNAME_SIZE)) { 2327 secure_mode = true; 2328 arbitrary_bytes = false; 2329 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4"; 2330 } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure", 2331 OMX_MAX_STRINGNAME_SIZE)) { 2332 secure_mode = true; 2333 arbitrary_bytes = false; 2334 role = (OMX_STRING)"OMX.qcom.video.decoder.vp9"; 2335 } 2336 else if (!strncmp(role, "OMX.qcom.video.decoder.vp8.secure", 2337 OMX_MAX_STRINGNAME_SIZE)) { 2338 secure_mode = true; 2339 arbitrary_bytes = false; 2340 role = (OMX_STRING)"OMX.qcom.video.decoder.vp8"; 2341 } 2342 2343 drv_ctx.video_driver_fd = open(device_name, O_RDWR); 2344 2345 DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd); 2346 2347 if (drv_ctx.video_driver_fd < 0) { 2348 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno); 2349 return OMX_ErrorInsufficientResources; 2350 } 2351 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; 2352 drv_ctx.frame_rate.fps_denominator = 1; 2353 operating_frame_rate = DEFAULT_FPS; 2354 m_poll_efd = eventfd(0, 0); 2355 if (m_poll_efd < 0) { 2356 DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno)); 2357 return OMX_ErrorInsufficientResources; 2358 } 2359 ret = subscribe_to_events(drv_ctx.video_driver_fd); 2360 if (!ret) { 2361 async_thread_created = true; 2362 ret = pthread_create(&async_thread_id,0,async_message_thread,this); 2363 } 2364 if (ret) { 2365 DEBUG_PRINT_ERROR("Failed to create async_message_thread"); 2366 async_thread_created = false; 2367 return OMX_ErrorInsufficientResources; 2368 } 2369 2370#ifdef OUTPUT_EXTRADATA_LOG 2371 outputExtradataFile = fopen (output_extradata_filename, "ab"); 2372#endif 2373 2374 // Copy the role information which provides the decoder kind 2375 strlcpy(drv_ctx.kind,role,128); 2376 2377 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ 2378 OMX_MAX_STRINGNAME_SIZE)) { 2379 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ 2380 OMX_MAX_STRINGNAME_SIZE); 2381 drv_ctx.timestamp_adjust = true; 2382 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; 2383 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 2384 output_capability=V4L2_PIX_FMT_MPEG4; 2385 /*Initialize Start Code for MPEG4*/ 2386 codec_type_parse = CODEC_TYPE_MPEG4; 2387 m_frame_parser.init_start_codes(codec_type_parse); 2388 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ 2389 OMX_MAX_STRINGNAME_SIZE)) { 2390 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ 2391 OMX_MAX_STRINGNAME_SIZE); 2392 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; 2393 output_capability = V4L2_PIX_FMT_MPEG2; 2394 eCompressionFormat = OMX_VIDEO_CodingMPEG2; 2395 /*Initialize Start Code for MPEG2*/ 2396 codec_type_parse = CODEC_TYPE_MPEG2; 2397 m_frame_parser.init_start_codes(codec_type_parse); 2398 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ 2399 OMX_MAX_STRINGNAME_SIZE)) { 2400 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 2401 DEBUG_PRINT_LOW("H263 Decoder selected"); 2402 drv_ctx.decoder_format = VDEC_CODECTYPE_H263; 2403 eCompressionFormat = OMX_VIDEO_CodingH263; 2404 output_capability = V4L2_PIX_FMT_H263; 2405 codec_type_parse = CODEC_TYPE_H263; 2406 m_frame_parser.init_start_codes(codec_type_parse); 2407 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ 2408 OMX_MAX_STRINGNAME_SIZE)) { 2409 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2410 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); 2411 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; 2412 output_capability = V4L2_PIX_FMT_DIVX_311; 2413 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2414 codec_type_parse = CODEC_TYPE_DIVX; 2415 m_frame_parser.init_start_codes(codec_type_parse); 2416 2417 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 2418 OMX_MAX_STRINGNAME_SIZE)) { 2419 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2420 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); 2421 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; 2422 output_capability = V4L2_PIX_FMT_DIVX; 2423 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2424 codec_type_parse = CODEC_TYPE_DIVX; 2425 codec_ambiguous = true; 2426 m_frame_parser.init_start_codes(codec_type_parse); 2427 2428 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ 2429 OMX_MAX_STRINGNAME_SIZE)) { 2430 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2431 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); 2432 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; 2433 output_capability = V4L2_PIX_FMT_DIVX; 2434 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 2435 codec_type_parse = CODEC_TYPE_DIVX; 2436 codec_ambiguous = true; 2437 m_frame_parser.init_start_codes(codec_type_parse); 2438 2439 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ 2440 OMX_MAX_STRINGNAME_SIZE)) { 2441 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 2442 drv_ctx.decoder_format = VDEC_CODECTYPE_H264; 2443 output_capability=V4L2_PIX_FMT_H264; 2444 eCompressionFormat = OMX_VIDEO_CodingAVC; 2445 codec_type_parse = CODEC_TYPE_H264; 2446 m_frame_parser.init_start_codes(codec_type_parse); 2447 m_frame_parser.init_nal_length(nal_length); 2448 if (is_thulium_v1) { 2449 arbitrary_bytes = true; 2450 DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264"); 2451 } 2452 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\ 2453 OMX_MAX_STRINGNAME_SIZE)) { 2454 strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 2455 drv_ctx.decoder_format = VDEC_CODECTYPE_MVC; 2456 output_capability = V4L2_PIX_FMT_H264_MVC; 2457 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC; 2458 codec_type_parse = CODEC_TYPE_H264; 2459 m_frame_parser.init_start_codes(codec_type_parse); 2460 m_frame_parser.init_nal_length(nal_length); 2461 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ 2462 OMX_MAX_STRINGNAME_SIZE)) { 2463 strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 2464 drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; 2465 output_capability = V4L2_PIX_FMT_HEVC; 2466 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; 2467 codec_type_parse = CODEC_TYPE_HEVC; 2468 m_frame_parser.init_start_codes(codec_type_parse); 2469 m_frame_parser.init_nal_length(nal_length); 2470 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ 2471 OMX_MAX_STRINGNAME_SIZE)) { 2472 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2473 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; 2474 eCompressionFormat = OMX_VIDEO_CodingWMV; 2475 codec_type_parse = CODEC_TYPE_VC1; 2476 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; 2477 m_frame_parser.init_start_codes(codec_type_parse); 2478 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ 2479 OMX_MAX_STRINGNAME_SIZE)) { 2480 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2481 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; 2482 eCompressionFormat = OMX_VIDEO_CodingWMV; 2483 codec_type_parse = CODEC_TYPE_VC1; 2484 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; 2485 m_frame_parser.init_start_codes(codec_type_parse); 2486 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ 2487 OMX_MAX_STRINGNAME_SIZE)) { 2488 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 2489 drv_ctx.decoder_format = VDEC_CODECTYPE_VP8; 2490 output_capability = V4L2_PIX_FMT_VP8; 2491 eCompressionFormat = OMX_VIDEO_CodingVP8; 2492 codec_type_parse = CODEC_TYPE_VP8; 2493 arbitrary_bytes = false; 2494 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", \ 2495 OMX_MAX_STRINGNAME_SIZE)) { 2496 strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 2497 drv_ctx.decoder_format = VDEC_CODECTYPE_VP9; 2498 output_capability = V4L2_PIX_FMT_VP9; 2499 eCompressionFormat = OMX_VIDEO_CodingVP9; 2500 codec_type_parse = CODEC_TYPE_VP9; 2501 arbitrary_bytes = false; 2502 } else { 2503 DEBUG_PRINT_ERROR("ERROR:Unknown Component"); 2504 eRet = OMX_ErrorInvalidComponentName; 2505 } 2506 2507 if (eRet == OMX_ErrorNone) { 2508 OMX_COLOR_FORMATTYPE dest_color_format; 2509 if (m_disable_ubwc_mode) { 2510 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 2511 } else { 2512 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC; 2513 } 2514 if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC) 2515 dest_color_format = (OMX_COLOR_FORMATTYPE) 2516 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 2517 else 2518 dest_color_format = (OMX_COLOR_FORMATTYPE) 2519 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 2520 if (!client_buffers.set_color_format(dest_color_format)) { 2521 DEBUG_PRINT_ERROR("Setting color format failed"); 2522 eRet = OMX_ErrorInsufficientResources; 2523 } 2524 2525 dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8; 2526 m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; 2527 2528 if (m_disable_ubwc_mode) { 2529 capture_capability = V4L2_PIX_FMT_NV12; 2530 } else { 2531 capture_capability = V4L2_PIX_FMT_NV12_UBWC; 2532 } 2533 2534 struct v4l2_capability cap; 2535 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); 2536 if (ret) { 2537 DEBUG_PRINT_ERROR("Failed to query capabilities"); 2538 /*TODO: How to handle this case */ 2539 } else { 2540 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," 2541 " version = %d, capabilities = %x", cap.driver, cap.card, 2542 cap.bus_info, cap.version, cap.capabilities); 2543 } 2544 ret=0; 2545 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2546 fdesc.index=0; 2547 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 2548 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 2549 fdesc.pixelformat, fdesc.flags); 2550 fdesc.index++; 2551 } 2552 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2553 fdesc.index=0; 2554 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 2555 2556 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 2557 fdesc.pixelformat, fdesc.flags); 2558 fdesc.index++; 2559 } 2560 m_extradata_info.output_crop_rect.nLeft = 0; 2561 m_extradata_info.output_crop_rect.nTop = 0; 2562 m_extradata_info.output_crop_rect.nWidth = 320; 2563 m_extradata_info.output_crop_rect.nHeight = 240; 2564 update_resolution(320, 240, 320, 240); 2565 2566 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2567 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2568 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2569 fmt.fmt.pix_mp.pixelformat = output_capability; 2570 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2571 if (ret) { 2572 /*TODO: How to handle this case */ 2573 DEBUG_PRINT_ERROR("Failed to set format on output port"); 2574 return OMX_ErrorInsufficientResources; 2575 } 2576 DEBUG_PRINT_HIGH("Set Format was successful"); 2577 if (codec_ambiguous) { 2578 if (output_capability == V4L2_PIX_FMT_DIVX) { 2579 struct v4l2_control divx_ctrl; 2580 2581 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { 2582 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; 2583 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { 2584 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; 2585 } else { 2586 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; 2587 } 2588 2589 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; 2590 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); 2591 if (ret) { 2592 DEBUG_PRINT_ERROR("Failed to set divx version"); 2593 } 2594 } else { 2595 DEBUG_PRINT_ERROR("Codec should not be ambiguous"); 2596 } 2597 } 2598 2599 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR); 2600 m_conceal_color= atoi(property_value); 2601 DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color); 2602 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR; 2603 control.value = m_conceal_color; 2604 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2605 if (ret) { 2606 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret); 2607 } 2608 2609 //Get the hardware capabilities 2610 memset((void *)&frmsize,0,sizeof(frmsize)); 2611 frmsize.index = 0; 2612 frmsize.pixel_format = output_capability; 2613 ret = ioctl(drv_ctx.video_driver_fd, 2614 VIDIOC_ENUM_FRAMESIZES, &frmsize); 2615 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 2616 DEBUG_PRINT_ERROR("Failed to get framesizes"); 2617 return OMX_ErrorHardware; 2618 } 2619 2620 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 2621 m_decoder_capability.min_width = frmsize.stepwise.min_width; 2622 m_decoder_capability.max_width = frmsize.stepwise.max_width; 2623 m_decoder_capability.min_height = frmsize.stepwise.min_height; 2624 m_decoder_capability.max_height = frmsize.stepwise.max_height; 2625 } 2626 2627 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 2628 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2629 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2630 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2631 fmt.fmt.pix_mp.pixelformat = capture_capability; 2632 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2633 if (ret) { 2634 /*TODO: How to handle this case */ 2635 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 2636 } 2637 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE)); 2638 framesize.nWidth = drv_ctx.video_resolution.frame_width; 2639 framesize.nHeight = drv_ctx.video_resolution.frame_height; 2640 2641 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE)); 2642 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 2643 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 2644 2645 DEBUG_PRINT_HIGH("Set Format was successful"); 2646 if (secure_mode) { 2647 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 2648 control.value = 1; 2649 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret); 2650 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 2651 if (ret) { 2652 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret); 2653 return OMX_ErrorInsufficientResources; 2654 } 2655 } 2656 if (output_capability == V4L2_PIX_FMT_H264_MVC) { 2657 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT; 2658 control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM; 2659 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2660 if (ret) { 2661 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout"); 2662 return OMX_ErrorInsufficientResources; 2663 } 2664 } 2665 2666 if (is_thulium_v1) { 2667 eRet = enable_smoothstreaming(); 2668 if (eRet != OMX_ErrorNone) { 2669 DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver"); 2670 return eRet; 2671 } 2672 } 2673 2674 /*Get the Buffer requirements for input and output ports*/ 2675 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; 2676 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 2677 2678 if (secure_mode) { 2679 drv_ctx.op_buf.alignment = SECURE_ALIGN; 2680 drv_ctx.ip_buf.alignment = SECURE_ALIGN; 2681 } else { 2682 drv_ctx.op_buf.alignment = SZ_4K; 2683 drv_ctx.ip_buf.alignment = SZ_4K; 2684 } 2685 2686 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 2687 drv_ctx.extradata = 0; 2688 drv_ctx.picture_order = VDEC_ORDER_DISPLAY; 2689 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 2690 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 2691 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 2692 drv_ctx.idr_only_decoding = 0; 2693 2694#ifdef _ANDROID_ 2695 property_get("vidc.dec.enable.downscalar",property_value,"0"); 2696 if (atoi(property_value)) { 2697 m_enable_downscalar = atoi(property_value); 2698 property_get("vidc.dec.downscalar_width",property_value,"0"); 2699 if (atoi(property_value)) { 2700 m_downscalar_width = atoi(property_value); 2701 } 2702 property_get("vidc.dec.downscalar_height",property_value,"0"); 2703 if (atoi(property_value)) { 2704 m_downscalar_height = atoi(property_value); 2705 } 2706 2707 if (m_downscalar_width < m_decoder_capability.min_width || 2708 m_downscalar_height < m_decoder_capability.min_height) { 2709 m_downscalar_width = 0; 2710 m_downscalar_height = 0; 2711 } 2712 2713 DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n", 2714 m_downscalar_width, m_downscalar_height); 2715 } 2716 property_get("vidc.disable.split.mode",property_value,"0"); 2717 m_disable_split_mode = atoi(property_value); 2718 DEBUG_PRINT_HIGH("split mode is %s", m_disable_split_mode ? "disabled" : "enabled"); 2719#endif 2720 m_state = OMX_StateLoaded; 2721#ifdef DEFAULT_EXTRADATA 2722 enable_extradata(DEFAULT_EXTRADATA, true, true); 2723#endif 2724 eRet = get_buffer_req(&drv_ctx.ip_buf); 2725 DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size); 2726 get_buffer_req(&drv_ctx.op_buf); 2727 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2728 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC || 2729 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2730 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; 2731 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); 2732 h264_scratch.nFilledLen = 0; 2733 h264_scratch.nOffset = 0; 2734 2735 if (h264_scratch.pBuffer == NULL) { 2736 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed "); 2737 return OMX_ErrorInsufficientResources; 2738 } 2739 } 2740 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 2741 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) { 2742 if (m_frame_parser.mutils == NULL) { 2743 m_frame_parser.mutils = new H264_Utils(); 2744 if (m_frame_parser.mutils == NULL) { 2745 DEBUG_PRINT_ERROR("parser utils Allocation failed "); 2746 eRet = OMX_ErrorInsufficientResources; 2747 } else { 2748 m_frame_parser.mutils->initialize_frame_checking_environment(); 2749 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); 2750 } 2751 } 2752 2753 h264_parser = new h264_stream_parser(); 2754 if (!h264_parser) { 2755 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); 2756 eRet = OMX_ErrorInsufficientResources; 2757 } 2758 } 2759 2760 if (pipe(fds)) { 2761 DEBUG_PRINT_ERROR("pipe creation failed"); 2762 eRet = OMX_ErrorInsufficientResources; 2763 } else { 2764 m_pipe_in = fds[0]; 2765 m_pipe_out = fds[1]; 2766 msg_thread_created = true; 2767 r = pthread_create(&msg_thread_id,0,message_thread_dec,this); 2768 2769 if (r < 0) { 2770 DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed"); 2771 msg_thread_created = false; 2772 eRet = OMX_ErrorInsufficientResources; 2773 } 2774 } 2775 } 2776 2777 if (eRet != OMX_ErrorNone) { 2778 DEBUG_PRINT_ERROR("Component Init Failed"); 2779 } else { 2780 DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d", 2781 drv_ctx.video_driver_fd); 2782 } 2783 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); 2784 return eRet; 2785} 2786 2787/* ====================================================================== 2788 FUNCTION 2789 omx_vdec::GetComponentVersion 2790 2791 DESCRIPTION 2792 Returns the component version. 2793 2794 PARAMETERS 2795 TBD. 2796 2797 RETURN VALUE 2798 OMX_ErrorNone. 2799 2800 ========================================================================== */ 2801OMX_ERRORTYPE omx_vdec::get_component_version 2802( 2803 OMX_IN OMX_HANDLETYPE hComp, 2804 OMX_OUT OMX_STRING componentName, 2805 OMX_OUT OMX_VERSIONTYPE* componentVersion, 2806 OMX_OUT OMX_VERSIONTYPE* specVersion, 2807 OMX_OUT OMX_UUIDTYPE* componentUUID 2808 ) 2809{ 2810 (void) hComp; 2811 (void) componentName; 2812 (void) componentVersion; 2813 (void) componentUUID; 2814 if (m_state == OMX_StateInvalid) { 2815 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State"); 2816 return OMX_ErrorInvalidState; 2817 } 2818 /* TBD -- Return the proper version */ 2819 if (specVersion) { 2820 specVersion->nVersion = OMX_SPEC_VERSION; 2821 } 2822 return OMX_ErrorNone; 2823} 2824/* ====================================================================== 2825 FUNCTION 2826 omx_vdec::SendCommand 2827 2828 DESCRIPTION 2829 Returns zero if all the buffers released.. 2830 2831 PARAMETERS 2832 None. 2833 2834 RETURN VALUE 2835 true/false 2836 2837 ========================================================================== */ 2838OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 2839 OMX_IN OMX_COMMANDTYPE cmd, 2840 OMX_IN OMX_U32 param1, 2841 OMX_IN OMX_PTR cmdData 2842 ) 2843{ 2844 (void) hComp; 2845 (void) cmdData; 2846 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client"); 2847 if (m_state == OMX_StateInvalid) { 2848 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State"); 2849 return OMX_ErrorInvalidState; 2850 } 2851 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX 2852 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) { 2853 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush " 2854 "to invalid port: %u", (unsigned int)param1); 2855 return OMX_ErrorBadPortIndex; 2856 } 2857 2858 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 2859 sem_wait(&m_cmd_lock); 2860 DEBUG_PRINT_LOW("send_command: Command Processed"); 2861 return OMX_ErrorNone; 2862} 2863 2864/* ====================================================================== 2865 FUNCTION 2866 omx_vdec::SendCommand 2867 2868 DESCRIPTION 2869 Returns zero if all the buffers released.. 2870 2871 PARAMETERS 2872 None. 2873 2874 RETURN VALUE 2875 true/false 2876 2877 ========================================================================== */ 2878OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 2879 OMX_IN OMX_COMMANDTYPE cmd, 2880 OMX_IN OMX_U32 param1, 2881 OMX_IN OMX_PTR cmdData 2882 ) 2883{ 2884 (void) hComp; 2885 (void) cmdData; 2886 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2887 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 2888 int bFlag = 1,sem_posted = 0,ret=0; 2889 2890 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd); 2891 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d", 2892 m_state, eState); 2893 2894 if (cmd == OMX_CommandStateSet) { 2895 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); 2896 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); 2897 /***************************/ 2898 /* Current State is Loaded */ 2899 /***************************/ 2900 if (m_state == OMX_StateLoaded) { 2901 if (eState == OMX_StateIdle) { 2902 //if all buffers are allocated or all ports disabled 2903 if (allocate_done() || 2904 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) { 2905 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); 2906 } else { 2907 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); 2908 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 2909 // Skip the event notification 2910 bFlag = 0; 2911 } 2912 } 2913 /* Requesting transition from Loaded to Loaded */ 2914 else if (eState == OMX_StateLoaded) { 2915 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded"); 2916 post_event(OMX_EventError,OMX_ErrorSameState,\ 2917 OMX_COMPONENT_GENERATE_EVENT); 2918 eRet = OMX_ErrorSameState; 2919 } 2920 /* Requesting transition from Loaded to WaitForResources */ 2921 else if (eState == OMX_StateWaitForResources) { 2922 /* Since error is None , we will post an event 2923 at the end of this function definition */ 2924 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); 2925 } 2926 /* Requesting transition from Loaded to Executing */ 2927 else if (eState == OMX_StateExecuting) { 2928 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing"); 2929 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2930 OMX_COMPONENT_GENERATE_EVENT); 2931 eRet = OMX_ErrorIncorrectStateTransition; 2932 } 2933 /* Requesting transition from Loaded to Pause */ 2934 else if (eState == OMX_StatePause) { 2935 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause"); 2936 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2937 OMX_COMPONENT_GENERATE_EVENT); 2938 eRet = OMX_ErrorIncorrectStateTransition; 2939 } 2940 /* Requesting transition from Loaded to Invalid */ 2941 else if (eState == OMX_StateInvalid) { 2942 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid"); 2943 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2944 eRet = OMX_ErrorInvalidState; 2945 } else { 2946 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\ 2947 eState); 2948 eRet = OMX_ErrorBadParameter; 2949 } 2950 } 2951 2952 /***************************/ 2953 /* Current State is IDLE */ 2954 /***************************/ 2955 else if (m_state == OMX_StateIdle) { 2956 if (eState == OMX_StateLoaded) { 2957 if (release_done()) { 2958 /* 2959 * Since error is None , we will post an event at the end 2960 * of this function definition 2961 * Reset buffer requirements here to ensure setting buffer requirement 2962 * when component move to executing state from loaded state via Idle. 2963 */ 2964 drv_ctx.op_buf.buffer_size = 0; 2965 drv_ctx.op_buf.actualcount = 0; 2966 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded"); 2967 } else { 2968 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending"); 2969 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 2970 // Skip the event notification 2971 bFlag = 0; 2972 } 2973 } 2974 /* Requesting transition from Idle to Executing */ 2975 else if (eState == OMX_StateExecuting) { 2976 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2977 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); 2978 bFlag = 1; 2979 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2980 m_state=OMX_StateExecuting; 2981 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful"); 2982 } 2983 /* Requesting transition from Idle to Idle */ 2984 else if (eState == OMX_StateIdle) { 2985 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle"); 2986 post_event(OMX_EventError,OMX_ErrorSameState,\ 2987 OMX_COMPONENT_GENERATE_EVENT); 2988 eRet = OMX_ErrorSameState; 2989 } 2990 /* Requesting transition from Idle to WaitForResources */ 2991 else if (eState == OMX_StateWaitForResources) { 2992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources"); 2993 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2994 OMX_COMPONENT_GENERATE_EVENT); 2995 eRet = OMX_ErrorIncorrectStateTransition; 2996 } 2997 /* Requesting transition from Idle to Pause */ 2998 else if (eState == OMX_StatePause) { 2999 /*To pause the Video core we need to start the driver*/ 3000 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 3001 NULL) < */0) { 3002 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED"); 3003 omx_report_error (); 3004 eRet = OMX_ErrorHardware; 3005 } else { 3006 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 3007 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause"); 3008 bFlag = 0; 3009 } 3010 } 3011 /* Requesting transition from Idle to Invalid */ 3012 else if (eState == OMX_StateInvalid) { 3013 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid"); 3014 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3015 eRet = OMX_ErrorInvalidState; 3016 } else { 3017 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState); 3018 eRet = OMX_ErrorBadParameter; 3019 } 3020 } 3021 3022 /******************************/ 3023 /* Current State is Executing */ 3024 /******************************/ 3025 else if (m_state == OMX_StateExecuting) { 3026 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting"); 3027 /* Requesting transition from Executing to Idle */ 3028 if (eState == OMX_StateIdle) { 3029 /* Since error is None , we will post an event 3030 at the end of this function definition 3031 */ 3032 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle"); 3033 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 3034 if (!sem_posted) { 3035 sem_posted = 1; 3036 sem_post (&m_cmd_lock); 3037 execute_omx_flush(OMX_ALL); 3038 } 3039 bFlag = 0; 3040 } 3041 /* Requesting transition from Executing to Paused */ 3042 else if (eState == OMX_StatePause) { 3043 DEBUG_PRINT_LOW("PAUSE Command Issued"); 3044 m_state = OMX_StatePause; 3045 bFlag = 1; 3046 } 3047 /* Requesting transition from Executing to Loaded */ 3048 else if (eState == OMX_StateLoaded) { 3049 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded"); 3050 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3051 OMX_COMPONENT_GENERATE_EVENT); 3052 eRet = OMX_ErrorIncorrectStateTransition; 3053 } 3054 /* Requesting transition from Executing to WaitForResources */ 3055 else if (eState == OMX_StateWaitForResources) { 3056 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources"); 3057 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3058 OMX_COMPONENT_GENERATE_EVENT); 3059 eRet = OMX_ErrorIncorrectStateTransition; 3060 } 3061 /* Requesting transition from Executing to Executing */ 3062 else if (eState == OMX_StateExecuting) { 3063 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing"); 3064 post_event(OMX_EventError,OMX_ErrorSameState,\ 3065 OMX_COMPONENT_GENERATE_EVENT); 3066 eRet = OMX_ErrorSameState; 3067 } 3068 /* Requesting transition from Executing to Invalid */ 3069 else if (eState == OMX_StateInvalid) { 3070 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid"); 3071 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3072 eRet = OMX_ErrorInvalidState; 3073 } else { 3074 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState); 3075 eRet = OMX_ErrorBadParameter; 3076 } 3077 } 3078 /***************************/ 3079 /* Current State is Pause */ 3080 /***************************/ 3081 else if (m_state == OMX_StatePause) { 3082 /* Requesting transition from Pause to Executing */ 3083 if (eState == OMX_StateExecuting) { 3084 DEBUG_PRINT_LOW("Pause --> Executing"); 3085 m_state = OMX_StateExecuting; 3086 bFlag = 1; 3087 } 3088 /* Requesting transition from Pause to Idle */ 3089 else if (eState == OMX_StateIdle) { 3090 /* Since error is None , we will post an event 3091 at the end of this function definition */ 3092 DEBUG_PRINT_LOW("Pause --> Idle"); 3093 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 3094 if (!sem_posted) { 3095 sem_posted = 1; 3096 sem_post (&m_cmd_lock); 3097 execute_omx_flush(OMX_ALL); 3098 } 3099 bFlag = 0; 3100 } 3101 /* Requesting transition from Pause to loaded */ 3102 else if (eState == OMX_StateLoaded) { 3103 DEBUG_PRINT_ERROR("Pause --> loaded"); 3104 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3105 OMX_COMPONENT_GENERATE_EVENT); 3106 eRet = OMX_ErrorIncorrectStateTransition; 3107 } 3108 /* Requesting transition from Pause to WaitForResources */ 3109 else if (eState == OMX_StateWaitForResources) { 3110 DEBUG_PRINT_ERROR("Pause --> WaitForResources"); 3111 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3112 OMX_COMPONENT_GENERATE_EVENT); 3113 eRet = OMX_ErrorIncorrectStateTransition; 3114 } 3115 /* Requesting transition from Pause to Pause */ 3116 else if (eState == OMX_StatePause) { 3117 DEBUG_PRINT_ERROR("Pause --> Pause"); 3118 post_event(OMX_EventError,OMX_ErrorSameState,\ 3119 OMX_COMPONENT_GENERATE_EVENT); 3120 eRet = OMX_ErrorSameState; 3121 } 3122 /* Requesting transition from Pause to Invalid */ 3123 else if (eState == OMX_StateInvalid) { 3124 DEBUG_PRINT_ERROR("Pause --> Invalid"); 3125 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3126 eRet = OMX_ErrorInvalidState; 3127 } else { 3128 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState); 3129 eRet = OMX_ErrorBadParameter; 3130 } 3131 } 3132 /***************************/ 3133 /* Current State is WaitForResources */ 3134 /***************************/ 3135 else if (m_state == OMX_StateWaitForResources) { 3136 /* Requesting transition from WaitForResources to Loaded */ 3137 if (eState == OMX_StateLoaded) { 3138 /* Since error is None , we will post an event 3139 at the end of this function definition */ 3140 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded"); 3141 } 3142 /* Requesting transition from WaitForResources to WaitForResources */ 3143 else if (eState == OMX_StateWaitForResources) { 3144 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources"); 3145 post_event(OMX_EventError,OMX_ErrorSameState, 3146 OMX_COMPONENT_GENERATE_EVENT); 3147 eRet = OMX_ErrorSameState; 3148 } 3149 /* Requesting transition from WaitForResources to Executing */ 3150 else if (eState == OMX_StateExecuting) { 3151 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing"); 3152 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3153 OMX_COMPONENT_GENERATE_EVENT); 3154 eRet = OMX_ErrorIncorrectStateTransition; 3155 } 3156 /* Requesting transition from WaitForResources to Pause */ 3157 else if (eState == OMX_StatePause) { 3158 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause"); 3159 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 3160 OMX_COMPONENT_GENERATE_EVENT); 3161 eRet = OMX_ErrorIncorrectStateTransition; 3162 } 3163 /* Requesting transition from WaitForResources to Invalid */ 3164 else if (eState == OMX_StateInvalid) { 3165 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid"); 3166 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 3167 eRet = OMX_ErrorInvalidState; 3168 } 3169 /* Requesting transition from WaitForResources to Loaded - 3170 is NOT tested by Khronos TS */ 3171 3172 } else { 3173 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState); 3174 eRet = OMX_ErrorBadParameter; 3175 } 3176 } 3177 /********************************/ 3178 /* Current State is Invalid */ 3179 /*******************************/ 3180 else if (m_state == OMX_StateInvalid) { 3181 /* State Transition from Inavlid to any state */ 3182 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources 3183 || OMX_StateIdle || OMX_StateExecuting 3184 || OMX_StatePause || OMX_StateInvalid)) { 3185 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded"); 3186 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 3187 OMX_COMPONENT_GENERATE_EVENT); 3188 eRet = OMX_ErrorInvalidState; 3189 } 3190 } else if (cmd == OMX_CommandFlush) { 3191 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued" 3192 "with param1: %u", (unsigned int)param1); 3193#ifdef _MSM8974_ 3194 send_codec_config(); 3195#endif 3196 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX || 3197 param1 == OMX_ALL)) { 3198 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) { 3199 struct timespec ts; 3200 3201 clock_gettime(CLOCK_REALTIME, &ts); 3202 ts.tv_sec += 2; 3203 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ", 3204 m_queued_codec_config_count); 3205 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED); 3206 if (sem_timedwait(&m_safe_flush, &ts)) { 3207 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers"); 3208 } 3209 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED); 3210 } 3211 } 3212 3213 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 3214 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 3215 } 3216 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 3217 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 3218 } 3219 if (!sem_posted) { 3220 sem_posted = 1; 3221 DEBUG_PRINT_LOW("Set the Semaphore"); 3222 sem_post (&m_cmd_lock); 3223 execute_omx_flush(param1); 3224 } 3225 bFlag = 0; 3226 } else if ( cmd == OMX_CommandPortEnable) { 3227 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued" 3228 "with param1: %u", (unsigned int)param1); 3229 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 3230 m_inp_bEnabled = OMX_TRUE; 3231 3232 if ( (m_state == OMX_StateLoaded && 3233 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3234 || allocate_input_done()) { 3235 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 3236 OMX_COMPONENT_GENERATE_EVENT); 3237 } else { 3238 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 3239 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 3240 // Skip the event notification 3241 bFlag = 0; 3242 } 3243 } 3244 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3245 DEBUG_PRINT_LOW("Enable output Port command recieved"); 3246 m_out_bEnabled = OMX_TRUE; 3247 3248 if ( (m_state == OMX_StateLoaded && 3249 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3250 || (allocate_output_done())) { 3251 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 3252 OMX_COMPONENT_GENERATE_EVENT); 3253 3254 } else { 3255 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 3256 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3257 // Skip the event notification 3258 bFlag = 0; 3259 /* enable/disable downscaling if required */ 3260 ret = decide_downscalar(); 3261 if (ret) { 3262 DEBUG_PRINT_LOW("decide_downscalar failed\n"); 3263 } 3264 } 3265 } 3266 } else if (cmd == OMX_CommandPortDisable) { 3267 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued" 3268 "with param1: %u", (unsigned int)param1); 3269 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 3270 codec_config_flag = false; 3271 m_inp_bEnabled = OMX_FALSE; 3272 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3273 && release_input_done()) { 3274 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 3275 OMX_COMPONENT_GENERATE_EVENT); 3276 } else { 3277 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 3278 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3279 if (!sem_posted) { 3280 sem_posted = 1; 3281 sem_post (&m_cmd_lock); 3282 } 3283 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 3284 } 3285 3286 // Skip the event notification 3287 bFlag = 0; 3288 } 3289 } 3290 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 3291 m_out_bEnabled = OMX_FALSE; 3292 DEBUG_PRINT_LOW("Disable output Port command recieved"); 3293 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 3294 && release_output_done()) { 3295 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 3296 OMX_COMPONENT_GENERATE_EVENT); 3297 } else { 3298 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 3299 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 3300 if (!sem_posted) { 3301 sem_posted = 1; 3302 sem_post (&m_cmd_lock); 3303 } 3304 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 3305 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 3306 } 3307 // Skip the event notification 3308 bFlag = 0; 3309 3310 } 3311 } 3312 } else { 3313 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd); 3314 eRet = OMX_ErrorNotImplemented; 3315 } 3316 if (eRet == OMX_ErrorNone && bFlag) { 3317 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 3318 } 3319 if (!sem_posted) { 3320 sem_post(&m_cmd_lock); 3321 } 3322 3323 return eRet; 3324} 3325 3326/* ====================================================================== 3327 FUNCTION 3328 omx_vdec::ExecuteOmxFlush 3329 3330 DESCRIPTION 3331 Executes the OMX flush. 3332 3333 PARAMETERS 3334 flushtype - input flush(1)/output flush(0)/ both. 3335 3336 RETURN VALUE 3337 true/false 3338 3339 ========================================================================== */ 3340bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 3341{ 3342 bool bRet = false; 3343 struct v4l2_plane plane; 3344 struct v4l2_buffer v4l2_buf; 3345 struct v4l2_decoder_cmd dec; 3346 DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType); 3347 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 3348 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; 3349 3350 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig); 3351 3352 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) { 3353 output_flush_progress = true; 3354 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3355 } else { 3356 /* XXX: The driver/hardware does not support flushing of individual ports 3357 * in all states. So we pretty much need to flush both ports internally, 3358 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it 3359 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, 3360 * we automatically omit sending the FLUSH done for the "opposite" port. */ 3361 input_flush_progress = true; 3362 output_flush_progress = true; 3363 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 3364 request_perf_level(VIDC_TURBO); 3365 } 3366 3367 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 3368 DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType); 3369 bRet = false; 3370 } 3371 3372 return bRet; 3373} 3374/*========================================================================= 3375FUNCTION : execute_output_flush 3376 3377DESCRIPTION 3378Executes the OMX flush at OUTPUT PORT. 3379 3380PARAMETERS 3381None. 3382 3383RETURN VALUE 3384true/false 3385==========================================================================*/ 3386bool omx_vdec::execute_output_flush() 3387{ 3388 unsigned long p1 = 0; // Parameter - 1 3389 unsigned long p2 = 0; // Parameter - 2 3390 unsigned long ident = 0; 3391 bool bRet = true; 3392 3393 /*Generate FBD for all Buffers in the FTBq*/ 3394 pthread_mutex_lock(&m_lock); 3395 DEBUG_PRINT_LOW("Initiate Output Flush"); 3396 3397 //reset last render TS 3398 if(m_last_rendered_TS > 0) { 3399 m_last_rendered_TS = 0; 3400 } 3401 3402 while (m_ftb_q.m_size) { 3403 DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d", 3404 m_ftb_q.m_size,pending_output_buffers); 3405 m_ftb_q.pop_entry(&p1,&p2,&ident); 3406 DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2); 3407 if (ident == m_fill_output_msg ) { 3408 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2); 3409 } else if (ident == OMX_COMPONENT_GENERATE_FBD) { 3410 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1); 3411 } 3412 } 3413 pthread_mutex_unlock(&m_lock); 3414 output_flush_progress = false; 3415 3416 if (arbitrary_bytes) { 3417 prev_ts = LLONG_MAX; 3418 rst_prev_ts = true; 3419 } 3420 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); 3421 return bRet; 3422} 3423/*========================================================================= 3424FUNCTION : execute_input_flush 3425 3426DESCRIPTION 3427Executes the OMX flush at INPUT PORT. 3428 3429PARAMETERS 3430None. 3431 3432RETURN VALUE 3433true/false 3434==========================================================================*/ 3435bool omx_vdec::execute_input_flush() 3436{ 3437 unsigned i =0; 3438 unsigned long p1 = 0; // Parameter - 1 3439 unsigned long p2 = 0; // Parameter - 2 3440 unsigned long ident = 0; 3441 bool bRet = true; 3442 3443 /*Generate EBD for all Buffers in the ETBq*/ 3444 DEBUG_PRINT_LOW("Initiate Input Flush"); 3445 3446 pthread_mutex_lock(&m_lock); 3447 DEBUG_PRINT_LOW("Check if the Queue is empty"); 3448 while (m_etb_q.m_size) { 3449 m_etb_q.pop_entry(&p1,&p2,&ident); 3450 3451 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 3452 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 3453 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 3454 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 3455 pending_input_buffers++; 3456 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 3457 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 3458 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 3459 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 3460 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 3461 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p", 3462 (OMX_BUFFERHEADERTYPE *)p1); 3463 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 3464 } 3465 } 3466 time_stamp_dts.flush_timestamp(); 3467 /*Check if Heap Buffers are to be flushed*/ 3468 if (arbitrary_bytes && !(codec_config_flag)) { 3469 DEBUG_PRINT_LOW("Reset all the variables before flusing"); 3470 h264_scratch.nFilledLen = 0; 3471 nal_count = 0; 3472 look_ahead_nal = false; 3473 frame_count = 0; 3474 h264_last_au_ts = LLONG_MAX; 3475 h264_last_au_flags = 0; 3476 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 3477 m_demux_entries = 0; 3478 DEBUG_PRINT_LOW("Initialize parser"); 3479 if (m_frame_parser.mutils) { 3480 m_frame_parser.mutils->initialize_frame_checking_environment(); 3481 } 3482 3483 while (m_input_pending_q.m_size) { 3484 m_input_pending_q.pop_entry(&p1,&p2,&ident); 3485 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 3486 } 3487 3488 if (psource_frame) { 3489 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 3490 psource_frame = NULL; 3491 } 3492 3493 if (pdest_frame) { 3494 pdest_frame->nFilledLen = 0; 3495 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL, 3496 (unsigned int)NULL); 3497 pdest_frame = NULL; 3498 } 3499 m_frame_parser.flush(); 3500 } else if (codec_config_flag) { 3501 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " 3502 "is not sent to the driver yet"); 3503 } 3504 pthread_mutex_unlock(&m_lock); 3505 input_flush_progress = false; 3506 if (!arbitrary_bytes) { 3507 prev_ts = LLONG_MAX; 3508 rst_prev_ts = true; 3509 } 3510#ifdef _ANDROID_ 3511 if (m_debug_timestamp) { 3512 m_timestamp_list.reset_ts_list(); 3513 } 3514#endif 3515 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); 3516 return bRet; 3517} 3518 3519 3520/* ====================================================================== 3521 FUNCTION 3522 omx_vdec::SendCommandEvent 3523 3524 DESCRIPTION 3525 Send the event to decoder pipe. This is needed to generate the callbacks 3526 in decoder thread context. 3527 3528 PARAMETERS 3529 None. 3530 3531 RETURN VALUE 3532 true/false 3533 3534 ========================================================================== */ 3535bool omx_vdec::post_event(unsigned long p1, 3536 unsigned long p2, 3537 unsigned long id) 3538{ 3539 bool bRet = false; 3540 3541 /* Just drop messages typically generated by hardware (w/o client request), 3542 * if we've reported an error to client. */ 3543 if (m_error_propogated) { 3544 switch (id) { 3545 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 3546 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 3547 DEBUG_PRINT_ERROR("Dropping message %lx " 3548 "since client expected to be in error state", id); 3549 return false; 3550 default: 3551 /* whatever */ 3552 break; 3553 } 3554 } 3555 3556 pthread_mutex_lock(&m_lock); 3557 3558 if (id == m_fill_output_msg || 3559 id == OMX_COMPONENT_GENERATE_FBD || 3560 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG || 3561 id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) { 3562 m_ftb_q.insert_entry(p1,p2,id); 3563 } else if (id == OMX_COMPONENT_GENERATE_ETB || 3564 id == OMX_COMPONENT_GENERATE_EBD || 3565 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY || 3566 id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) { 3567 m_etb_q.insert_entry(p1,p2,id); 3568 } else { 3569 m_cmd_q.insert_entry(p1,p2,id); 3570 } 3571 3572 bRet = true; 3573 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); 3574 post_message(this, id); 3575 3576 pthread_mutex_unlock(&m_lock); 3577 3578 return bRet; 3579} 3580 3581OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 3582{ 3583 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3584 if (!profileLevelType) 3585 return OMX_ErrorBadParameter; 3586 3587 if (profileLevelType->nPortIndex == 0) { 3588 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 3589 profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; 3590 if (profileLevelType->nProfileIndex == 0) { 3591 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 3592 } else if (profileLevelType->nProfileIndex == 1) { 3593 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 3594 } else if (profileLevelType->nProfileIndex == 2) { 3595 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 3596 } else if (profileLevelType->nProfileIndex == 3) { 3597 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 3598 } else if (profileLevelType->nProfileIndex == 4) { 3599 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh; 3600 } else { 3601 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3602 (unsigned int)profileLevelType->nProfileIndex); 3603 eRet = OMX_ErrorNoMore; 3604 } 3605 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 3606 if (profileLevelType->nProfileIndex == 0) { 3607 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh; 3608 profileLevelType->eLevel = QOMX_VIDEO_MVCLevel51; 3609 } else { 3610 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3611 (unsigned int)profileLevelType->nProfileIndex); 3612 eRet = OMX_ErrorNoMore; 3613 } 3614 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 3615 if (profileLevelType->nProfileIndex == 0) { 3616 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain; 3617 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3618 } else if (profileLevelType->nProfileIndex == 1) { 3619 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10; 3620 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3621 } else if (profileLevelType->nProfileIndex == 2) { 3622 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10HDR10; 3623 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51; 3624 } else { 3625 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3626 (unsigned int)profileLevelType->nProfileIndex); 3627 eRet = OMX_ErrorNoMore; 3628 } 3629 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) { 3630 if (profileLevelType->nProfileIndex == 0) { 3631 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 3632 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 3633 } else { 3634 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3635 (unsigned int)profileLevelType->nProfileIndex); 3636 eRet = OMX_ErrorNoMore; 3637 } 3638 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 3639 if (profileLevelType->nProfileIndex == 0) { 3640 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3641 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3642 } else if (profileLevelType->nProfileIndex == 1) { 3643 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 3644 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 3645 } else { 3646 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3647 (unsigned int)profileLevelType->nProfileIndex); 3648 eRet = OMX_ErrorNoMore; 3649 } 3650 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || 3651 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 3652 eRet = OMX_ErrorNoMore; 3653 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 3654 if (profileLevelType->nProfileIndex == 0) { 3655 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; 3656 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3657 } else if (profileLevelType->nProfileIndex == 1) { 3658 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; 3659 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 3660 } else { 3661 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 3662 (unsigned int)profileLevelType->nProfileIndex); 3663 eRet = OMX_ErrorNoMore; 3664 } 3665 } else { 3666 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind); 3667 eRet = OMX_ErrorNoMore; 3668 } 3669 } else { 3670 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u", 3671 (unsigned int)profileLevelType->nPortIndex); 3672 eRet = OMX_ErrorBadPortIndex; 3673 } 3674 return eRet; 3675} 3676 3677/* ====================================================================== 3678 FUNCTION 3679 omx_vdec::GetParameter 3680 3681 DESCRIPTION 3682 OMX Get Parameter method implementation 3683 3684 PARAMETERS 3685 <TBD>. 3686 3687 RETURN VALUE 3688 Error None if successful. 3689 3690 ========================================================================== */ 3691OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 3692 OMX_IN OMX_INDEXTYPE paramIndex, 3693 OMX_INOUT OMX_PTR paramData) 3694{ 3695 (void) hComp; 3696 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3697 3698 DEBUG_PRINT_LOW("get_parameter:"); 3699 if (m_state == OMX_StateInvalid) { 3700 DEBUG_PRINT_ERROR("Get Param in Invalid State"); 3701 return OMX_ErrorInvalidState; 3702 } 3703 if (paramData == NULL) { 3704 DEBUG_PRINT_LOW("Get Param in Invalid paramData"); 3705 return OMX_ErrorBadParameter; 3706 } 3707 switch ((unsigned long)paramIndex) { 3708 case OMX_IndexParamPortDefinition: { 3709 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 3710 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = 3711 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 3712 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition"); 3713 decide_dpb_buffer_mode(is_down_scalar_enabled); 3714 eRet = update_portdef(portDefn); 3715 if (eRet == OMX_ErrorNone) 3716 m_port_def = *portDefn; 3717 break; 3718 } 3719 case OMX_IndexParamVideoInit: { 3720 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3721 OMX_PORT_PARAM_TYPE *portParamType = 3722 (OMX_PORT_PARAM_TYPE *) paramData; 3723 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); 3724 3725 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3726 portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3727 portParamType->nPorts = 2; 3728 portParamType->nStartPortNumber = 0; 3729 break; 3730 } 3731 case OMX_IndexParamVideoPortFormat: { 3732 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 3733 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 3734 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 3735 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); 3736 3737 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 3738 portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); 3739 3740 if (0 == portFmt->nPortIndex) { 3741 if (0 == portFmt->nIndex) { 3742 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 3743 portFmt->eCompressionFormat = eCompressionFormat; 3744 } else { 3745 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3746 " NoMore compression formats"); 3747 eRet = OMX_ErrorNoMore; 3748 } 3749 } else if (1 == portFmt->nPortIndex) { 3750 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 3751 3752 // Distinguish non-surface mode from normal playback use-case based on 3753 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2" 3754 // For non-android, use the default list 3755 // Also use default format-list if FLEXIBLE YUV is supported, 3756 // as the client negotiates the standard color-format if it needs to 3757 bool useNonSurfaceMode = false; 3758#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) 3759 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE); 3760#endif 3761 if (is_thulium_v1) { 3762 portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex); 3763 } else { 3764 portFmt->eColorFormat = useNonSurfaceMode ? 3765 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) : 3766 getPreferredColorFormatDefaultMode(portFmt->nIndex); 3767 } 3768 3769 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) { 3770 eRet = OMX_ErrorNoMore; 3771 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 3772 " NoMore Color formats"); 3773 } 3774 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat); 3775 } else { 3776 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d", 3777 (int)portFmt->nPortIndex); 3778 eRet = OMX_ErrorBadPortIndex; 3779 } 3780 break; 3781 } 3782 /*Component should support this port definition*/ 3783 case OMX_IndexParamAudioInit: { 3784 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3785 OMX_PORT_PARAM_TYPE *audioPortParamType = 3786 (OMX_PORT_PARAM_TYPE *) paramData; 3787 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); 3788 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3789 audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3790 audioPortParamType->nPorts = 0; 3791 audioPortParamType->nStartPortNumber = 0; 3792 break; 3793 } 3794 /*Component should support this port definition*/ 3795 case OMX_IndexParamImageInit: { 3796 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); 3797 OMX_PORT_PARAM_TYPE *imagePortParamType = 3798 (OMX_PORT_PARAM_TYPE *) paramData; 3799 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); 3800 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 3801 imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE); 3802 imagePortParamType->nPorts = 0; 3803 imagePortParamType->nStartPortNumber = 0; 3804 break; 3805 3806 } 3807 /*Component should support this port definition*/ 3808 case OMX_IndexParamOtherInit: { 3809 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x", 3810 paramIndex); 3811 eRet =OMX_ErrorUnsupportedIndex; 3812 break; 3813 } 3814 case OMX_IndexParamStandardComponentRole: { 3815 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 3816 OMX_PARAM_COMPONENTROLETYPE *comp_role; 3817 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 3818 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 3819 comp_role->nSize = sizeof(*comp_role); 3820 3821 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d", 3822 paramIndex); 3823 strlcpy((char*)comp_role->cRole,(const char*)m_cRole, 3824 OMX_MAX_STRINGNAME_SIZE); 3825 break; 3826 } 3827 /* Added for parameter test */ 3828 case OMX_IndexParamPriorityMgmt: { 3829 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 3830 OMX_PRIORITYMGMTTYPE *priorityMgmType = 3831 (OMX_PRIORITYMGMTTYPE *) paramData; 3832 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); 3833 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 3834 priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE); 3835 3836 break; 3837 } 3838 /* Added for parameter test */ 3839 case OMX_IndexParamCompBufferSupplier: { 3840 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 3841 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 3842 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 3843 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); 3844 3845 bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); 3846 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 3847 if (0 == bufferSupplierType->nPortIndex) 3848 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3849 else if (1 == bufferSupplierType->nPortIndex) 3850 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 3851 else 3852 eRet = OMX_ErrorBadPortIndex; 3853 3854 3855 break; 3856 } 3857 case OMX_IndexParamVideoAvc: { 3858 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x", 3859 paramIndex); 3860 break; 3861 } 3862 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 3863 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x", 3864 paramIndex); 3865 break; 3866 } 3867 case OMX_IndexParamVideoH263: { 3868 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x", 3869 paramIndex); 3870 break; 3871 } 3872 case OMX_IndexParamVideoMpeg4: { 3873 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x", 3874 paramIndex); 3875 break; 3876 } 3877 case OMX_IndexParamVideoMpeg2: { 3878 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x", 3879 paramIndex); 3880 break; 3881 } 3882 case OMX_IndexParamVideoProfileLevelQuerySupported: { 3883 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3884 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex); 3885 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = 3886 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 3887 eRet = get_supported_profile_level(profileLevelType); 3888 break; 3889 } 3890#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3891 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: { 3892 VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams); 3893 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); 3894 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; 3895 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 3896 3897 if (secure_mode && !secure_scaling_to_non_secure_opb) { 3898 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | 3899 GRALLOC_USAGE_PRIVATE_UNCACHED); 3900 } else { 3901 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED; 3902 } 3903 } else { 3904 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); 3905 eRet = OMX_ErrorBadParameter; 3906 } 3907 } 3908 break; 3909#endif 3910 3911#ifdef FLEXYUV_SUPPORTED 3912 case OMX_QcomIndexFlexibleYUVDescription: { 3913 DEBUG_PRINT_LOW("get_parameter: describeColorFormat"); 3914 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams); 3915 eRet = describeColorFormat(paramData); 3916 break; 3917 } 3918#endif 3919 case OMX_IndexParamVideoProfileLevelCurrent: { 3920 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 3921 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 3922 struct v4l2_control profile_control, level_control; 3923 3924 switch (drv_ctx.decoder_format) { 3925 case VDEC_CODECTYPE_H264: 3926 profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 3927 level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 3928 break; 3929 default: 3930 DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264"); 3931 eRet = OMX_ErrorNotImplemented; 3932 break; 3933 } 3934 3935 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) { 3936 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) { 3937 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 3938 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 3939 pParam->eProfile = OMX_VIDEO_AVCProfileBaseline; 3940 break; 3941 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 3942 pParam->eProfile = OMX_VIDEO_AVCProfileMain; 3943 break; 3944 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 3945 pParam->eProfile = OMX_VIDEO_AVCProfileExtended; 3946 break; 3947 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 3948 pParam->eProfile = OMX_VIDEO_AVCProfileHigh; 3949 break; 3950 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 3951 pParam->eProfile = OMX_VIDEO_AVCProfileHigh10; 3952 break; 3953 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 3954 pParam->eProfile = OMX_VIDEO_AVCProfileHigh422; 3955 break; 3956 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 3957 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA: 3958 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA: 3959 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA: 3960 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA: 3961 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE: 3962 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH: 3963 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA: 3964 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH: 3965 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH: 3966 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: 3967 eRet = OMX_ErrorUnsupportedIndex; 3968 break; 3969 } 3970 } else { 3971 eRet = OMX_ErrorUnsupportedIndex; 3972 } 3973 3974 3975 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) { 3976 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) { 3977 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 3978 pParam->eLevel = OMX_VIDEO_AVCLevel1; 3979 break; 3980 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 3981 pParam->eLevel = OMX_VIDEO_AVCLevel1b; 3982 break; 3983 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 3984 pParam->eLevel = OMX_VIDEO_AVCLevel11; 3985 break; 3986 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 3987 pParam->eLevel = OMX_VIDEO_AVCLevel12; 3988 break; 3989 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 3990 pParam->eLevel = OMX_VIDEO_AVCLevel13; 3991 break; 3992 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 3993 pParam->eLevel = OMX_VIDEO_AVCLevel2; 3994 break; 3995 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 3996 pParam->eLevel = OMX_VIDEO_AVCLevel21; 3997 break; 3998 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 3999 pParam->eLevel = OMX_VIDEO_AVCLevel22; 4000 break; 4001 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 4002 pParam->eLevel = OMX_VIDEO_AVCLevel3; 4003 break; 4004 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 4005 pParam->eLevel = OMX_VIDEO_AVCLevel31; 4006 break; 4007 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 4008 pParam->eLevel = OMX_VIDEO_AVCLevel32; 4009 break; 4010 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 4011 pParam->eLevel = OMX_VIDEO_AVCLevel4; 4012 break; 4013 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 4014 pParam->eLevel = OMX_VIDEO_AVCLevel41; 4015 break; 4016 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 4017 pParam->eLevel = OMX_VIDEO_AVCLevel42; 4018 break; 4019 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 4020 pParam->eLevel = OMX_VIDEO_AVCLevel5; 4021 break; 4022 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 4023 pParam->eLevel = OMX_VIDEO_AVCLevel51; 4024 break; 4025 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: 4026 pParam->eLevel = OMX_VIDEO_AVCLevel52; 4027 break; 4028 } 4029 } else { 4030 eRet = OMX_ErrorUnsupportedIndex; 4031 } 4032 4033 break; 4034 4035 } 4036 case OMX_QTIIndexParamVideoClientExtradata: 4037 { 4038 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CLIENT_EXTRADATATYPE); 4039 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata"); 4040 QOMX_VIDEO_CLIENT_EXTRADATATYPE *pParam = 4041 (QOMX_VIDEO_CLIENT_EXTRADATATYPE *)paramData; 4042 pParam->nExtradataSize = VENUS_EXTRADATA_SIZE(4096, 2160); 4043 pParam->nExtradataAllocSize = pParam->nExtradataSize * MAX_NUM_INPUT_OUTPUT_BUFFERS; 4044 eRet = OMX_ErrorNone; 4045 break; 4046 } 4047 case OMX_QTIIndexParamDitherControl: 4048 { 4049 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL); 4050 DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL"); 4051 QOMX_VIDEO_DITHER_CONTROL *pParam = 4052 (QOMX_VIDEO_DITHER_CONTROL *) paramData; 4053 pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config; 4054 eRet = OMX_ErrorNone; 4055 break; 4056 } 4057 default: { 4058 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex); 4059 eRet =OMX_ErrorUnsupportedIndex; 4060 } 4061 4062 } 4063 4064 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", 4065 drv_ctx.video_resolution.frame_width, 4066 drv_ctx.video_resolution.frame_height, 4067 drv_ctx.video_resolution.stride, 4068 drv_ctx.video_resolution.scan_lines); 4069 4070 return eRet; 4071} 4072 4073#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 4074OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) 4075{ 4076 DEBUG_PRINT_LOW("Inside use_android_native_buffer"); 4077 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4078 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; 4079 4080 if ((params == NULL) || 4081 (params->nativeBuffer == NULL) || 4082 (params->nativeBuffer->handle == NULL) || 4083 !m_enable_android_native_buffers) 4084 return OMX_ErrorBadParameter; 4085 m_use_android_native_buffers = OMX_TRUE; 4086 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 4087 private_handle_t *handle = (private_handle_t *)nBuf->handle; 4088 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port 4089 OMX_U8 *buffer = NULL; 4090 if (!secure_mode) { 4091 buffer = (OMX_U8*)mmap(0, handle->size, 4092 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 4093 if (buffer == MAP_FAILED) { 4094 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 4095 return OMX_ErrorInsufficientResources; 4096 } 4097 } 4098 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); 4099 } else { 4100 eRet = OMX_ErrorBadParameter; 4101 } 4102 return eRet; 4103} 4104#endif 4105 4106OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() { 4107 struct v4l2_control control; 4108 struct v4l2_format fmt; 4109 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; 4110 control.value = 1; 4111 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 4112 if (rc < 0) { 4113 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 4114 return OMX_ErrorHardware; 4115 } 4116 m_smoothstreaming_mode = true; 4117 return OMX_ErrorNone; 4118} 4119 4120/* ====================================================================== 4121 FUNCTION 4122 omx_vdec::Setparameter 4123 4124 DESCRIPTION 4125 OMX Set Parameter method implementation. 4126 4127 PARAMETERS 4128 <TBD>. 4129 4130 RETURN VALUE 4131 OMX Error None if successful. 4132 4133 ========================================================================== */ 4134OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 4135 OMX_IN OMX_INDEXTYPE paramIndex, 4136 OMX_IN OMX_PTR paramData) 4137{ 4138 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4139 int ret=0; 4140 struct v4l2_format fmt; 4141#ifdef _ANDROID_ 4142 char property_value[PROPERTY_VALUE_MAX] = {0}; 4143#endif 4144 if (m_state == OMX_StateInvalid) { 4145 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 4146 return OMX_ErrorInvalidState; 4147 } 4148 if (paramData == NULL) { 4149 DEBUG_PRINT_ERROR("Get Param in Invalid paramData"); 4150 return OMX_ErrorBadParameter; 4151 } 4152 if ((m_state != OMX_StateLoaded) && 4153 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && 4154 (m_out_bEnabled == OMX_TRUE) && 4155 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && 4156 (m_inp_bEnabled == OMX_TRUE)) { 4157 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 4158 return OMX_ErrorIncorrectStateOperation; 4159 } 4160 switch ((unsigned long)paramIndex) { 4161 case OMX_IndexParamPortDefinition: { 4162 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); 4163 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 4164 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 4165 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has 4166 //been called. 4167 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", 4168 (int)portDefn->format.video.nFrameHeight, 4169 (int)portDefn->format.video.nFrameWidth); 4170 4171 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4172 DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d", 4173 portDefn->nBufferCountActual); 4174 eRet = OMX_ErrorBadParameter; 4175 break; 4176 } 4177 if (OMX_DirOutput == portDefn->eDir) { 4178 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); 4179 bool port_format_changed = false; 4180 m_display_id = portDefn->format.video.pNativeWindow; 4181 unsigned int buffer_size; 4182 /* update output port resolution with client supplied dimensions 4183 in case scaling is enabled, else it follows input resolution set 4184 */ 4185 decide_dpb_buffer_mode(is_down_scalar_enabled); 4186 if (is_down_scalar_enabled) { 4187 DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)", 4188 (unsigned int)portDefn->format.video.nFrameWidth, 4189 (unsigned int)portDefn->format.video.nFrameHeight); 4190 if (portDefn->format.video.nFrameHeight != 0x0 && 4191 portDefn->format.video.nFrameWidth != 0x0) { 4192 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4193 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4194 fmt.fmt.pix_mp.pixelformat = capture_capability; 4195 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 4196 if (ret) { 4197 DEBUG_PRINT_ERROR("Get Resolution failed"); 4198 eRet = OMX_ErrorHardware; 4199 break; 4200 } 4201 if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) || 4202 (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) { 4203 port_format_changed = true; 4204 } 4205 4206 /* set crop info */ 4207 rectangle.nLeft = 0; 4208 rectangle.nTop = 0; 4209 rectangle.nWidth = portDefn->format.video.nFrameWidth; 4210 rectangle.nHeight = portDefn->format.video.nFrameHeight; 4211 4212 m_extradata_info.output_crop_rect.nLeft = 0; 4213 m_extradata_info.output_crop_rect.nTop = 0; 4214 m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth; 4215 m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight; 4216 4217 eRet = is_video_session_supported(); 4218 if (eRet) 4219 break; 4220 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4221 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4222 fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight; 4223 fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth; 4224 fmt.fmt.pix_mp.pixelformat = capture_capability; 4225 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d", 4226 fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width); 4227 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4228 if (ret) { 4229 DEBUG_PRINT_ERROR("Set Resolution failed"); 4230 eRet = OMX_ErrorUnsupportedSetting; 4231 } else 4232 eRet = get_buffer_req(&drv_ctx.op_buf); 4233 } 4234 4235 if (eRet) { 4236 break; 4237 } 4238 4239 if (secure_mode) { 4240 struct v4l2_control control; 4241 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD; 4242 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 4243 DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id); 4244 eRet = OMX_ErrorHardware; 4245 } else { 4246 /* This is a workaround for a bug in fw which uses stride 4247 * and slice instead of width and height to check against 4248 * the threshold. 4249 */ 4250 OMX_U32 stride, slice; 4251 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 4252 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth); 4253 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight); 4254 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 4255 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth); 4256 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight); 4257 } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 4258 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameWidth); 4259 slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameHeight); 4260 } else { 4261 stride = portDefn->format.video.nFrameWidth; 4262 slice = portDefn->format.video.nFrameHeight; 4263 } 4264 4265 DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice); 4266 DEBUG_PRINT_LOW("Threshold value is %d\n", control.value); 4267 4268 if (stride * slice <= (OMX_U32)control.value) { 4269 secure_scaling_to_non_secure_opb = true; 4270 DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ"); 4271 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2; 4272 control.value = 1; 4273 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) { 4274 DEBUG_PRINT_ERROR("Enabling non-secure output2 failed"); 4275 eRet = OMX_ErrorUnsupportedSetting; 4276 } 4277 } 4278 } 4279 } 4280 } 4281 4282 if (eRet) { 4283 break; 4284 } 4285 4286 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4287 DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)", 4288 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4289 eRet = OMX_ErrorBadParameter; 4290 } else if (!client_buffers.get_buffer_req(buffer_size)) { 4291 DEBUG_PRINT_ERROR("Error in getting buffer requirements"); 4292 eRet = OMX_ErrorBadParameter; 4293 } else if (!port_format_changed) { 4294 4295 // Buffer count can change only when port is unallocated 4296 if (m_out_mem_ptr && 4297 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount || 4298 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) { 4299 4300 DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !"); 4301 eRet = OMX_ErrorInvalidState; 4302 break; 4303 } 4304 4305 // route updating of buffer requirements via c2d proxy. 4306 // Based on whether c2d is enabled, requirements will be handed 4307 // to the vidc driver appropriately 4308 eRet = client_buffers.set_buffer_req(portDefn->nBufferSize, 4309 portDefn->nBufferCountActual); 4310 if (eRet == OMX_ErrorNone) { 4311 m_port_def = *portDefn; 4312 } else { 4313 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)", 4314 drv_ctx.op_buf.mincount, (unsigned int)buffer_size, 4315 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4316 eRet = OMX_ErrorBadParameter; 4317 } 4318 } 4319 } else if (OMX_DirInput == portDefn->eDir) { 4320 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); 4321 bool port_format_changed = false; 4322 if ((portDefn->format.video.xFramerate >> 16) > 0 && 4323 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) { 4324 // Frame rate only should be set if this is a "known value" or to 4325 // activate ts prediction logic (arbitrary mode only) sending input 4326 // timestamps with max value (LLONG_MAX). 4327 m_fps_received = portDefn->format.video.xFramerate; 4328 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u", 4329 (unsigned int)portDefn->format.video.xFramerate >> 16); 4330 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, 4331 drv_ctx.frame_rate.fps_denominator); 4332 if (!drv_ctx.frame_rate.fps_numerator) { 4333 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 4334 drv_ctx.frame_rate.fps_numerator = 30; 4335 } 4336 if (drv_ctx.frame_rate.fps_denominator) 4337 drv_ctx.frame_rate.fps_numerator = (int) 4338 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 4339 drv_ctx.frame_rate.fps_denominator = 1; 4340 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 4341 drv_ctx.frame_rate.fps_numerator; 4342 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", 4343 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 4344 (float)drv_ctx.frame_rate.fps_denominator); 4345 4346 struct v4l2_outputparm oparm; 4347 /*XXX: we're providing timing info as seconds per frame rather than frames 4348 * per second.*/ 4349 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 4350 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 4351 4352 struct v4l2_streamparm sparm; 4353 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4354 sparm.parm.output = oparm; 4355 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 4356 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected"); 4357 eRet = OMX_ErrorHardware; 4358 break; 4359 } 4360 m_perf_control.request_cores(frm_int); 4361 } 4362 4363 if (drv_ctx.video_resolution.frame_height != 4364 portDefn->format.video.nFrameHeight || 4365 drv_ctx.video_resolution.frame_width != 4366 portDefn->format.video.nFrameWidth) { 4367 DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)", 4368 (unsigned int)portDefn->format.video.nFrameWidth, 4369 (unsigned int)portDefn->format.video.nFrameHeight); 4370 port_format_changed = true; 4371 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth; 4372 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight; 4373 if (frameHeight != 0x0 && frameWidth != 0x0) { 4374 if (m_smoothstreaming_mode && 4375 ((frameWidth * frameHeight) < 4376 (m_smoothstreaming_width * m_smoothstreaming_height))) { 4377 frameWidth = m_smoothstreaming_width; 4378 frameHeight = m_smoothstreaming_height; 4379 DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u " 4380 "for adaptive-playback/smooth-streaming", 4381 (unsigned int)frameWidth, (unsigned int)frameHeight); 4382 } 4383 4384 m_extradata_info.output_crop_rect.nLeft = 0; 4385 m_extradata_info.output_crop_rect.nTop = 0; 4386 m_extradata_info.output_crop_rect.nWidth = frameWidth; 4387 m_extradata_info.output_crop_rect.nHeight = frameHeight; 4388 4389 update_resolution(frameWidth, frameHeight, 4390 frameWidth, frameHeight); 4391 eRet = is_video_session_supported(); 4392 if (eRet) 4393 break; 4394 if (is_down_scalar_enabled) { 4395 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4396 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4397 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4398 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4399 fmt.fmt.pix_mp.pixelformat = output_capability; 4400 DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d", 4401 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 4402 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4403 } else { 4404 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4405 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4406 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 4407 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 4408 fmt.fmt.pix_mp.pixelformat = output_capability; 4409 DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d", 4410 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 4411 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4412 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4413 fmt.fmt.pix_mp.pixelformat = capture_capability; 4414 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4415 } 4416 if (ret) { 4417 DEBUG_PRINT_ERROR("Set Resolution failed"); 4418 eRet = OMX_ErrorUnsupportedSetting; 4419 } else { 4420 if (!is_down_scalar_enabled) 4421 eRet = get_buffer_req(&drv_ctx.op_buf); 4422 } 4423 } 4424 } 4425 if (m_custom_buffersize.input_buffersize 4426 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) { 4427 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d", 4428 m_custom_buffersize.input_buffersize, portDefn->nBufferSize); 4429 eRet = OMX_ErrorBadParameter; 4430 break; 4431 } 4432 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) { 4433 DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)", 4434 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS); 4435 eRet = OMX_ErrorBadParameter; 4436 break; 4437 } 4438 // Buffer count can change only when port is unallocated 4439 if (m_inp_mem_ptr && 4440 (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount || 4441 portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) { 4442 DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !"); 4443 eRet = OMX_ErrorInvalidState; 4444 break; 4445 } 4446 4447 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount 4448 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) { 4449 port_format_changed = true; 4450 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; 4451 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; 4452 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & 4453 (~(buffer_prop->alignment - 1)); 4454 eRet = set_buffer_req(buffer_prop); 4455 } 4456 if (false == port_format_changed) { 4457 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)", 4458 drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size, 4459 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize); 4460 eRet = OMX_ErrorBadParameter; 4461 } 4462 } else if (portDefn->eDir == OMX_DirMax) { 4463 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 4464 (int)portDefn->nPortIndex); 4465 eRet = OMX_ErrorBadPortIndex; 4466 } 4467 } 4468 break; 4469 case OMX_IndexParamVideoPortFormat: { 4470 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); 4471 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 4472 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 4473 int ret=0; 4474 struct v4l2_format fmt; 4475 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u", 4476 portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex); 4477 4478 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 4479 if (1 == portFmt->nPortIndex) { 4480 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4481 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 4482 if (ret < 0) { 4483 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__); 4484 return OMX_ErrorBadParameter; 4485 } 4486 enum vdec_output_fromat op_format; 4487 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4488 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m || 4489 portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4490 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView || 4491 portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar || 4492 portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 4493 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; 4494 } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4495 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4496 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC; 4497 } else 4498 eRet = OMX_ErrorBadParameter; 4499 4500 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 4501 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 4502 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC; 4503 } else { 4504 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12; 4505 } 4506 4507 if (eRet == OMX_ErrorNone) { 4508 drv_ctx.output_format = op_format; 4509 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 4510 if (ret) { 4511 DEBUG_PRINT_ERROR("Set output format failed"); 4512 eRet = OMX_ErrorUnsupportedSetting; 4513 /*TODO: How to handle this case */ 4514 } else { 4515 eRet = get_buffer_req(&drv_ctx.op_buf); 4516 } 4517 } 4518 if (eRet == OMX_ErrorNone) { 4519 if (!client_buffers.set_color_format(portFmt->eColorFormat)) { 4520 DEBUG_PRINT_ERROR("Set color format failed"); 4521 eRet = OMX_ErrorBadParameter; 4522 } 4523 } 4524 } 4525 } 4526 break; 4527 4528 case OMX_QcomIndexPortDefn: { 4529 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE); 4530 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 4531 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 4532 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u", 4533 (unsigned int)portFmt->nFramePackingFormat); 4534 4535 /* Input port */ 4536 if (portFmt->nPortIndex == 0) { 4537 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how: 4538 // - headers are allocated and 4539 // - headers-indices are derived 4540 // Avoid changing arbitrary_bytes when the port is already allocated 4541 if (m_inp_mem_ptr) { 4542 DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!"); 4543 return OMX_ErrorUnsupportedSetting; 4544 } 4545 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) { 4546 if (secure_mode || m_input_pass_buffer_fd) { 4547 arbitrary_bytes = false; 4548 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode"); 4549 eRet = OMX_ErrorUnsupportedSetting; 4550 } else { 4551 arbitrary_bytes = true; 4552 } 4553 } else if (portFmt->nFramePackingFormat == 4554 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) { 4555 arbitrary_bytes = false; 4556#ifdef _ANDROID_ 4557 property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0"); 4558 if (atoi(property_value)) { 4559 DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command"); 4560 arbitrary_bytes = true; 4561 } 4562#endif 4563 } else { 4564 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u", 4565 (unsigned int)portFmt->nFramePackingFormat); 4566 eRet = OMX_ErrorUnsupportedSetting; 4567 } 4568 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 4569 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); 4570 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && 4571 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && 4572 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) { 4573 m_out_mem_region_smi = OMX_TRUE; 4574 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4575 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set"); 4576 m_use_output_pmem = OMX_TRUE; 4577 } 4578 } 4579 } 4580 } 4581 if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", 4582 OMX_MAX_STRINGNAME_SIZE)) { 4583 arbitrary_bytes = true; 4584 DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264"); 4585 } 4586 break; 4587 4588 case OMX_IndexParamStandardComponentRole: { 4589 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); 4590 OMX_PARAM_COMPONENTROLETYPE *comp_role; 4591 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 4592 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", 4593 comp_role->cRole); 4594 4595 if ((m_state == OMX_StateLoaded)&& 4596 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) { 4597 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 4598 } else { 4599 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4600 return OMX_ErrorIncorrectStateOperation; 4601 } 4602 4603 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4604 if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) { 4605 strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE); 4606 } else { 4607 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4608 eRet =OMX_ErrorUnsupportedSetting; 4609 } 4610 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4611 if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 4612 strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 4613 } else { 4614 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4615 eRet = OMX_ErrorUnsupportedSetting; 4616 } 4617 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4618 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) { 4619 strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE); 4620 } else { 4621 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4622 eRet = OMX_ErrorUnsupportedSetting; 4623 } 4624 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4625 if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) { 4626 strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE); 4627 } else { 4628 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4629 eRet =OMX_ErrorUnsupportedSetting; 4630 } 4631 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4632 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) { 4633 strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE); 4634 } else { 4635 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4636 eRet = OMX_ErrorUnsupportedSetting; 4637 } 4638 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) || 4639 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) || 4640 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE)) 4641 ) { 4642 if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) { 4643 strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE); 4644 } else { 4645 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4646 eRet =OMX_ErrorUnsupportedSetting; 4647 } 4648 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) || 4649 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) 4650 ) { 4651 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) { 4652 strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE); 4653 } else { 4654 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4655 eRet =OMX_ErrorUnsupportedSetting; 4656 } 4657 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) { 4658 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) || 4659 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4660 strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE); 4661 } else { 4662 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4663 eRet = OMX_ErrorUnsupportedSetting; 4664 } 4665 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) { 4666 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) || 4667 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) { 4668 strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE); 4669 } else { 4670 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4671 eRet = OMX_ErrorUnsupportedSetting; 4672 } 4673 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4674 if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4675 strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 4676 } else { 4677 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 4678 eRet = OMX_ErrorUnsupportedSetting; 4679 } 4680 } else { 4681 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind); 4682 eRet = OMX_ErrorInvalidComponentName; 4683 } 4684 break; 4685 } 4686 4687 case OMX_IndexParamPriorityMgmt: { 4688 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); 4689 if (m_state != OMX_StateLoaded) { 4690 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 4691 return OMX_ErrorIncorrectStateOperation; 4692 } 4693 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 4694 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u", 4695 (unsigned int)priorityMgmtype->nGroupID); 4696 4697 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u", 4698 (unsigned int)priorityMgmtype->nGroupPriority); 4699 4700 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 4701 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 4702 4703 break; 4704 } 4705 4706 case OMX_IndexParamCompBufferSupplier: { 4707 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); 4708 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 4709 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d", 4710 bufferSupplierType->eBufferSupplier); 4711 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 4712 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 4713 4714 else 4715 4716 eRet = OMX_ErrorBadPortIndex; 4717 4718 break; 4719 4720 } 4721 case OMX_IndexParamVideoAvc: { 4722 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d", 4723 paramIndex); 4724 break; 4725 } 4726 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: { 4727 DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d", 4728 paramIndex); 4729 break; 4730 } 4731 case OMX_IndexParamVideoH263: { 4732 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d", 4733 paramIndex); 4734 break; 4735 } 4736 case OMX_IndexParamVideoMpeg4: { 4737 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d", 4738 paramIndex); 4739 break; 4740 } 4741 case OMX_IndexParamVideoMpeg2: { 4742 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d", 4743 paramIndex); 4744 break; 4745 } 4746 case OMX_QTIIndexParamLowLatencyMode: { 4747 struct v4l2_control control; 4748 int rc = 0; 4749 QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam = 4750 (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData; 4751 if (pParam->bLowLatencyMode) { 4752 DEBUG_PRINT_HIGH("Enabling DECODE order"); 4753 time_stamp_dts.set_timestamp_reorder_mode(false); 4754 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4755 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4756 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4757 if (rc) { 4758 DEBUG_PRINT_ERROR("Set picture order failed"); 4759 eRet = OMX_ErrorUnsupportedSetting; 4760 } 4761 } 4762 break; 4763 } 4764 case OMX_QcomIndexParamVideoDecoderPictureOrder: { 4765 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER); 4766 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = 4767 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; 4768 struct v4l2_control control; 4769 int pic_order,rc=0; 4770 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d", 4771 pictureOrder->eOutputPictureOrder); 4772 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { 4773 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 4774 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) { 4775 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4776 time_stamp_dts.set_timestamp_reorder_mode(false); 4777 } else 4778 eRet = OMX_ErrorBadParameter; 4779 if (eRet == OMX_ErrorNone) { 4780 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4781 control.value = pic_order; 4782 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4783 if (rc) { 4784 DEBUG_PRINT_ERROR("Set picture order failed"); 4785 eRet = OMX_ErrorUnsupportedSetting; 4786 } 4787 } 4788 break; 4789 } 4790 case OMX_QcomIndexParamConcealMBMapExtraData: 4791 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4792 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, 4793 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4794 break; 4795 case OMX_QcomIndexParamFrameInfoExtraData: 4796 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4797 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 4798 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4799 break; 4800 case OMX_ExtraDataFrameDimension: 4801 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4802 eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false, 4803 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4804 break; 4805 case OMX_QcomIndexParamInterlaceExtraData: 4806 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4807 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, 4808 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4809 break; 4810 case OMX_QcomIndexParamH264TimeInfo: 4811 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4812 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, 4813 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4814 break; 4815 case OMX_QcomIndexParamVideoFramePackingExtradata: 4816 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4817 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false, 4818 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4819 break; 4820 case OMX_QcomIndexParamVideoQPExtraData: 4821 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4822 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 4823 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4824 break; 4825 case OMX_QcomIndexParamVideoInputBitsInfoExtraData: 4826 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4827 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false, 4828 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4829 break; 4830 case OMX_QcomIndexEnableExtnUserData: 4831 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4832 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false, 4833 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4834 break; 4835 case OMX_QTIIndexParamVQZipSEIExtraData: 4836 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 4837 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 4838 ((QOMX_ENABLETYPE *)paramData)->bEnable); 4839 break; 4840 case OMX_QcomIndexParamVideoDivx: { 4841 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; 4842 } 4843 break; 4844 case OMX_QcomIndexPlatformPvt: { 4845 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN); 4846 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); 4847 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; 4848 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 4849 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); 4850 eRet = OMX_ErrorUnsupportedSetting; 4851 } else { 4852 m_out_pvt_entry_pmem = OMX_TRUE; 4853 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 4854 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set"); 4855 m_use_output_pmem = OMX_TRUE; 4856 } 4857 } 4858 4859 } 4860 break; 4861 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: { 4862 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); 4863 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); 4864 struct v4l2_control control; 4865 int rc; 4866 drv_ctx.idr_only_decoding = 1; 4867 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 4868 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 4869 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4870 if (rc) { 4871 DEBUG_PRINT_ERROR("Set picture order failed"); 4872 eRet = OMX_ErrorUnsupportedSetting; 4873 } else { 4874 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; 4875 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; 4876 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 4877 if (rc) { 4878 DEBUG_PRINT_ERROR("Sync frame setting failed"); 4879 eRet = OMX_ErrorUnsupportedSetting; 4880 } 4881 /*Setting sync frame decoding on driver might change buffer 4882 * requirements so update them here*/ 4883 if (get_buffer_req(&drv_ctx.ip_buf)) { 4884 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements"); 4885 eRet = OMX_ErrorUnsupportedSetting; 4886 } 4887 if (get_buffer_req(&drv_ctx.op_buf)) { 4888 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements"); 4889 eRet = OMX_ErrorUnsupportedSetting; 4890 } 4891 } 4892 } 4893 break; 4894 4895 case OMX_QcomIndexParamIndexExtraDataType: { 4896 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE); 4897 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; 4898 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && 4899 (extradataIndexType->bEnabled == OMX_TRUE) && 4900 (extradataIndexType->nPortIndex == 1)) { 4901 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); 4902 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); 4903 4904 } 4905 } 4906 break; 4907 case OMX_QcomIndexParamEnableSmoothStreaming: { 4908#ifndef SMOOTH_STREAMING_DISABLED 4909 eRet = enable_smoothstreaming(); 4910#else 4911 eRet = OMX_ErrorUnsupportedSetting; 4912#endif 4913 } 4914 break; 4915#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 4916 /* Need to allow following two set_parameters even in Idle 4917 * state. This is ANDROID architecture which is not in sync 4918 * with openmax standard. */ 4919 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: { 4920 VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams); 4921 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; 4922 if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 4923 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!"); 4924 eRet = OMX_ErrorUnsupportedSetting; 4925 break; 4926 } else if (m_out_mem_ptr) { 4927 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !"); 4928 eRet = OMX_ErrorInvalidState; 4929 break; 4930 } 4931 if (enableNativeBuffers) { 4932 m_enable_android_native_buffers = enableNativeBuffers->enable; 4933 } 4934#if !defined(FLEXYUV_SUPPORTED) 4935 if (m_enable_android_native_buffers) { 4936 // Use the most-preferred-native-color-format as surface-mode is hinted here 4937 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) { 4938 DEBUG_PRINT_ERROR("Failed to set native color format!"); 4939 eRet = OMX_ErrorUnsupportedSetting; 4940 } 4941 } 4942#endif 4943 } 4944 break; 4945 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: { 4946 VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams); 4947 eRet = use_android_native_buffer(hComp, paramData); 4948 } 4949 break; 4950#if ALLOCATE_OUTPUT_NATIVEHANDLE 4951 case OMX_GoogleAndroidIndexAllocateNativeHandle: { 4952 4953 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData; 4954 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams); 4955 4956 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 4957 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!"); 4958 eRet = OMX_ErrorUnsupportedSetting; 4959 break; 4960 } else if (m_inp_mem_ptr) { 4961 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !"); 4962 eRet = OMX_ErrorInvalidState; 4963 break; 4964 } 4965 4966 if (allocateNativeHandleParams != NULL) { 4967 allocate_native_handle = allocateNativeHandleParams->enable; 4968 } 4969 } 4970 break; 4971#endif //ALLOCATE_OUTPUT_NATIVEHANDLE 4972#endif 4973 case OMX_QcomIndexParamEnableTimeStampReorder: { 4974 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER); 4975 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; 4976 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { 4977 if (reorder->bEnable == OMX_TRUE) { 4978 frm_int =0; 4979 time_stamp_dts.set_timestamp_reorder_mode(true); 4980 } else 4981 time_stamp_dts.set_timestamp_reorder_mode(false); 4982 } else { 4983 time_stamp_dts.set_timestamp_reorder_mode(false); 4984 if (reorder->bEnable == OMX_TRUE) { 4985 eRet = OMX_ErrorUnsupportedSetting; 4986 } 4987 } 4988 } 4989 break; 4990 case OMX_IndexParamVideoProfileLevelCurrent: { 4991 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); 4992 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = 4993 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 4994 if (pParam) { 4995 m_profile_lvl.eProfile = pParam->eProfile; 4996 m_profile_lvl.eLevel = pParam->eLevel; 4997 } 4998 break; 4999 5000 } 5001 case OMX_QcomIndexParamVideoMetaBufferMode: 5002 { 5003 VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams); 5004 StoreMetaDataInBuffersParams *metabuffer = 5005 (StoreMetaDataInBuffersParams *)paramData; 5006 if (!metabuffer) { 5007 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer); 5008 eRet = OMX_ErrorBadParameter; 5009 break; 5010 } 5011 if (m_disable_dynamic_buf_mode) { 5012 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled"); 5013 eRet = OMX_ErrorUnsupportedSetting; 5014 break; 5015 } 5016 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 5017 5018 if (m_out_mem_ptr) { 5019 DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !"); 5020 eRet = OMX_ErrorInvalidState; 5021 break; 5022 } 5023 //set property dynamic buffer mode to driver. 5024 struct v4l2_control control; 5025 struct v4l2_format fmt; 5026 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT; 5027 if (metabuffer->bStoreMetaData == true) { 5028 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC; 5029 } else { 5030 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC; 5031 } 5032 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 5033 if (!rc) { 5034 DEBUG_PRINT_HIGH("%s buffer mode", 5035 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic"); 5036 dynamic_buf_mode = metabuffer->bStoreMetaData; 5037 } else { 5038 DEBUG_PRINT_ERROR("Failed to %s buffer mode", 5039 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic"); 5040 eRet = OMX_ErrorUnsupportedSetting; 5041 } 5042 } else { 5043 DEBUG_PRINT_ERROR( 5044 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u", 5045 (unsigned int)metabuffer->nPortIndex); 5046 eRet = OMX_ErrorUnsupportedSetting; 5047 } 5048 break; 5049 } 5050 case OMX_QcomIndexParamVideoDownScalar: 5051 { 5052 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR); 5053 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData; 5054 struct v4l2_control control; 5055 int rc; 5056 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable); 5057 5058 if (pParam && pParam->bEnable) { 5059 rc = enable_downscalar(); 5060 if (rc < 0) { 5061 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__); 5062 return OMX_ErrorUnsupportedSetting; 5063 } 5064 m_force_down_scalar = pParam->bEnable; 5065 } else { 5066 rc = disable_downscalar(); 5067 if (rc < 0) { 5068 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__); 5069 return OMX_ErrorUnsupportedSetting; 5070 } 5071 m_force_down_scalar = pParam->bEnable; 5072 } 5073 break; 5074 } 5075#ifdef ADAPTIVE_PLAYBACK_SUPPORTED 5076 case OMX_QcomIndexParamVideoAdaptivePlaybackMode: 5077 { 5078 VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams); 5079 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback"); 5080 PrepareForAdaptivePlaybackParams* pParams = 5081 (PrepareForAdaptivePlaybackParams *) paramData; 5082 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 5083 if (!pParams->bEnable) { 5084 return OMX_ErrorNone; 5085 } 5086 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth 5087 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) { 5088 DEBUG_PRINT_ERROR( 5089 "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]", 5090 (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight, 5091 (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight); 5092 eRet = OMX_ErrorBadParameter; 5093 } else { 5094 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight); 5095 } 5096 } else { 5097 DEBUG_PRINT_ERROR( 5098 "Prepare for adaptive playback supported only on output port"); 5099 eRet = OMX_ErrorBadParameter; 5100 } 5101 break; 5102 } 5103 5104 case OMX_QTIIndexParamVideoPreferAdaptivePlayback: 5105 { 5106 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 5107 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback"); 5108 m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable; 5109 if (m_disable_dynamic_buf_mode) { 5110 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set"); 5111 } 5112 break; 5113 } 5114#endif 5115 case OMX_QcomIndexParamVideoCustomBufferSize: 5116 { 5117 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE); 5118 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize"); 5119 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData; 5120 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 5121 struct v4l2_control control; 5122 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT; 5123 control.value = pParam->nBufferSize; 5124 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5125 DEBUG_PRINT_ERROR("Failed to set input buffer size"); 5126 eRet = OMX_ErrorUnsupportedSetting; 5127 } else { 5128 eRet = get_buffer_req(&drv_ctx.ip_buf); 5129 if (eRet == OMX_ErrorNone) { 5130 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size; 5131 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d", 5132 m_custom_buffersize.input_buffersize); 5133 } else { 5134 DEBUG_PRINT_ERROR("Failed to get buffer requirement"); 5135 } 5136 } 5137 } else { 5138 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port"); 5139 eRet = OMX_ErrorBadParameter; 5140 } 5141 break; 5142 } 5143 case OMX_QTIIndexParamVQZIPSEIType: 5144 { 5145 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE); 5146 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType"); 5147 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam = 5148 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData; 5149 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable); 5150 5151 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false, 5152 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5153 if (eRet != OMX_ErrorNone) { 5154 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata"); 5155 eRet = OMX_ErrorBadParameter; 5156 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5157 break; 5158 } 5159 eRet = enable_extradata(OMX_QP_EXTRADATA, false, 5160 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5161 if (eRet != OMX_ErrorNone) { 5162 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata"); 5163 eRet = OMX_ErrorBadParameter; 5164 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5165 client_extradata = client_extradata & ~OMX_QP_EXTRADATA; 5166 break; 5167 } 5168 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 5169 ((QOMX_ENABLETYPE *)paramData)->bEnable); 5170 if (eRet != OMX_ErrorNone) { 5171 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata"); 5172 eRet = OMX_ErrorBadParameter; 5173 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA; 5174 client_extradata = client_extradata & ~OMX_QP_EXTRADATA; 5175 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA; 5176 } 5177 break; 5178 } 5179 case OMX_QTIIndexParamPassInputBufferFd: 5180 { 5181 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); 5182 if (arbitrary_bytes) { 5183 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode"); 5184 eRet = OMX_ErrorUnsupportedSetting; 5185 break; 5186 } 5187 5188 m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable; 5189 if (m_input_pass_buffer_fd) 5190 DEBUG_PRINT_LOW("Enable passing input buffer FD"); 5191 break; 5192 } 5193 case OMX_QTIIndexParamForceCompressedForDPB: 5194 { 5195 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE); 5196 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB"); 5197 OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam = 5198 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData; 5199 if (m_disable_ubwc_mode) { 5200 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled"); 5201 eRet = OMX_ErrorUnsupportedSetting; 5202 break; 5203 } 5204 if (!paramData) { 5205 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL"); 5206 eRet = OMX_ErrorBadParameter; 5207 break; 5208 } 5209 5210 m_force_compressed_for_dpb = pParam->bEnable; 5211 break; 5212 } 5213 case OMX_QTIIndexParamForceUnCompressedForOPB: 5214 { 5215 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB"); 5216 OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam = 5217 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData; 5218 if (!paramData) { 5219 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL"); 5220 eRet = OMX_ErrorBadParameter; 5221 break; 5222 } 5223 m_disable_ubwc_mode = pParam->bEnable; 5224 DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled"); 5225 break; 5226 } 5227 case OMX_QTIIndexParamVideoClientExtradata: 5228 { 5229 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CLIENT_EXTRADATATYPE); 5230 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata"); 5231 QOMX_VIDEO_CLIENT_EXTRADATATYPE *pParam = 5232 (QOMX_VIDEO_CLIENT_EXTRADATATYPE *)paramData; 5233 OMX_U32 extradata_size = VENUS_EXTRADATA_SIZE(4096, 2160); 5234 if (pParam->nExtradataSize < extradata_size || 5235 pParam->nExtradataAllocSize < (extradata_size * MAX_NUM_INPUT_OUTPUT_BUFFERS) || 5236 pParam->nExtradataAllocSize < (pParam->nExtradataSize * MAX_NUM_INPUT_OUTPUT_BUFFERS)) { 5237 DEBUG_PRINT_ERROR("set_parameter: Incorrect buffer size for client extradata"); 5238 eRet = OMX_ErrorBadParameter; 5239 break; 5240 } 5241 if (!m_client_extradata_info.set_extradata_info(dup(pParam->nFd), 5242 pParam->nExtradataAllocSize, pParam->nExtradataSize)) { 5243 DEBUG_PRINT_ERROR("set_parameter: Setting client extradata failed."); 5244 eRet = OMX_ErrorBadParameter; 5245 break; 5246 } 5247 break; 5248 } 5249 case OMX_QTIIndexParamDitherControl: 5250 { 5251 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL); 5252 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl"); 5253 QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData; 5254 DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType); 5255 if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) || 5256 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) { 5257 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range"); 5258 eRet = OMX_ErrorBadParameter; 5259 break; 5260 } 5261 m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE; 5262 DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config); 5263 break; 5264 } 5265 default: { 5266 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex); 5267 eRet = OMX_ErrorUnsupportedIndex; 5268 } 5269 } 5270 if (eRet != OMX_ErrorNone) 5271 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex); 5272 return eRet; 5273} 5274 5275/* ====================================================================== 5276 FUNCTION 5277 omx_vdec::GetConfig 5278 5279 DESCRIPTION 5280 OMX Get Config Method implementation. 5281 5282 PARAMETERS 5283 <TBD>. 5284 5285 RETURN VALUE 5286 OMX Error None if successful. 5287 5288 ========================================================================== */ 5289OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 5290 OMX_IN OMX_INDEXTYPE configIndex, 5291 OMX_INOUT OMX_PTR configData) 5292{ 5293 (void) hComp; 5294 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5295 5296 if (m_state == OMX_StateInvalid) { 5297 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 5298 return OMX_ErrorInvalidState; 5299 } 5300 5301 switch ((unsigned long)configIndex) { 5302 case OMX_QcomIndexConfigInterlaced: { 5303 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE); 5304 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 5305 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 5306 if (configFmt->nPortIndex == 1) { 5307 if (configFmt->nIndex == 0) { 5308 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 5309 } else if (configFmt->nIndex == 1) { 5310 configFmt->eInterlaceType = 5311 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 5312 } else if (configFmt->nIndex == 2) { 5313 configFmt->eInterlaceType = 5314 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 5315 } else { 5316 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 5317 " NoMore Interlaced formats"); 5318 eRet = OMX_ErrorNoMore; 5319 } 5320 5321 } else { 5322 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port", 5323 (int)configFmt->nPortIndex); 5324 eRet = OMX_ErrorBadPortIndex; 5325 } 5326 break; 5327 } 5328 case OMX_QcomIndexQueryNumberOfVideoDecInstance: { 5329 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES); 5330 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 5331 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 5332 decoderinstances->nNumOfInstances = 16; 5333 /*TODO: How to handle this case */ 5334 break; 5335 } 5336 case OMX_QcomIndexConfigVideoFramePackingArrangement: { 5337 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) { 5338 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT); 5339 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = 5340 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; 5341 memcpy(configFmt, &m_frame_pack_arrangement, 5342 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 5343 } else { 5344 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); 5345 } 5346 break; 5347 } 5348 case OMX_IndexConfigCommonOutputCrop: { 5349 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE); 5350 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; 5351 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); 5352 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u", 5353 rectangle.nLeft, rectangle.nTop, 5354 rectangle.nWidth, rectangle.nHeight); 5355 break; 5356 } 5357 case OMX_QcomIndexConfigPerfLevel: { 5358 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); 5359 struct v4l2_control control; 5360 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 5361 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 5362 5363 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5364 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) { 5365 DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno); 5366 eRet = OMX_ErrorHardware; 5367 } 5368 5369 if (eRet == OMX_ErrorNone) { 5370 switch (control.value) { 5371 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO: 5372 perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo; 5373 break; 5374 default: 5375 DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value); 5376 /* Fall through */ 5377 case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL: 5378 perf->ePerfLevel = OMX_QCOM_PerfLevelNominal; 5379 break; 5380 } 5381 } 5382 5383 break; 5384 } 5385 case OMX_QcomIndexConfigH264EntropyCodingCabac: { 5386 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE); 5387 QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData; 5388 struct v4l2_control control; 5389 5390 if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) { 5391 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264"); 5392 eRet = OMX_ErrorNotImplemented; 5393 break; 5394 } 5395 5396 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 5397 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) { 5398 coding->bCabac = (OMX_BOOL) 5399 (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC); 5400 /* We can't query driver at the moment for the cabac mode, so 5401 * just use 0xff...f as a place holder for future improvement */ 5402 coding->nCabacInitIdc = ~0; 5403 } else { 5404 eRet = OMX_ErrorUnsupportedIndex; 5405 } 5406 5407 break; 5408 } 5409 case OMX_QTIIndexConfigDescribeColorAspects: 5410 { 5411 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5412 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5413 5414 print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client"); 5415 print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal"); 5416 5417 if (params->bRequestingDataSpace) { 5418 DEBUG_PRINT_ERROR("Does not handle dataspace request"); 5419 return OMX_ErrorUnsupportedSetting; 5420 } 5421 if (m_internal_color_space.bDataSpaceChanged == OMX_TRUE) { 5422 DEBUG_PRINT_LOW("Updating Client's color aspects with internal"); 5423 memcpy(&(m_client_color_space.sAspects), 5424 &(m_internal_color_space.sAspects), sizeof(ColorAspects)); 5425 m_internal_color_space.bDataSpaceChanged = OMX_FALSE; 5426 } 5427 memcpy(&(params->sAspects), &(m_client_color_space.sAspects), sizeof(ColorAspects)); 5428 5429 break; 5430 } 5431 case OMX_QTIIndexConfigDescribeHDRColorInfo: 5432 { 5433 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams); 5434 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData; 5435 auto_lock lock(m_hdr_info_client_lock); 5436 5437 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR"); 5438 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR"); 5439 5440 if (m_change_client_hdr_info) { 5441 DEBUG_PRINT_LOW("Updating Client's HDR Info with internal"); 5442 memcpy(&m_client_hdr_info.sInfo, 5443 &m_internal_hdr_info.sInfo, sizeof(HDRStaticInfo)); 5444 m_change_client_hdr_info = false; 5445 } 5446 5447 memcpy(&(params->sInfo), &(m_client_hdr_info.sInfo), sizeof(HDRStaticInfo)); 5448 5449 break; 5450 } 5451 default: 5452 { 5453 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex); 5454 eRet = OMX_ErrorBadParameter; 5455 } 5456 5457 } 5458 5459 return eRet; 5460} 5461 5462/* ====================================================================== 5463 FUNCTION 5464 omx_vdec::SetConfig 5465 5466 DESCRIPTION 5467 OMX Set Config method implementation 5468 5469 PARAMETERS 5470 <TBD>. 5471 5472 RETURN VALUE 5473 OMX Error None if successful. 5474 ========================================================================== */ 5475OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 5476 OMX_IN OMX_INDEXTYPE configIndex, 5477 OMX_IN OMX_PTR configData) 5478{ 5479 (void) hComp; 5480 if (m_state == OMX_StateInvalid) { 5481 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 5482 return OMX_ErrorInvalidState; 5483 } 5484 5485 OMX_ERRORTYPE ret = OMX_ErrorNone; 5486 OMX_VIDEO_CONFIG_NALSIZE *pNal; 5487 5488 DEBUG_PRINT_LOW("Set Config Called"); 5489 5490 if (configIndex == OMX_IndexConfigVideoNalSize) { 5491 struct v4l2_control temp; 5492 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT; 5493 5494 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE); 5495 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 5496 switch (pNal->nNaluBytes) { 5497 case 0: 5498 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES; 5499 break; 5500 case 2: 5501 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH; 5502 break; 5503 case 4: 5504 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH; 5505 break; 5506 default: 5507 return OMX_ErrorUnsupportedSetting; 5508 } 5509 5510 if (!arbitrary_bytes) { 5511 /* In arbitrary bytes mode, the assembler strips out nal size and replaces 5512 * with start code, so only need to notify driver in frame by frame mode */ 5513 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) { 5514 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT"); 5515 return OMX_ErrorHardware; 5516 } 5517 } 5518 5519 nal_length = pNal->nNaluBytes; 5520 m_frame_parser.init_nal_length(nal_length); 5521 5522 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length); 5523 return ret; 5524 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) { 5525 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData; 5526 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps); 5527 5528 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) { 5529 if (config->bEnabled) { 5530 if ((config->nFps >> 16) > 0 && 5531 (config->nFps >> 16) <= MAX_SUPPORTED_FPS) { 5532 m_fps_received = config->nFps; 5533 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u", 5534 (unsigned int)config->nFps >> 16); 5535 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator, 5536 drv_ctx.frame_rate.fps_denominator); 5537 5538 if (!drv_ctx.frame_rate.fps_numerator) { 5539 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 5540 drv_ctx.frame_rate.fps_numerator = 30; 5541 } 5542 5543 if (drv_ctx.frame_rate.fps_denominator) { 5544 drv_ctx.frame_rate.fps_numerator = (int) 5545 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 5546 } 5547 5548 drv_ctx.frame_rate.fps_denominator = 1; 5549 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 5550 drv_ctx.frame_rate.fps_numerator; 5551 5552 struct v4l2_outputparm oparm; 5553 /*XXX: we're providing timing info as seconds per frame rather than frames 5554 * per second.*/ 5555 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 5556 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 5557 5558 struct v4l2_streamparm sparm; 5559 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5560 sparm.parm.output = oparm; 5561 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 5562 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 5563 performance might be affected"); 5564 ret = OMX_ErrorHardware; 5565 } 5566 client_set_fps = true; 5567 } else { 5568 DEBUG_PRINT_ERROR("Frame rate not supported."); 5569 ret = OMX_ErrorUnsupportedSetting; 5570 } 5571 } else { 5572 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate"); 5573 client_set_fps = false; 5574 } 5575 } else { 5576 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d", 5577 (int)config->nPortIndex); 5578 ret = OMX_ErrorBadPortIndex; 5579 } 5580 5581 return ret; 5582 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) { 5583 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 5584 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 5585 struct v4l2_control control; 5586 5587 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel); 5588 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5589 5590 switch (perf->ePerfLevel) { 5591 case OMX_QCOM_PerfLevelNominal: 5592 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 5593 m_need_turbo &= ~TURBO_MODE_CLIENT_REQUESTED; 5594 break; 5595 case OMX_QCOM_PerfLevelTurbo: 5596 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 5597 m_need_turbo |= TURBO_MODE_CLIENT_REQUESTED; 5598 break; 5599 default: 5600 ret = OMX_ErrorUnsupportedSetting; 5601 break; 5602 } 5603 5604 if (ret == OMX_ErrorNone) { 5605 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5606 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5607 } 5608 5609 return ret; 5610 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) { 5611 OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config = 5612 (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData; 5613 struct v4l2_control control; 5614 DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType); 5615 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE; 5616 5617 switch (config->eDecodeType) { 5618 case OMX_QCOM_PictypeDecode_I: 5619 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON; 5620 break; 5621 case OMX_QCOM_PictypeDecode_IPB: 5622 default: 5623 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF; 5624 break; 5625 } 5626 5627 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ? 5628 OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 5629 if (ret) 5630 DEBUG_PRINT_ERROR("Failed to set picture type decode"); 5631 5632 return ret; 5633 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) { 5634 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData; 5635 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32); 5636 5637 struct v4l2_control control; 5638 5639 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY; 5640 if (priority->nU32 == 0) 5641 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE; 5642 else 5643 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE; 5644 5645 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5646 DEBUG_PRINT_ERROR("Failed to set Priority"); 5647 ret = OMX_ErrorUnsupportedSetting; 5648 } 5649 return ret; 5650 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) { 5651 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData; 5652 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16); 5653 5654 struct v4l2_control control; 5655 5656 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE; 5657 control.value = rate->nU32; 5658 5659 operating_frame_rate = rate->nU32 >> 16; 5660 5661 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 5662 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources : 5663 OMX_ErrorUnsupportedSetting; 5664 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)", 5665 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno)); 5666 } 5667 return ret; 5668 5669 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) { 5670 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); 5671 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 5672 if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) { 5673 enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true); 5674 } 5675 5676 print_debug_color_aspects(&(params->sAspects), "Set Config"); 5677 memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams)); 5678 return ret; 5679 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) { 5680 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams); 5681 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData; 5682 if (!DEFAULT_EXTRADATA & OMX_HDR_COLOR_INFO_EXTRADATA) { 5683 ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, true, true); 5684 if (ret != OMX_ErrorNone) { 5685 DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA"); 5686 return ret; 5687 } 5688 } 5689 5690 print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR"); 5691 memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams)); 5692 return ret; 5693 } 5694 5695 return OMX_ErrorNotImplemented; 5696} 5697 5698#define extn_equals(param, extn) (!strcmp(param, extn)) 5699 5700/* ====================================================================== 5701 FUNCTION 5702 omx_vdec::GetExtensionIndex 5703 5704 DESCRIPTION 5705 OMX GetExtensionIndex method implementaion. <TBD> 5706 5707 PARAMETERS 5708 <TBD>. 5709 5710 RETURN VALUE 5711 OMX Error None if everything successful. 5712 5713 ========================================================================== */ 5714OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 5715 OMX_IN OMX_STRING paramName, 5716 OMX_OUT OMX_INDEXTYPE* indexType) 5717{ 5718 (void) hComp; 5719 if (m_state == OMX_StateInvalid) { 5720 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State"); 5721 return OMX_ErrorInvalidState; 5722 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) { 5723 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; 5724 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) { 5725 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; 5726 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) { 5727 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata; 5728 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) { 5729 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement; 5730 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) { 5731 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData; 5732 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) { 5733 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData; 5734 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) { 5735 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData; 5736 } 5737#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 5738 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) { 5739 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; 5740 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) { 5741 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; 5742 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) { 5743 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName); 5744 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; 5745 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) { 5746 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; 5747 } 5748#if ALLOCATE_OUTPUT_NATIVEHANDLE 5749 else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) { 5750 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle; 5751 } 5752#endif //ALLOCATE_OUTPUT_NATIVEHANDLE 5753#endif 5754 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) { 5755 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; 5756 } 5757#ifdef ADAPTIVE_PLAYBACK_SUPPORTED 5758 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) { 5759 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode; 5760 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) { 5761 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback; 5762 } 5763#endif 5764#ifdef FLEXYUV_SUPPORTED 5765 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) { 5766 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription; 5767 } 5768#endif 5769 else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) { 5770 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd; 5771 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) { 5772 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB; 5773 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) { 5774 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB; 5775 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) { 5776 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode; 5777 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) { 5778 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata; 5779 } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) { 5780 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects; 5781 } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) { 5782 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo; 5783 } else { 5784 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName); 5785 return OMX_ErrorNotImplemented; 5786 } 5787 return OMX_ErrorNone; 5788} 5789 5790/* ====================================================================== 5791 FUNCTION 5792 omx_vdec::GetState 5793 5794 DESCRIPTION 5795 Returns the state information back to the caller.<TBD> 5796 5797 PARAMETERS 5798 <TBD>. 5799 5800 RETURN VALUE 5801 Error None if everything is successful. 5802 ========================================================================== */ 5803OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 5804 OMX_OUT OMX_STATETYPE* state) 5805{ 5806 (void) hComp; 5807 *state = m_state; 5808 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); 5809 return OMX_ErrorNone; 5810} 5811 5812/* ====================================================================== 5813 FUNCTION 5814 omx_vdec::ComponentTunnelRequest 5815 5816 DESCRIPTION 5817 OMX Component Tunnel Request method implementation. <TBD> 5818 5819 PARAMETERS 5820 None. 5821 5822 RETURN VALUE 5823 OMX Error None if everything successful. 5824 5825 ========================================================================== */ 5826OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 5827 OMX_IN OMX_U32 port, 5828 OMX_IN OMX_HANDLETYPE peerComponent, 5829 OMX_IN OMX_U32 peerPort, 5830 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 5831{ 5832 (void) hComp; 5833 (void) port; 5834 (void) peerComponent; 5835 (void) peerPort; 5836 (void) tunnelSetup; 5837 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented"); 5838 return OMX_ErrorNotImplemented; 5839} 5840 5841/* ====================================================================== 5842 FUNCTION 5843 omx_vdec::UseOutputBuffer 5844 5845 DESCRIPTION 5846 Helper function for Use buffer in the input pin 5847 5848 PARAMETERS 5849 None. 5850 5851 RETURN VALUE 5852 true/false 5853 5854 ========================================================================== */ 5855OMX_ERRORTYPE omx_vdec::allocate_extradata() 5856{ 5857#ifdef USE_ION 5858 if (drv_ctx.extradata_info.buffer_size) { 5859 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { 5860 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5861 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5862 free_ion_memory(&drv_ctx.extradata_info.ion); 5863 } 5864 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); 5865 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( 5866 drv_ctx.extradata_info.size, 4096, 5867 &drv_ctx.extradata_info.ion.ion_alloc_data, 5868 &drv_ctx.extradata_info.ion.fd_ion_data, 0); 5869 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { 5870 DEBUG_PRINT_ERROR("Failed to alloc extradata memory"); 5871 return OMX_ErrorInsufficientResources; 5872 } 5873 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, 5874 drv_ctx.extradata_info.size, 5875 PROT_READ|PROT_WRITE, MAP_SHARED, 5876 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); 5877 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { 5878 DEBUG_PRINT_ERROR("Failed to map extradata memory"); 5879 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5880 free_ion_memory(&drv_ctx.extradata_info.ion); 5881 return OMX_ErrorInsufficientResources; 5882 } 5883 } 5884#endif 5885 if (!m_other_extradata) { 5886 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size); 5887 if (!m_other_extradata) { 5888 DEBUG_PRINT_ERROR("Failed to alloc memory\n"); 5889 return OMX_ErrorInsufficientResources; 5890 } 5891 } 5892 return OMX_ErrorNone; 5893} 5894 5895void omx_vdec::free_extradata() 5896{ 5897#ifdef USE_ION 5898 if (drv_ctx.extradata_info.uaddr) { 5899 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 5900 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 5901 free_ion_memory(&drv_ctx.extradata_info.ion); 5902 } 5903#endif 5904 if (m_other_extradata) { 5905 free(m_other_extradata); 5906 m_other_extradata = NULL; 5907 } 5908} 5909 5910OMX_ERRORTYPE omx_vdec::use_output_buffer( 5911 OMX_IN OMX_HANDLETYPE hComp, 5912 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5913 OMX_IN OMX_U32 port, 5914 OMX_IN OMX_PTR appData, 5915 OMX_IN OMX_U32 bytes, 5916 OMX_IN OMX_U8* buffer) 5917{ 5918 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5919 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 5920 unsigned i= 0; // Temporary counter 5921 struct vdec_setbuffer_cmd setbuffers; 5922 OMX_PTR privateAppData = NULL; 5923 private_handle_t *handle = NULL; 5924 OMX_U8 *buff = buffer; 5925 struct v4l2_buffer buf; 5926 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 5927 int extra_idx = 0; 5928 (void) hComp; 5929 (void) port; 5930 5931 if (!m_out_mem_ptr) { 5932 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); 5933 eRet = allocate_output_headers(); 5934 if (eRet == OMX_ErrorNone) 5935 eRet = allocate_extradata(); 5936 } 5937 5938 if (eRet == OMX_ErrorNone) { 5939 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 5940 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 5941 break; 5942 } 5943 } 5944 } 5945 5946 if (i >= drv_ctx.op_buf.actualcount) { 5947 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount); 5948 eRet = OMX_ErrorInsufficientResources; 5949 } 5950 5951 if (eRet != OMX_ErrorNone) 5952 return eRet; 5953 5954 if (dynamic_buf_mode) { 5955 *bufferHdr = (m_out_mem_ptr + i ); 5956 (*bufferHdr)->pBuffer = NULL; 5957 if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) { 5958 enum v4l2_buf_type buf_type; 5959 int rr = 0; 5960 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5961 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) { 5962 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr); 5963 return OMX_ErrorInsufficientResources; 5964 } else { 5965 streaming[CAPTURE_PORT] = true; 5966 DEBUG_PRINT_LOW("STREAMON Successful"); 5967 } 5968 5969 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 5970 request_perf_level(VIDC_TURBO); 5971 } 5972 BITMASK_SET(&m_out_bm_count,i); 5973 (*bufferHdr)->pAppPrivate = appData; 5974 (*bufferHdr)->pBuffer = buffer; 5975 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 5976 return eRet; 5977 } 5978 5979 if (eRet == OMX_ErrorNone) { 5980#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 5981 if (m_enable_android_native_buffers) { 5982 if (m_use_android_native_buffers) { 5983 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; 5984 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 5985 handle = (private_handle_t *)nBuf->handle; 5986 privateAppData = params->pAppPrivate; 5987 } else { 5988 handle = (private_handle_t *)buff; 5989 privateAppData = appData; 5990 } 5991 if (!handle) { 5992 DEBUG_PRINT_ERROR("handle is invalid"); 5993 return OMX_ErrorBadParameter; 5994 } 5995 5996 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 5997 if (secure_mode && secure_scaling_to_non_secure_opb) { 5998 DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it", 5999 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 6000 } else { 6001 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 6002 " expected %u, got %u", 6003 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size); 6004 return OMX_ErrorBadParameter; 6005 } 6006 } 6007 6008 drv_ctx.op_buf.buffer_size = handle->size; 6009 6010 if (!m_use_android_native_buffers) { 6011 if (!secure_mode) { 6012 buff = (OMX_U8*)mmap(0, handle->size, 6013 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 6014 if (buff == MAP_FAILED) { 6015 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 6016 return OMX_ErrorInsufficientResources; 6017 } 6018 } 6019 } 6020#if defined(_ANDROID_ICS_) 6021 native_buffer[i].nativehandle = handle; 6022 native_buffer[i].privatehandle = handle; 6023#endif 6024 if (!handle) { 6025 DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); 6026 return OMX_ErrorBadParameter; 6027 } 6028 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; 6029 drv_ctx.ptr_outputbuffer[i].offset = 0; 6030 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 6031 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 6032 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size; 6033 } else 6034#endif 6035 6036 if (!ouput_egl_buffers && !m_use_output_pmem) { 6037#ifdef USE_ION 6038 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 6039 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 6040 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 6041 &drv_ctx.op_buf_ion_info[i].fd_ion_data, 6042 secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0); 6043 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 6044 DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd); 6045 return OMX_ErrorInsufficientResources; 6046 } 6047 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6048 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 6049#else 6050 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6051 open (MEM_DEVICE,O_RDWR); 6052 6053 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 6054 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 6055 return OMX_ErrorInsufficientResources; 6056 } 6057 6058 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ 6059 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) { 6060 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 6061 open (MEM_DEVICE,O_RDWR); 6062 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 6063 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 6064 return OMX_ErrorInsufficientResources; 6065 } 6066 } 6067 6068 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, 6069 drv_ctx.op_buf.buffer_size, 6070 drv_ctx.op_buf.alignment)) { 6071 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6072 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 6073 return OMX_ErrorInsufficientResources; 6074 } 6075#endif 6076 if (!secure_mode) { 6077 drv_ctx.ptr_outputbuffer[i].bufferaddr = 6078 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, 6079 PROT_READ|PROT_WRITE, MAP_SHARED, 6080 drv_ctx.ptr_outputbuffer[i].pmem_fd,0); 6081 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { 6082 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 6083#ifdef USE_ION 6084 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 6085#endif 6086 DEBUG_PRINT_ERROR("Unable to mmap output buffer"); 6087 return OMX_ErrorInsufficientResources; 6088 } 6089 } 6090 drv_ctx.ptr_outputbuffer[i].offset = 0; 6091 privateAppData = appData; 6092 } else { 6093 6094 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); 6095 if (!appData || !bytes ) { 6096 if (!secure_mode && !buffer) { 6097 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case"); 6098 return OMX_ErrorBadParameter; 6099 } 6100 } 6101 6102 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; 6103 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; 6104 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; 6105 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry || 6106 !pmem_list->nEntries || 6107 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 6108 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer"); 6109 return OMX_ErrorBadParameter; 6110 } 6111 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 6112 pmem_list->entryList->entry; 6113 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx", 6114 pmem_info->pmem_fd); 6115 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; 6116 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; 6117 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 6118 drv_ctx.ptr_outputbuffer[i].mmaped_size = 6119 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 6120 privateAppData = appData; 6121 } 6122 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 6123 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; 6124 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 6125 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 6126 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 6127 6128 *bufferHdr = (m_out_mem_ptr + i ); 6129 if (secure_mode) 6130 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 6131 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 6132 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], 6133 sizeof (vdec_bufferpayload)); 6134 6135 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, 6136 drv_ctx.ptr_outputbuffer[i].bufferaddr, 6137 drv_ctx.ptr_outputbuffer[i].pmem_fd ); 6138 6139 buf.index = i; 6140 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6141 buf.memory = V4L2_MEMORY_USERPTR; 6142 plane[0].length = drv_ctx.op_buf.buffer_size; 6143 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 6144 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 6145 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; 6146 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 6147 plane[0].data_offset = 0; 6148 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 6149 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 6150 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 6151 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 6152#ifdef USE_ION 6153 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 6154#endif 6155 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 6156 plane[extra_idx].data_offset = 0; 6157 } else if (extra_idx >= VIDEO_MAX_PLANES) { 6158 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 6159 return OMX_ErrorBadParameter; 6160 } 6161 buf.m.planes = plane; 6162 buf.length = drv_ctx.num_planes; 6163 6164 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { 6165 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 6166 /*TODO: How to handle this case */ 6167 return OMX_ErrorInsufficientResources; 6168 } 6169 6170 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { 6171 enum v4l2_buf_type buf_type; 6172 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6173 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { 6174 return OMX_ErrorInsufficientResources; 6175 } else { 6176 streaming[CAPTURE_PORT] = true; 6177 DEBUG_PRINT_LOW("STREAMON Successful"); 6178 } 6179 6180 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 6181 request_perf_level(VIDC_TURBO); 6182 } 6183 6184 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 6185 if (m_enable_android_native_buffers) { 6186 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); 6187 (*bufferHdr)->pBuffer = (OMX_U8 *)handle; 6188 } else { 6189 (*bufferHdr)->pBuffer = buff; 6190 } 6191 (*bufferHdr)->pAppPrivate = privateAppData; 6192 BITMASK_SET(&m_out_bm_count,i); 6193 } 6194 return eRet; 6195} 6196 6197/* ====================================================================== 6198 FUNCTION 6199 omx_vdec::use_input_heap_buffers 6200 6201 DESCRIPTION 6202 OMX Use Buffer Heap allocation method implementation. 6203 6204 PARAMETERS 6205 <TBD>. 6206 6207 RETURN VALUE 6208 OMX Error None , if everything successful. 6209 6210 ========================================================================== */ 6211OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( 6212 OMX_IN OMX_HANDLETYPE hComp, 6213 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6214 OMX_IN OMX_U32 port, 6215 OMX_IN OMX_PTR appData, 6216 OMX_IN OMX_U32 bytes, 6217 OMX_IN OMX_U8* buffer) 6218{ 6219 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); 6220 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6221 6222 if (secure_mode) { 6223 DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode"); 6224 return OMX_ErrorUndefined; 6225 } 6226 6227 if (!m_inp_heap_ptr) 6228 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) 6229 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 6230 drv_ctx.ip_buf.actualcount); 6231 if (!m_phdr_pmem_ptr) 6232 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) 6233 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 6234 drv_ctx.ip_buf.actualcount); 6235 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) { 6236 DEBUG_PRINT_ERROR("Insufficent memory"); 6237 eRet = OMX_ErrorInsufficientResources; 6238 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) { 6239 input_use_buffer = true; 6240 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); 6241 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; 6242 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; 6243 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; 6244 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; 6245 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; 6246 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; 6247 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); 6248 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); 6249 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt], 6250 (unsigned)NULL, (unsigned)NULL)) { 6251 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 6252 return OMX_ErrorInsufficientResources; 6253 } 6254 m_in_alloc_cnt++; 6255 } else { 6256 DEBUG_PRINT_ERROR("All i/p buffers have been set!"); 6257 eRet = OMX_ErrorInsufficientResources; 6258 } 6259 return eRet; 6260} 6261 6262/* ====================================================================== 6263 FUNCTION 6264 omx_vdec::UseBuffer 6265 6266 DESCRIPTION 6267 OMX Use Buffer method implementation. 6268 6269 PARAMETERS 6270 <TBD>. 6271 6272 RETURN VALUE 6273 OMX Error None , if everything successful. 6274 6275 ========================================================================== */ 6276OMX_ERRORTYPE omx_vdec::use_buffer( 6277 OMX_IN OMX_HANDLETYPE hComp, 6278 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6279 OMX_IN OMX_U32 port, 6280 OMX_IN OMX_PTR appData, 6281 OMX_IN OMX_U32 bytes, 6282 OMX_IN OMX_U8* buffer) 6283{ 6284 OMX_ERRORTYPE error = OMX_ErrorNone; 6285 struct vdec_setbuffer_cmd setbuffers; 6286 6287 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) { 6288 DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer); 6289 return OMX_ErrorBadParameter; 6290 } 6291 if (m_state == OMX_StateInvalid) { 6292 DEBUG_PRINT_ERROR("Use Buffer in Invalid State"); 6293 return OMX_ErrorInvalidState; 6294 } 6295 if (port == OMX_CORE_INPUT_PORT_INDEX) { 6296 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated), 6297 // ensure that use-buffer was called for previous allocation. 6298 // Mix-and-match of useBuffer and allocateBuffer is not allowed 6299 if (m_inp_mem_ptr && !input_use_buffer) { 6300 DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !"); 6301 return OMX_ErrorUndefined; 6302 } 6303 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); 6304 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) 6305 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested 6306 else { 6307 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 6308 error = OMX_ErrorBadPortIndex; 6309 } 6310 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error); 6311 if (error == OMX_ErrorNone) { 6312 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 6313 // Send the callback now 6314 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 6315 post_event(OMX_CommandStateSet,OMX_StateIdle, 6316 OMX_COMPONENT_GENERATE_EVENT); 6317 } 6318 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && 6319 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 6320 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 6321 post_event(OMX_CommandPortEnable, 6322 OMX_CORE_INPUT_PORT_INDEX, 6323 OMX_COMPONENT_GENERATE_EVENT); 6324 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && 6325 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 6326 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 6327 post_event(OMX_CommandPortEnable, 6328 OMX_CORE_OUTPUT_PORT_INDEX, 6329 OMX_COMPONENT_GENERATE_EVENT); 6330 } 6331 } 6332 return error; 6333} 6334 6335OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, 6336 OMX_BUFFERHEADERTYPE *pmem_bufferHdr) 6337{ 6338 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) { 6339 if (m_inp_heap_ptr[bufferindex].pBuffer) 6340 free(m_inp_heap_ptr[bufferindex].pBuffer); 6341 m_inp_heap_ptr[bufferindex].pBuffer = NULL; 6342 } 6343 if (pmem_bufferHdr) 6344 free_input_buffer(pmem_bufferHdr); 6345 return OMX_ErrorNone; 6346} 6347 6348OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 6349{ 6350 unsigned int index = 0; 6351 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { 6352 return OMX_ErrorBadParameter; 6353 } 6354 6355 index = bufferHdr - m_inp_mem_ptr; 6356 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 6357 6358 auto_lock l(buf_lock); 6359 bufferHdr->pInputPortPrivate = NULL; 6360 6361 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) { 6362 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 6363 if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) { 6364 struct vdec_setbuffer_cmd setbuffers; 6365 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 6366 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], 6367 sizeof (vdec_bufferpayload)); 6368 if (!secure_mode) { 6369 DEBUG_PRINT_LOW("unmap the input buffer fd=%d", 6370 drv_ctx.ptr_inputbuffer[index].pmem_fd); 6371 DEBUG_PRINT_LOW("unmap the input buffer size=%u address = %p", 6372 (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size, 6373 drv_ctx.ptr_inputbuffer[index].bufferaddr); 6374 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, 6375 drv_ctx.ptr_inputbuffer[index].mmaped_size); 6376 } 6377 6378 if (allocate_native_handle){ 6379 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer; 6380 native_handle_close(nh); 6381 native_handle_delete(nh); 6382 } else { 6383 // Close fd for non-secure and secure non-native-handle case 6384 close(drv_ctx.ptr_inputbuffer[index].pmem_fd); 6385 } 6386 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; 6387 6388 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) { 6389 free(m_desc_buffer_ptr[index].buf_addr); 6390 m_desc_buffer_ptr[index].buf_addr = NULL; 6391 m_desc_buffer_ptr[index].desc_data_size = 0; 6392 } 6393#ifdef USE_ION 6394 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); 6395#endif 6396 m_in_alloc_cnt--; 6397 } 6398 } 6399 6400 return OMX_ErrorNone; 6401} 6402 6403OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 6404{ 6405 unsigned int index = 0; 6406 6407 if (bufferHdr == NULL || m_out_mem_ptr == NULL) { 6408 return OMX_ErrorBadParameter; 6409 } 6410 6411 index = bufferHdr - m_out_mem_ptr; 6412 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); 6413 6414 if (index < drv_ctx.op_buf.actualcount 6415 && drv_ctx.ptr_outputbuffer) { 6416 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index, 6417 drv_ctx.ptr_outputbuffer[index].bufferaddr); 6418 6419 struct vdec_setbuffer_cmd setbuffers; 6420 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 6421 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], 6422 sizeof (vdec_bufferpayload)); 6423 6424 if (!dynamic_buf_mode) { 6425 if (streaming[CAPTURE_PORT] && 6426 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) { 6427 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 6428 DEBUG_PRINT_ERROR("STREAMOFF Failed"); 6429 } else { 6430 DEBUG_PRINT_LOW("STREAMOFF Successful"); 6431 } 6432 } 6433#ifdef _ANDROID_ 6434 if (m_enable_android_native_buffers) { 6435 if (!secure_mode) { 6436 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { 6437 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, 6438 drv_ctx.ptr_outputbuffer[index].mmaped_size); 6439 } 6440 } 6441 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 6442 } else { 6443#endif 6444 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 6445 && !ouput_egl_buffers && !m_use_output_pmem) { 6446 if (drv_ctx.op_buf_map_info[index].free_buffer) { 6447 if (!secure_mode) { 6448 DEBUG_PRINT_LOW("unmap the output buffer fd = %d", 6449 drv_ctx.ptr_outputbuffer[0].pmem_fd); 6450 DEBUG_PRINT_LOW("unmap the ouput buffer size=%u address = %p", 6451 (unsigned int)drv_ctx.op_buf_map_info[index].map_size, 6452 drv_ctx.op_buf_map_info[index].base_address); 6453 munmap (drv_ctx.op_buf_map_info[index].base_address, 6454 drv_ctx.op_buf_map_info[index].map_size); 6455 } 6456 close (drv_ctx.ptr_outputbuffer[index].pmem_fd); 6457 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 6458#ifdef USE_ION 6459 free_ion_memory(&drv_ctx.op_buf_ion_info[index]); 6460#endif 6461 } else { 6462 drv_ctx.op_buf_ion_info[index].ion_device_fd = -1; 6463 drv_ctx.op_buf_ion_info[index].ion_alloc_data.handle = 0; 6464 drv_ctx.op_buf_ion_info[index].fd_ion_data.fd = -1; 6465 } 6466 drv_ctx.op_buf_map_info[index].free_buffer = false; 6467 drv_ctx.op_buf_map_info[index].base_address = NULL; 6468 drv_ctx.op_buf_map_info[index].map_size = 0; 6469 drv_ctx.op_buf_map_info[index].offset = 0; 6470 } 6471#ifdef _ANDROID_ 6472 } 6473#endif 6474 } //!dynamic_buf_mode 6475 if (release_output_done()) { 6476 free_extradata(); 6477 } 6478 } 6479 6480 return OMX_ErrorNone; 6481 6482} 6483 6484OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 6485 OMX_BUFFERHEADERTYPE **bufferHdr, 6486 OMX_U32 port, 6487 OMX_PTR appData, 6488 OMX_U32 bytes) 6489{ 6490 OMX_BUFFERHEADERTYPE *input = NULL; 6491 unsigned char *buf_addr = NULL; 6492 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6493 unsigned i = 0; 6494 6495 /* Sanity Check*/ 6496 if (bufferHdr == NULL) { 6497 return OMX_ErrorBadParameter; 6498 } 6499 6500 if (m_inp_heap_ptr == NULL) { 6501 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 6502 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 6503 drv_ctx.ip_buf.actualcount); 6504 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 6505 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 6506 drv_ctx.ip_buf.actualcount); 6507 6508 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) { 6509 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed "); 6510 return OMX_ErrorInsufficientResources; 6511 } 6512 } 6513 6514 /*Find a Free index*/ 6515 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6516 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) { 6517 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6518 break; 6519 } 6520 } 6521 6522 if (i < drv_ctx.ip_buf.actualcount) { 6523 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); 6524 6525 if (buf_addr == NULL) { 6526 return OMX_ErrorInsufficientResources; 6527 } 6528 6529 *bufferHdr = (m_inp_heap_ptr + i); 6530 input = *bufferHdr; 6531 BITMASK_SET(&m_heap_inp_bm_count,i); 6532 6533 input->pBuffer = (OMX_U8 *)buf_addr; 6534 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6535 input->nVersion.nVersion = OMX_SPEC_VERSION; 6536 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6537 input->pAppPrivate = appData; 6538 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6539 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); 6540 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 6541 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); 6542 /*Add the Buffers to freeq*/ 6543 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i], 6544 (unsigned)NULL, (unsigned)NULL)) { 6545 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 6546 return OMX_ErrorInsufficientResources; 6547 } 6548 } else { 6549 return OMX_ErrorBadParameter; 6550 } 6551 6552 return eRet; 6553 6554} 6555 6556 6557/* ====================================================================== 6558 FUNCTION 6559 omx_vdec::AllocateInputBuffer 6560 6561 DESCRIPTION 6562 Helper function for allocate buffer in the input pin 6563 6564 PARAMETERS 6565 None. 6566 6567 RETURN VALUE 6568 true/false 6569 6570 ========================================================================== */ 6571OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 6572 OMX_IN OMX_HANDLETYPE hComp, 6573 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6574 OMX_IN OMX_U32 port, 6575 OMX_IN OMX_PTR appData, 6576 OMX_IN OMX_U32 bytes) 6577{ 6578 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6579 struct vdec_setbuffer_cmd setbuffers; 6580 OMX_BUFFERHEADERTYPE *input = NULL; 6581 unsigned i = 0; 6582 unsigned char *buf_addr = NULL; 6583 int pmem_fd = -1; 6584 6585 (void) hComp; 6586 (void) port; 6587 6588 6589 if (bytes != drv_ctx.ip_buf.buffer_size) { 6590 DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u", 6591 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size); 6592 return OMX_ErrorBadParameter; 6593 } 6594 6595 if (!m_inp_mem_ptr) { 6596 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)", 6597 drv_ctx.ip_buf.actualcount, 6598 (unsigned int)drv_ctx.ip_buf.buffer_size); 6599 6600 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 6601 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); 6602 6603 if (m_inp_mem_ptr == NULL) { 6604 return OMX_ErrorInsufficientResources; 6605 } 6606 6607 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 6608 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); 6609 6610 if (drv_ctx.ptr_inputbuffer == NULL) { 6611 return OMX_ErrorInsufficientResources; 6612 } 6613#ifdef USE_ION 6614 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ 6615 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); 6616 6617 if (drv_ctx.ip_buf_ion_info == NULL) { 6618 return OMX_ErrorInsufficientResources; 6619 } 6620#endif 6621 6622 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) { 6623 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; 6624#ifdef USE_ION 6625 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; 6626#endif 6627 } 6628 } 6629 6630 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 6631 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 6632 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 6633 break; 6634 } 6635 } 6636 6637 if (i < drv_ctx.ip_buf.actualcount) { 6638 struct v4l2_buffer buf; 6639 struct v4l2_plane plane; 6640 int rc; 6641 DEBUG_PRINT_LOW("Allocate input Buffer"); 6642#ifdef USE_ION 6643 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 6644 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, 6645 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, 6646 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? 6647 SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED); 6648 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { 6649 return OMX_ErrorInsufficientResources; 6650 } 6651 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; 6652#else 6653 pmem_fd = open (MEM_DEVICE,O_RDWR); 6654 6655 if (pmem_fd < 0) { 6656 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6657 return OMX_ErrorInsufficientResources; 6658 } 6659 6660 if (pmem_fd == 0) { 6661 pmem_fd = open (MEM_DEVICE,O_RDWR); 6662 6663 if (pmem_fd < 0) { 6664 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 6665 return OMX_ErrorInsufficientResources; 6666 } 6667 } 6668 6669 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, 6670 drv_ctx.ip_buf.alignment)) { 6671 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6672 close(pmem_fd); 6673 return OMX_ErrorInsufficientResources; 6674 } 6675#endif 6676 if (!secure_mode) { 6677 buf_addr = (unsigned char *)mmap(NULL, 6678 drv_ctx.ip_buf.buffer_size, 6679 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); 6680 6681 if (buf_addr == MAP_FAILED) { 6682 close(pmem_fd); 6683#ifdef USE_ION 6684 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); 6685#endif 6686 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer"); 6687 return OMX_ErrorInsufficientResources; 6688 } 6689 } 6690 *bufferHdr = (m_inp_mem_ptr + i); 6691 if (secure_mode) 6692 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; 6693 else 6694 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; 6695 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; 6696 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; 6697 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; 6698 drv_ctx.ptr_inputbuffer [i].offset = 0; 6699 6700 6701 buf.index = i; 6702 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 6703 buf.memory = V4L2_MEMORY_USERPTR; 6704 plane.bytesused = 0; 6705 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; 6706 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; 6707 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; 6708 plane.reserved[1] = 0; 6709 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; 6710 buf.m.planes = &plane; 6711 buf.length = 1; 6712 6713 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i, 6714 drv_ctx.ptr_inputbuffer[i].bufferaddr); 6715 6716 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 6717 6718 if (rc) { 6719 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 6720 /*TODO: How to handle this case */ 6721 return OMX_ErrorInsufficientResources; 6722 } 6723 6724 input = *bufferHdr; 6725 BITMASK_SET(&m_inp_bm_count,i); 6726 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); 6727 if (allocate_native_handle) { 6728 native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/); 6729 if (!nh) { 6730 DEBUG_PRINT_ERROR("Native handle create failed"); 6731 return OMX_ErrorInsufficientResources; 6732 } 6733 nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd; 6734 input->pBuffer = (OMX_U8 *)nh; 6735 } else if (secure_mode || m_input_pass_buffer_fd) { 6736 /*Legacy method, pass ion fd stashed directly in pBuffer*/ 6737 input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd; 6738 } else { 6739 input->pBuffer = (OMX_U8 *)buf_addr; 6740 } 6741 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6742 input->nVersion.nVersion = OMX_SPEC_VERSION; 6743 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 6744 input->pAppPrivate = appData; 6745 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 6746 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; 6747 6748 if (drv_ctx.disable_dmx) { 6749 eRet = allocate_desc_buffer(i); 6750 } 6751 } else { 6752 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found"); 6753 eRet = OMX_ErrorInsufficientResources; 6754 } 6755 return eRet; 6756} 6757 6758 6759/* ====================================================================== 6760 FUNCTION 6761 omx_vdec::AllocateOutputBuffer 6762 6763 DESCRIPTION 6764 Helper fn for AllocateBuffer in the output pin 6765 6766 PARAMETERS 6767 <TBD>. 6768 6769 RETURN VALUE 6770 OMX Error None if everything went well. 6771 6772 ========================================================================== */ 6773OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 6774 OMX_IN OMX_HANDLETYPE hComp, 6775 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6776 OMX_IN OMX_U32 port, 6777 OMX_IN OMX_PTR appData, 6778 OMX_IN OMX_U32 bytes) 6779{ 6780 (void)hComp; 6781 (void)port; 6782 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6783 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 6784 unsigned i= 0; // Temporary counter 6785 struct vdec_setbuffer_cmd setbuffers; 6786 int extra_idx = 0; 6787#ifdef USE_ION 6788 int ion_device_fd =-1; 6789 struct ion_allocation_data ion_alloc_data; 6790 struct ion_fd_data fd_ion_data; 6791#endif 6792 if (!m_out_mem_ptr) { 6793 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)", 6794 drv_ctx.op_buf.actualcount, 6795 (unsigned int)drv_ctx.op_buf.buffer_size); 6796 int nBufHdrSize = 0; 6797 int nPlatformEntrySize = 0; 6798 int nPlatformListSize = 0; 6799 int nPMEMInfoSize = 0; 6800 6801 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 6802 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 6803 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 6804 6805 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", 6806 drv_ctx.op_buf.actualcount); 6807 nBufHdrSize = drv_ctx.op_buf.actualcount * 6808 sizeof(OMX_BUFFERHEADERTYPE); 6809 6810 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 6811 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 6812 nPlatformListSize = drv_ctx.op_buf.actualcount * 6813 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 6814 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 6815 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 6816 6817 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 6818 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 6819 nPMEMInfoSize, 6820 nPlatformListSize); 6821 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, 6822 drv_ctx.op_buf.actualcount); 6823 unsigned char *pmem_baseaddress_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {NULL}; 6824 int pmem_fd[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {-1}; 6825 int alloc_size[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {0}; 6826 static const int block_max_size = 128 * 1024 * 1024; 6827 unsigned int block_buf_count = block_max_size / drv_ctx.op_buf.buffer_size; 6828 unsigned int last_block_buf_count = 0, block_count = 1; 6829 if (drv_ctx.op_buf.actualcount <= block_buf_count) { 6830 block_buf_count = drv_ctx.op_buf.actualcount; 6831 } else { 6832 last_block_buf_count = drv_ctx.op_buf.actualcount % block_buf_count; 6833 block_count = (drv_ctx.op_buf.actualcount + block_buf_count - 1) / block_buf_count; 6834 } 6835 unsigned int idx = 0; 6836 DEBUG_PRINT_LOW("block_count = %d block_buf_count = %d last_block_buf_count = %d", 6837 block_count, block_buf_count, last_block_buf_count); 6838#ifdef USE_ION 6839 struct vdec_ion op_buf_ion_info_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS]; 6840 int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED; 6841 for (; idx < block_count; idx++) { 6842 int cnt = ((idx == block_count - 1) && last_block_buf_count) ? 6843 last_block_buf_count : block_buf_count; 6844 alloc_size[idx] = drv_ctx.op_buf.buffer_size * cnt; 6845 // Allocate output buffers as cached to improve performance of software-reading 6846 // of the YUVs. Output buffers are cache-invalidated in driver. 6847 // If color-conversion is involved, Only the C2D output buffers are cached, no 6848 // need to cache the decoder's output buffers 6849 op_buf_ion_info_temp[idx].ion_device_fd = alloc_map_ion_memory( 6850 alloc_size[idx], 6851 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment, 6852 &op_buf_ion_info_temp[idx].ion_alloc_data, &op_buf_ion_info_temp[idx].fd_ion_data, 6853 (secure_mode && !secure_scaling_to_non_secure_opb) ? 6854 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag); 6855 if (op_buf_ion_info_temp[idx].ion_device_fd < 0) { 6856 DEBUG_PRINT_LOW("Failed to allocate chunk %ul size = %d", idx, alloc_size[idx]); 6857 break; 6858 } 6859 pmem_fd[idx] = op_buf_ion_info_temp[idx].fd_ion_data.fd; 6860 DEBUG_PRINT_LOW("Allocated chunk %ul fd = %ul size = %d", idx, pmem_fd[idx], alloc_size[idx]); 6861 } 6862 if (idx != block_count) { 6863 for (OMX_U32 i = 0; i < idx; i++) { 6864 close(pmem_fd[i]); 6865 free_ion_memory(&op_buf_ion_info_temp[i]); 6866 } 6867 return OMX_ErrorInsufficientResources; 6868 } 6869 6870#else 6871 for (idx = 0; idx < block_count; idx++) { 6872 pmem_fd[idx] = open (MEM_DEVICE,O_RDWR); 6873 6874 if (pmem_fd[idx] < 0) { 6875 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d", 6876 drv_ctx.op_buf.buffer_size); 6877 break; 6878 } 6879 int cnt = ((idx == block_count - 1) && last_block_buf_count) ? 6880 last_block_buf_count : block_buf_count; 6881 if (!align_pmem_buffers(pmem_fd[idx], drv_ctx.op_buf.buffer_size * cnt, 6882 drv_ctx.op_buf.alignment)) { 6883 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 6884 close(pmem_fd[idx]); 6885 break; 6886 } 6887 } 6888 if (idx != block_count) { 6889 for (i = 0; i < idx; i++) { 6890 close(pmem_fd[i]); 6891 } 6892 return OMX_ErrorInsufficientResources; 6893 } 6894#endif 6895 if (!secure_mode) { 6896 idx = 0; 6897 for (; idx < block_count; idx++) { 6898 pmem_baseaddress_temp[idx] = (unsigned char *)mmap(NULL, 6899 alloc_size[idx], 6900 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd[idx], 0); 6901 6902 if (pmem_baseaddress_temp[idx] == MAP_FAILED) { 6903 DEBUG_PRINT_ERROR("MMAP failed for Size %u for fd = %d", 6904 (unsigned int)alloc_size[idx], pmem_fd[idx]); 6905 close(pmem_fd[idx]); 6906#ifdef USE_ION 6907 free_ion_memory(&op_buf_ion_info_temp[idx]); 6908#endif 6909 break; 6910 } 6911 } 6912 if (idx != block_count) { 6913 for (i = 0; i < idx; i++) { 6914 munmap(pmem_baseaddress_temp[idx], alloc_size[idx]); 6915 close(pmem_fd[i]); 6916#ifdef USE_ION 6917 free_ion_memory(&op_buf_ion_info_temp[i]); 6918#endif 6919 } 6920 return OMX_ErrorInsufficientResources; 6921 } 6922 } 6923 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 6924 // Alloc mem for platform specific info 6925 char *pPtr=NULL; 6926 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 6927 nPMEMInfoSize,1); 6928 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ 6929 calloc (sizeof(struct vdec_bufferpayload), 6930 drv_ctx.op_buf.actualcount); 6931 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 6932 calloc (sizeof (struct vdec_output_frameinfo), 6933 drv_ctx.op_buf.actualcount); 6934 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 6935 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer "); 6936 return OMX_ErrorInsufficientResources; 6937 } 6938 6939#ifdef USE_ION 6940 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ 6941 calloc (sizeof(struct vdec_ion), 6942 drv_ctx.op_buf.actualcount); 6943 if (!drv_ctx.op_buf_ion_info) { 6944 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 6945 return OMX_ErrorInsufficientResources; 6946 } 6947#endif 6948 drv_ctx.op_buf_map_info = (struct vdec_ion_map_info *)\ 6949 calloc (sizeof(struct vdec_ion_map_info), 6950 drv_ctx.op_buf.actualcount); 6951 if (!drv_ctx.op_buf_map_info) { 6952 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_map_info"); 6953 return OMX_ErrorInsufficientResources; 6954 } 6955 6956 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 6957 && drv_ctx.ptr_respbuffer) { 6958 drv_ctx.ptr_outputbuffer[0].mmaped_size = 6959 (drv_ctx.op_buf.buffer_size * 6960 drv_ctx.op_buf.actualcount); 6961 bufHdr = m_out_mem_ptr; 6962 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 6963 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 6964 (((char *) m_platform_list) + nPlatformListSize); 6965 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 6966 (((char *) m_platform_entry) + nPlatformEntrySize); 6967 pPlatformList = m_platform_list; 6968 pPlatformEntry = m_platform_entry; 6969 pPMEMInfo = m_pmem_info; 6970 6971 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 6972 6973 // Settting the entire storage nicely 6974 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); 6975 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 6976 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 6977 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 6978 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 6979 // Set the values when we determine the right HxW param 6980 bufHdr->nAllocLen = bytes; 6981 bufHdr->nFilledLen = 0; 6982 bufHdr->pAppPrivate = appData; 6983 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 6984 // Platform specific PMEM Information 6985 // Initialize the Platform Entry 6986 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); 6987 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 6988 pPlatformEntry->entry = pPMEMInfo; 6989 // Initialize the Platform List 6990 pPlatformList->nEntries = 1; 6991 pPlatformList->entryList = pPlatformEntry; 6992 // Keep pBuffer NULL till vdec is opened 6993 bufHdr->pBuffer = NULL; 6994 bufHdr->nOffset = 0; 6995 6996 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; 6997 pPMEMInfo->pmem_fd = -1; 6998 bufHdr->pPlatformPrivate = pPlatformList; 6999 7000 int block_idx = i / block_buf_count; 7001 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd[block_idx]; 7002 m_pmem_info[i].pmem_fd = pmem_fd[block_idx]; 7003#ifdef USE_ION 7004 drv_ctx.op_buf_ion_info[i].ion_device_fd = op_buf_ion_info_temp[block_idx].ion_device_fd; 7005 drv_ctx.op_buf_ion_info[i].ion_alloc_data = op_buf_ion_info_temp[block_idx].ion_alloc_data; 7006 drv_ctx.op_buf_ion_info[i].fd_ion_data = op_buf_ion_info_temp[block_idx].fd_ion_data; 7007#endif 7008 drv_ctx.op_buf_map_info[i].free_buffer = !(i % block_buf_count); 7009 drv_ctx.op_buf_map_info[i].base_address = pmem_baseaddress_temp[block_idx]; 7010 drv_ctx.op_buf_map_info[i].map_size = alloc_size[block_idx]; 7011 drv_ctx.op_buf_map_info[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count); 7012 7013 /*Create a mapping between buffers*/ 7014 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 7015 drv_ctx.ptr_respbuffer[i].client_data = (void *)\ 7016 &drv_ctx.ptr_outputbuffer[i]; 7017 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count); 7018 drv_ctx.ptr_outputbuffer[i].bufferaddr = 7019 pmem_baseaddress_temp[block_idx] + (drv_ctx.op_buf.buffer_size * (i % block_buf_count)); 7020 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; 7021 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; 7022 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; 7023 7024 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p", 7025 pmem_fd[block_idx], (unsigned int)drv_ctx.ptr_outputbuffer[i].offset, 7026 drv_ctx.ptr_outputbuffer[i].bufferaddr); 7027 // Move the buffer and buffer header pointers 7028 bufHdr++; 7029 pPMEMInfo++; 7030 pPlatformEntry++; 7031 pPlatformList++; 7032 } 7033 } else { 7034 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 7035 m_out_mem_ptr, pPtr); 7036 if (m_out_mem_ptr) { 7037 free(m_out_mem_ptr); 7038 m_out_mem_ptr = NULL; 7039 } 7040 if (pPtr) { 7041 free(pPtr); 7042 pPtr = NULL; 7043 } 7044 if (drv_ctx.ptr_outputbuffer) { 7045 free(drv_ctx.ptr_outputbuffer); 7046 drv_ctx.ptr_outputbuffer = NULL; 7047 } 7048 if (drv_ctx.ptr_respbuffer) { 7049 free(drv_ctx.ptr_respbuffer); 7050 drv_ctx.ptr_respbuffer = NULL; 7051 } 7052#ifdef USE_ION 7053 if (drv_ctx.op_buf_ion_info) { 7054 DEBUG_PRINT_LOW("Free o/p ion context"); 7055 free(drv_ctx.op_buf_ion_info); 7056 drv_ctx.op_buf_ion_info = NULL; 7057 } 7058#endif 7059 free(drv_ctx.op_buf_map_info); 7060 drv_ctx.op_buf_map_info = NULL; 7061 eRet = OMX_ErrorInsufficientResources; 7062 } 7063 if (eRet == OMX_ErrorNone) 7064 eRet = allocate_extradata(); 7065 } 7066 7067 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 7068 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 7069 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i); 7070 break; 7071 } 7072 } 7073 7074 if (eRet == OMX_ErrorNone) { 7075 if (i < drv_ctx.op_buf.actualcount) { 7076 struct v4l2_buffer buf; 7077 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 7078 int rc; 7079 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 7080 7081 drv_ctx.ptr_outputbuffer[i].buffer_len = 7082 drv_ctx.op_buf.buffer_size; 7083 7084 *bufferHdr = (m_out_mem_ptr + i ); 7085 if (secure_mode) { 7086#ifdef USE_ION 7087 drv_ctx.ptr_outputbuffer[i].bufferaddr = 7088 (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 7089#else 7090 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 7091#endif 7092 } 7093 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; 7094 7095 buf.index = i; 7096 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7097 buf.memory = V4L2_MEMORY_USERPTR; 7098 plane[0].length = drv_ctx.op_buf.buffer_size; 7099 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 7100 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 7101#ifdef USE_ION 7102 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 7103#endif 7104 plane[0].reserved[1] = drv_ctx.op_buf_map_info[i].offset; 7105 plane[0].data_offset = 0; 7106 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 7107 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 7108 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 7109 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 7110#ifdef USE_ION 7111 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 7112#endif 7113 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 7114 plane[extra_idx].data_offset = 0; 7115 } else if (extra_idx >= VIDEO_MAX_PLANES) { 7116 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx); 7117 return OMX_ErrorBadParameter; 7118 } 7119 buf.m.planes = plane; 7120 buf.length = drv_ctx.num_planes; 7121 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr); 7122 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 7123 if (rc) { 7124 /*TODO: How to handle this case */ 7125 return OMX_ErrorInsufficientResources; 7126 } 7127 7128 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { 7129 enum v4l2_buf_type buf_type; 7130 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7131 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 7132 if (rc) { 7133 return OMX_ErrorInsufficientResources; 7134 } else { 7135 streaming[CAPTURE_PORT] = true; 7136 DEBUG_PRINT_LOW("STREAMON Successful"); 7137 } 7138 7139 DEBUG_PRINT_HIGH("Enabling Turbo mode"); 7140 request_perf_level(VIDC_TURBO); 7141 } 7142 7143 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; 7144 (*bufferHdr)->pAppPrivate = appData; 7145 BITMASK_SET(&m_out_bm_count,i); 7146 } else { 7147 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient"); 7148 eRet = OMX_ErrorInsufficientResources; 7149 } 7150 } 7151 7152 return eRet; 7153} 7154 7155 7156// AllocateBuffer -- API Call 7157/* ====================================================================== 7158 FUNCTION 7159 omx_vdec::AllocateBuffer 7160 7161 DESCRIPTION 7162 Returns zero if all the buffers released.. 7163 7164 PARAMETERS 7165 None. 7166 7167 RETURN VALUE 7168 true/false 7169 7170 ========================================================================== */ 7171OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 7172 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 7173 OMX_IN OMX_U32 port, 7174 OMX_IN OMX_PTR appData, 7175 OMX_IN OMX_U32 bytes) 7176{ 7177 unsigned i = 0; 7178 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 7179 7180 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); 7181 if (m_state == OMX_StateInvalid) { 7182 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State"); 7183 return OMX_ErrorInvalidState; 7184 } 7185 7186 if (port == OMX_CORE_INPUT_PORT_INDEX) { 7187 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated), 7188 // ensure that use-buffer was never called. 7189 // Mix-and-match of useBuffer and allocateBuffer is not allowed 7190 if (m_inp_mem_ptr && input_use_buffer) { 7191 DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !"); 7192 return OMX_ErrorUndefined; 7193 } 7194 if (arbitrary_bytes) { 7195 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 7196 } else { 7197 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 7198 } 7199 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 7200 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, 7201 appData,bytes); 7202 } else { 7203 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 7204 eRet = OMX_ErrorBadPortIndex; 7205 } 7206 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 7207 if (eRet == OMX_ErrorNone) { 7208 if (allocate_done()) { 7209 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 7210 // Send the callback now 7211 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 7212 post_event(OMX_CommandStateSet,OMX_StateIdle, 7213 OMX_COMPONENT_GENERATE_EVENT); 7214 } 7215 } 7216 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) { 7217 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 7218 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 7219 post_event(OMX_CommandPortEnable, 7220 OMX_CORE_INPUT_PORT_INDEX, 7221 OMX_COMPONENT_GENERATE_EVENT); 7222 } 7223 } 7224 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) { 7225 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 7226 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 7227 post_event(OMX_CommandPortEnable, 7228 OMX_CORE_OUTPUT_PORT_INDEX, 7229 OMX_COMPONENT_GENERATE_EVENT); 7230 } 7231 } 7232 } 7233 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); 7234 return eRet; 7235} 7236 7237// Free Buffer - API call 7238/* ====================================================================== 7239 FUNCTION 7240 omx_vdec::FreeBuffer 7241 7242 DESCRIPTION 7243 7244 PARAMETERS 7245 None. 7246 7247 RETURN VALUE 7248 true/false 7249 7250 ========================================================================== */ 7251OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 7252 OMX_IN OMX_U32 port, 7253 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7254{ 7255 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7256 unsigned int nPortIndex; 7257 (void) hComp; 7258 DEBUG_PRINT_LOW("In for decoder free_buffer"); 7259 7260 if (m_state == OMX_StateIdle && 7261 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 7262 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); 7263 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 7264 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) { 7265 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port); 7266 } else if ((port == OMX_CORE_INPUT_PORT_INDEX && 7267 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || 7268 (port == OMX_CORE_OUTPUT_PORT_INDEX && 7269 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) { 7270 DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port); 7271 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) { 7272 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled"); 7273 post_event(OMX_EventError, 7274 OMX_ErrorPortUnpopulated, 7275 OMX_COMPONENT_GENERATE_EVENT); 7276 7277 return OMX_ErrorIncorrectStateOperation; 7278 } else if (m_state != OMX_StateInvalid) { 7279 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers"); 7280 post_event(OMX_EventError, 7281 OMX_ErrorPortUnpopulated, 7282 OMX_COMPONENT_GENERATE_EVENT); 7283 } 7284 7285 if (port == OMX_CORE_INPUT_PORT_INDEX) { 7286 /*Check if arbitrary bytes*/ 7287 if (!arbitrary_bytes && !input_use_buffer) 7288 nPortIndex = buffer - m_inp_mem_ptr; 7289 else 7290 nPortIndex = buffer - m_inp_heap_ptr; 7291 7292 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); 7293 if (nPortIndex < drv_ctx.ip_buf.actualcount && 7294 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) { 7295 // Clear the bit associated with it. 7296 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 7297 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 7298 if (input_use_buffer == true) { 7299 7300 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); 7301 if (m_phdr_pmem_ptr) 7302 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 7303 } else { 7304 if (arbitrary_bytes) { 7305 if (m_phdr_pmem_ptr) 7306 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); 7307 else 7308 free_input_buffer(nPortIndex,NULL); 7309 } else 7310 free_input_buffer(buffer); 7311 } 7312 m_inp_bPopulated = OMX_FALSE; 7313 if(release_input_done()) 7314 release_buffers(this, VDEC_BUFFER_TYPE_INPUT); 7315 /*Free the Buffer Header*/ 7316 if (release_input_done()) { 7317 DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); 7318 free_input_buffer_header(); 7319 } 7320 } else { 7321 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid"); 7322 eRet = OMX_ErrorBadPortIndex; 7323 } 7324 7325 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 7326 && release_input_done()) { 7327 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 7328 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 7329 post_event(OMX_CommandPortDisable, 7330 OMX_CORE_INPUT_PORT_INDEX, 7331 OMX_COMPONENT_GENERATE_EVENT); 7332 } 7333 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 7334 // check if the buffer is valid 7335 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 7336 if (nPortIndex < drv_ctx.op_buf.actualcount && 7337 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) { 7338 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); 7339 // Clear the bit associated with it. 7340 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 7341 m_out_bPopulated = OMX_FALSE; 7342 client_buffers.free_output_buffer (buffer); 7343 7344 if(release_output_done()) { 7345 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT); 7346 } 7347 if (release_output_done()) { 7348 free_output_buffer_header(); 7349 } 7350 } else { 7351 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid"); 7352 eRet = OMX_ErrorBadPortIndex; 7353 } 7354 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 7355 && release_output_done()) { 7356 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); 7357 7358 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 7359 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 7360#ifdef _ANDROID_ICS_ 7361 if (m_enable_android_native_buffers) { 7362 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); 7363 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 7364 } 7365#endif 7366 7367 post_event(OMX_CommandPortDisable, 7368 OMX_CORE_OUTPUT_PORT_INDEX, 7369 OMX_COMPONENT_GENERATE_EVENT); 7370 } 7371 } else { 7372 eRet = OMX_ErrorBadPortIndex; 7373 } 7374 if ((eRet == OMX_ErrorNone) && 7375 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 7376 if (release_done()) { 7377 /* 7378 * Reset buffer requirements here to ensure setting buffer requirement 7379 * when component move to executing state from loaded state via idle. 7380 */ 7381 drv_ctx.op_buf.buffer_size = 0; 7382 drv_ctx.op_buf.actualcount = 0; 7383 7384 // Send the callback now 7385 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 7386 post_event(OMX_CommandStateSet, OMX_StateLoaded, 7387 OMX_COMPONENT_GENERATE_EVENT); 7388 } 7389 } 7390 return eRet; 7391} 7392 7393 7394/* ====================================================================== 7395 FUNCTION 7396 omx_vdec::EmptyThisBuffer 7397 7398 DESCRIPTION 7399 This routine is used to push the encoded video frames to 7400 the video decoder. 7401 7402 PARAMETERS 7403 None. 7404 7405 RETURN VALUE 7406 OMX Error None if everything went successful. 7407 7408 ========================================================================== */ 7409OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 7410 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7411{ 7412 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 7413 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; 7414 7415 if (m_state != OMX_StateExecuting && 7416 m_state != OMX_StatePause && 7417 m_state != OMX_StateIdle) { 7418 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State"); 7419 return OMX_ErrorInvalidState; 7420 } 7421 7422 if (buffer == NULL) { 7423 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL"); 7424 return OMX_ErrorBadParameter; 7425 } 7426 7427 if (!m_inp_bEnabled) { 7428 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled."); 7429 return OMX_ErrorIncorrectStateOperation; 7430 } 7431 7432 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 7433 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex); 7434 return OMX_ErrorBadPortIndex; 7435 } 7436 7437 if (perf_flag) { 7438 if (!latency) { 7439 dec_time.stop(); 7440 latency = dec_time.processing_time_us(); 7441 dec_time.start(); 7442 } 7443 } 7444 7445 if (arbitrary_bytes) { 7446 nBufferIndex = buffer - m_inp_heap_ptr; 7447 } else { 7448 if (input_use_buffer == true) { 7449 nBufferIndex = buffer - m_inp_heap_ptr; 7450 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) { 7451 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode"); 7452 return OMX_ErrorBadParameter; 7453 } 7454 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; 7455 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; 7456 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; 7457 buffer = &m_inp_mem_ptr[nBufferIndex]; 7458 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u", 7459 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen); 7460 } else { 7461 nBufferIndex = buffer - m_inp_mem_ptr; 7462 } 7463 } 7464 7465 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) { 7466 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid"); 7467 return OMX_ErrorBadParameter; 7468 } 7469 7470 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 7471 codec_config_flag = true; 7472 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); 7473 } 7474 7475 /* The client should not set this when codec is in arbitrary bytes mode */ 7476 if (m_input_pass_buffer_fd) { 7477 buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr; 7478 } 7479 7480 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)", 7481 buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen); 7482 if (arbitrary_bytes) { 7483 post_event ((unsigned long)hComp,(unsigned long)buffer, 7484 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 7485 } else { 7486 post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB); 7487 } 7488 time_stamp_dts.insert_timestamp(buffer); 7489 return OMX_ErrorNone; 7490} 7491 7492/* ====================================================================== 7493 FUNCTION 7494 omx_vdec::empty_this_buffer_proxy 7495 7496 DESCRIPTION 7497 This routine is used to push the encoded video frames to 7498 the video decoder. 7499 7500 PARAMETERS 7501 None. 7502 7503 RETURN VALUE 7504 OMX Error None if everything went successful. 7505 7506 ========================================================================== */ 7507OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 7508 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7509{ 7510 VIDC_TRACE_NAME_HIGH("ETB"); 7511 (void) hComp; 7512 int push_cnt = 0,i=0; 7513 unsigned nPortIndex = 0; 7514 OMX_ERRORTYPE ret = OMX_ErrorNone; 7515 struct vdec_input_frameinfo frameinfo; 7516 struct vdec_bufferpayload *temp_buffer; 7517 struct vdec_seqheader seq_header; 7518 bool port_setting_changed = true; 7519 7520 /*Should we generate a Aync error event*/ 7521 if (buffer == NULL || buffer->pInputPortPrivate == NULL) { 7522 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid"); 7523 return OMX_ErrorBadParameter; 7524 } 7525 7526 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 7527 7528 if (nPortIndex >= drv_ctx.ip_buf.actualcount) { 7529 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 7530 nPortIndex); 7531 return OMX_ErrorBadParameter; 7532 } 7533 7534 pending_input_buffers++; 7535 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 7536 7537 /* return zero length and not an EOS buffer */ 7538 if (!arbitrary_bytes && (buffer->nFilledLen == 0) && 7539 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) { 7540 DEBUG_PRINT_HIGH("return zero legth buffer"); 7541 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 7542 OMX_COMPONENT_GENERATE_EBD); 7543 return OMX_ErrorNone; 7544 } 7545 7546 if (input_flush_progress == true) { 7547 DEBUG_PRINT_LOW("Flush in progress return buffer "); 7548 post_event ((unsigned long)buffer,VDEC_S_SUCCESS, 7549 OMX_COMPONENT_GENERATE_EBD); 7550 return OMX_ErrorNone; 7551 } 7552 7553 auto_lock l(buf_lock); 7554 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 7555 7556 if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) { 7557 return OMX_ErrorBadParameter; 7558 } 7559 /* If its first frame, H264 codec and reject is true, then parse the nal 7560 and get the profile. Based on this, reject the clip playback */ 7561 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 && 7562 m_reject_avc_1080p_mp) { 7563 first_frame = 1; 7564 DEBUG_PRINT_ERROR("Parse nal to get the profile"); 7565 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen, 7566 NALU_TYPE_SPS); 7567 m_profile = h264_parser->get_profile(); 7568 ret = is_video_session_supported(); 7569 if (ret) { 7570 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD); 7571 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT); 7572 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */ 7573 m_state = OMX_StateInvalid; 7574 return OMX_ErrorNone; 7575 } 7576 } 7577 7578 VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000); 7579 VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen); 7580 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 7581 /*for use buffer we need to memcpy the data*/ 7582 temp_buffer->buffer_len = buffer->nFilledLen; 7583 7584 if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) { 7585 if (buffer->nFilledLen <= temp_buffer->buffer_len) { 7586 if (arbitrary_bytes) { 7587 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 7588 } else { 7589 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), 7590 buffer->nFilledLen); 7591 } 7592 } else { 7593 return OMX_ErrorBadParameter; 7594 } 7595 7596 } 7597 7598 frameinfo.bufferaddr = temp_buffer->bufferaddr; 7599 frameinfo.client_data = (void *) buffer; 7600 frameinfo.datalen = temp_buffer->buffer_len; 7601 frameinfo.flags = 0; 7602 frameinfo.offset = buffer->nOffset; 7603 frameinfo.pmem_fd = temp_buffer->pmem_fd; 7604 frameinfo.pmem_offset = temp_buffer->offset; 7605 frameinfo.timestamp = buffer->nTimeStamp; 7606 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) { 7607 DEBUG_PRINT_LOW("ETB: dmx enabled"); 7608 if (m_demux_entries == 0) { 7609 extract_demux_addr_offsets(buffer); 7610 } 7611 7612 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries); 7613 handle_demux_data(buffer); 7614 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; 7615 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; 7616 } else { 7617 frameinfo.desc_addr = NULL; 7618 frameinfo.desc_size = 0; 7619 } 7620 if (!arbitrary_bytes) { 7621 frameinfo.flags |= buffer->nFlags; 7622 } 7623 7624#ifdef _ANDROID_ 7625 if (m_debug_timestamp) { 7626 if (arbitrary_bytes) { 7627 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7628 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7629 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7630 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 7631 m_timestamp_list.insert_ts(buffer->nTimeStamp); 7632 } 7633 } 7634#endif 7635 7636 log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len); 7637 7638if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 7639 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7640 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7641 } 7642 7643 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7644 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); 7645 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 7646 h264_scratch.nFilledLen = 0; 7647 nal_count = 0; 7648 look_ahead_nal = false; 7649 frame_count = 0; 7650 if (m_frame_parser.mutils) 7651 m_frame_parser.mutils->initialize_frame_checking_environment(); 7652 m_frame_parser.flush(); 7653 h264_last_au_ts = LLONG_MAX; 7654 h264_last_au_flags = 0; 7655 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 7656 m_demux_entries = 0; 7657 } 7658 struct v4l2_buffer buf; 7659 struct v4l2_plane plane; 7660 memset( (void *)&buf, 0, sizeof(buf)); 7661 memset( (void *)&plane, 0, sizeof(plane)); 7662 int rc; 7663 unsigned long print_count; 7664 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 7665 buf.flags = V4L2_QCOM_BUF_FLAG_EOS; 7666 DEBUG_PRINT_HIGH("INPUT EOS reached") ; 7667 } 7668 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7669 buf.index = nPortIndex; 7670 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7671 buf.memory = V4L2_MEMORY_USERPTR; 7672 plane.bytesused = temp_buffer->buffer_len; 7673 plane.length = drv_ctx.ip_buf.buffer_size; 7674 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - 7675 (unsigned long)temp_buffer->offset; 7676 plane.reserved[0] = temp_buffer->pmem_fd; 7677 plane.reserved[1] = temp_buffer->offset; 7678 plane.data_offset = 0; 7679 buf.m.planes = &plane; 7680 buf.length = 1; 7681 if (frameinfo.timestamp >= LLONG_MAX) { 7682 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; 7683 } 7684 //assumption is that timestamp is in milliseconds 7685 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; 7686 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); 7687 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; 7688 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0; 7689 7690 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 7691 DEBUG_PRINT_LOW("Increment codec_config buffer counter"); 7692 android_atomic_inc(&m_queued_codec_config_count); 7693 } 7694 7695 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 7696 if (rc) { 7697 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client"); 7698 m_cb.EmptyBufferDone(hComp, m_app_data, buffer); 7699 return OMX_ErrorHardware; 7700 } 7701 7702 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 7703 codec_config_flag = false; 7704 } 7705 if (!streaming[OUTPUT_PORT]) { 7706 enum v4l2_buf_type buf_type; 7707 int ret,r; 7708 7709 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7710 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 7711 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 7712 if (!ret) { 7713 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful"); 7714 streaming[OUTPUT_PORT] = true; 7715 } else if (errno == EBUSY) { 7716 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD"); 7717 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7718 OMX_COMPONENT_GENERATE_EBD); 7719 return OMX_ErrorInsufficientResources; 7720 } else { 7721 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT"); 7722 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); 7723 post_event ((unsigned long)buffer, VDEC_S_SUCCESS, 7724 OMX_COMPONENT_GENERATE_EBD); 7725 return OMX_ErrorBadParameter; 7726 } 7727 } 7728 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)", 7729 frameinfo.bufferaddr, (long long)frameinfo.timestamp, 7730 (unsigned int)frameinfo.datalen); 7731 7732 return ret; 7733} 7734 7735/* ====================================================================== 7736 FUNCTION 7737 omx_vdec::FillThisBuffer 7738 7739 DESCRIPTION 7740 IL client uses this method to release the frame buffer 7741 after displaying them. 7742 7743 PARAMETERS 7744 None. 7745 7746 RETURN VALUE 7747 true/false 7748 7749 ========================================================================== */ 7750OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 7751 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 7752{ 7753 if (m_state != OMX_StateExecuting && 7754 m_state != OMX_StatePause && 7755 m_state != OMX_StateIdle) { 7756 DEBUG_PRINT_ERROR("FTB in Invalid State"); 7757 return OMX_ErrorInvalidState; 7758 } 7759 7760 if (!m_out_bEnabled) { 7761 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); 7762 return OMX_ErrorIncorrectStateOperation; 7763 } 7764 7765 unsigned nPortIndex = 0; 7766 if (dynamic_buf_mode) { 7767 private_handle_t *handle = NULL; 7768 struct VideoDecoderOutputMetaData *meta; 7769 unsigned int nPortIndex = 0; 7770 7771 if (!buffer || !buffer->pBuffer) { 7772 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer); 7773 return OMX_ErrorBadParameter; 7774 } 7775 7776 //get the buffer type and fd info 7777 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer; 7778 handle = (private_handle_t *)meta->pHandle; 7779 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle); 7780 7781 if (!handle) { 7782 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle); 7783 return OMX_ErrorBadParameter; 7784 } 7785 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF 7786 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 7787 if (nPortIndex < drv_ctx.op_buf.actualcount && 7788 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 7789 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd; 7790 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer; 7791 7792 //Store private handle from GraphicBuffer 7793 native_buffer[nPortIndex].privatehandle = handle; 7794 native_buffer[nPortIndex].nativehandle = handle; 7795 } else { 7796 DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex); 7797 return OMX_ErrorBadParameter; 7798 } 7799 7800 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite 7801 //this with a more sane size so that we don't compensate in rest of code 7802 //We'll restore this size later on, so that it's transparent to client 7803 buffer->nFilledLen = 0; 7804 buffer->nAllocLen = handle->size; 7805 7806 if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) { 7807 m_is_display_session = true; 7808 } else { 7809 m_is_display_session = false; 7810 } 7811 DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session); 7812 7813 drv_ctx.op_buf.buffer_size = handle->size; 7814 } 7815 7816 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 7817 if (buffer == NULL || 7818 (nPortIndex >= drv_ctx.op_buf.actualcount)) { 7819 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 7820 nPortIndex, drv_ctx.op_buf.actualcount); 7821 return OMX_ErrorBadParameter; 7822 } 7823 7824 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 7825 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex); 7826 return OMX_ErrorBadPortIndex; 7827 } 7828 7829 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 7830 post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg); 7831 return OMX_ErrorNone; 7832} 7833/* ====================================================================== 7834 FUNCTION 7835 omx_vdec::fill_this_buffer_proxy 7836 7837 DESCRIPTION 7838 IL client uses this method to release the frame buffer 7839 after displaying them. 7840 7841 PARAMETERS 7842 None. 7843 7844 RETURN VALUE 7845 true/false 7846 7847 ========================================================================== */ 7848OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 7849 OMX_IN OMX_HANDLETYPE hComp, 7850 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 7851{ 7852 VIDC_TRACE_NAME_HIGH("FTB"); 7853 OMX_ERRORTYPE nRet = OMX_ErrorNone; 7854 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 7855 unsigned nPortIndex = 0; 7856 struct vdec_fillbuffer_cmd fillbuffer; 7857 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 7858 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 7859 7860 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 7861 7862 if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) { 7863 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 7864 nPortIndex, drv_ctx.op_buf.actualcount); 7865 return OMX_ErrorBadParameter; 7866 } 7867 7868 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 7869 bufferAdd, bufferAdd->pBuffer); 7870 /*Return back the output buffer to client*/ 7871 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) { 7872 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); 7873 buffer->nFilledLen = 0; 7874 m_cb.FillBufferDone (hComp,m_app_data,buffer); 7875 return OMX_ErrorNone; 7876 } 7877 7878 if (dynamic_buf_mode) { 7879 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0; 7880 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen; 7881 buf_ref_add(nPortIndex); 7882 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen; 7883 } 7884 7885 pending_output_buffers++; 7886 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 7887 buffer = client_buffers.get_dr_buf_hdr(bufferAdd); 7888 if (!buffer) { 7889 DEBUG_PRINT_ERROR("err: client_buffer ptr invalid"); 7890 return OMX_ErrorBadParameter; 7891 } 7892 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 7893 if (ptr_respbuffer) { 7894 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 7895 } 7896 7897 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) { 7898 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); 7899 buffer->nFilledLen = 0; 7900 m_cb.FillBufferDone (hComp,m_app_data,buffer); 7901 pending_output_buffers--; 7902 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 7903 return OMX_ErrorBadParameter; 7904 } 7905 7906 int rc = 0; 7907 struct v4l2_buffer buf; 7908 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 7909 memset( (void *)&buf, 0, sizeof(buf)); 7910 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); 7911 unsigned int extra_idx = 0; 7912 7913 buf.index = nPortIndex; 7914 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7915 buf.memory = V4L2_MEMORY_USERPTR; 7916 plane[0].bytesused = buffer->nFilledLen; 7917 plane[0].length = buffer->nAllocLen; 7918 plane[0].m.userptr = 7919 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - 7920 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; 7921 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 7922 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 7923 plane[0].data_offset = 0; 7924 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 7925 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 7926 plane[extra_idx].bytesused = 0; 7927 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 7928 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); 7929#ifdef USE_ION 7930 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 7931#endif 7932 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; 7933 plane[extra_idx].data_offset = 0; 7934 } else if (extra_idx >= VIDEO_MAX_PLANES) { 7935 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx); 7936 return OMX_ErrorBadParameter; 7937 } 7938 buf.m.planes = plane; 7939 buf.length = drv_ctx.num_planes; 7940 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d", 7941 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress); 7942 7943 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 7944 if (rc) { 7945 buffer->nFilledLen = 0; 7946 DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno)); 7947 m_cb.FillBufferDone(hComp, m_app_data, buffer); 7948 return OMX_ErrorHardware; 7949 } 7950 7951 return OMX_ErrorNone; 7952} 7953 7954/* ====================================================================== 7955 FUNCTION 7956 omx_vdec::SetCallbacks 7957 7958 DESCRIPTION 7959 Set the callbacks. 7960 7961 PARAMETERS 7962 None. 7963 7964 RETURN VALUE 7965 OMX Error None if everything successful. 7966 7967 ========================================================================== */ 7968OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 7969 OMX_IN OMX_CALLBACKTYPE* callbacks, 7970 OMX_IN OMX_PTR appData) 7971{ 7972 (void) hComp; 7973 m_cb = *callbacks; 7974 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 7975 m_cb.EventHandler,m_cb.FillBufferDone); 7976 m_app_data = appData; 7977 return OMX_ErrorNotImplemented; 7978} 7979 7980/* ====================================================================== 7981 FUNCTION 7982 omx_vdec::ComponentDeInit 7983 7984 DESCRIPTION 7985 Destroys the component and release memory allocated to the heap. 7986 7987 PARAMETERS 7988 <TBD>. 7989 7990 RETURN VALUE 7991 OMX Error None if everything successful. 7992 7993 ========================================================================== */ 7994OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 7995{ 7996 (void) hComp; 7997 7998 unsigned i = 0; 7999 if (OMX_StateLoaded != m_state) { 8000 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\ 8001 m_state); 8002 DEBUG_PRINT_ERROR("Playback Ended - FAILED"); 8003 } else { 8004 DEBUG_PRINT_HIGH("Playback Ended - PASSED"); 8005 } 8006 8007 /*Check if the output buffers have to be cleaned up*/ 8008 if (m_out_mem_ptr) { 8009 DEBUG_PRINT_LOW("Freeing the Output Memory"); 8010 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) { 8011 if (BITMASK_PRESENT(&m_out_bm_count, i)) { 8012 BITMASK_CLEAR(&m_out_bm_count, i); 8013 client_buffers.free_output_buffer (&m_out_mem_ptr[i]); 8014 } 8015 8016 if (release_output_done()) { 8017 break; 8018 } 8019 } 8020#ifdef _ANDROID_ICS_ 8021 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 8022#endif 8023 } 8024 8025 /*Check if the input buffers have to be cleaned up*/ 8026 if (m_inp_mem_ptr || m_inp_heap_ptr) { 8027 DEBUG_PRINT_LOW("Freeing the Input Memory"); 8028 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) { 8029 8030 if (BITMASK_PRESENT(&m_inp_bm_count, i)) { 8031 BITMASK_CLEAR(&m_inp_bm_count, i); 8032 if (m_inp_mem_ptr) 8033 free_input_buffer (i,&m_inp_mem_ptr[i]); 8034 else 8035 free_input_buffer (i,NULL); 8036 } 8037 8038 if (release_input_done()) { 8039 break; 8040 } 8041 } 8042 } 8043 free_input_buffer_header(); 8044 free_output_buffer_header(); 8045 if (h264_scratch.pBuffer) { 8046 free(h264_scratch.pBuffer); 8047 h264_scratch.pBuffer = NULL; 8048 } 8049 8050 if (h264_parser) { 8051 delete h264_parser; 8052 h264_parser = NULL; 8053 } 8054 8055 if (m_frame_parser.mutils) { 8056 DEBUG_PRINT_LOW("Free utils parser"); 8057 delete (m_frame_parser.mutils); 8058 m_frame_parser.mutils = NULL; 8059 } 8060 8061 if (m_platform_list) { 8062 free(m_platform_list); 8063 m_platform_list = NULL; 8064 } 8065 if (m_vendor_config.pData) { 8066 free(m_vendor_config.pData); 8067 m_vendor_config.pData = NULL; 8068 } 8069 8070 // Reset counters in mesg queues 8071 m_ftb_q.m_size=0; 8072 m_cmd_q.m_size=0; 8073 m_etb_q.m_size=0; 8074 m_ftb_q.m_read = m_ftb_q.m_write =0; 8075 m_cmd_q.m_read = m_cmd_q.m_write =0; 8076 m_etb_q.m_read = m_etb_q.m_write =0; 8077#ifdef _ANDROID_ 8078 if (m_debug_timestamp) { 8079 m_timestamp_list.reset_ts_list(); 8080 } 8081#endif 8082 8083 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG"); 8084 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 8085 // NULL); 8086 DEBUG_PRINT_HIGH("Close the driver instance"); 8087 8088 if (m_debug.infile) { 8089 fclose(m_debug.infile); 8090 m_debug.infile = NULL; 8091 } 8092 if (m_debug.outfile) { 8093 fclose(m_debug.outfile); 8094 m_debug.outfile = NULL; 8095 } 8096 if (m_debug.out_ymeta_file) { 8097 fclose(m_debug.out_ymeta_file); 8098 m_debug.out_ymeta_file = NULL; 8099 } 8100 if (m_debug.out_uvmeta_file) { 8101 fclose(m_debug.out_uvmeta_file); 8102 m_debug.out_uvmeta_file = NULL; 8103 } 8104#ifdef OUTPUT_EXTRADATA_LOG 8105 if (outputExtradataFile) 8106 fclose (outputExtradataFile); 8107#endif 8108 DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete"); 8109 return OMX_ErrorNone; 8110} 8111 8112/* ====================================================================== 8113 FUNCTION 8114 omx_vdec::UseEGLImage 8115 8116 DESCRIPTION 8117 OMX Use EGL Image method implementation <TBD>. 8118 8119 PARAMETERS 8120 <TBD>. 8121 8122 RETURN VALUE 8123 Not Implemented error. 8124 8125 ========================================================================== */ 8126OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 8127 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 8128 OMX_IN OMX_U32 port, 8129 OMX_IN OMX_PTR appData, 8130 OMX_IN void* eglImage) 8131{ 8132 (void) appData; 8133 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; 8134 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; 8135 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; 8136 8137#ifdef USE_EGL_IMAGE_GPU 8138 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; 8139 EGLint fd = -1, offset = 0,pmemPtr = 0; 8140#else 8141 int fd = -1, offset = 0; 8142#endif 8143 DEBUG_PRINT_HIGH("use EGL image support for decoder"); 8144 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { 8145 DEBUG_PRINT_ERROR("Invalid EGL image"); 8146 } 8147#ifdef USE_EGL_IMAGE_GPU 8148 if (m_display_id == NULL) { 8149 DEBUG_PRINT_ERROR("Display ID is not set by IL client"); 8150 return OMX_ErrorInsufficientResources; 8151 } 8152 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) 8153 eglGetProcAddress("eglQueryImageKHR"); 8154 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd); 8155 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset); 8156 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr); 8157#else //with OMX test app 8158 struct temp_egl { 8159 int pmem_fd; 8160 int offset; 8161 }; 8162 struct temp_egl *temp_egl_id = NULL; 8163 void * pmemPtr = (void *) eglImage; 8164 temp_egl_id = (struct temp_egl *)eglImage; 8165 if (temp_egl_id != NULL) { 8166 fd = temp_egl_id->pmem_fd; 8167 offset = temp_egl_id->offset; 8168 } 8169#endif 8170 if (fd < 0) { 8171 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd); 8172 return OMX_ErrorInsufficientResources; 8173 } 8174 pmem_info.pmem_fd = (OMX_U32) fd; 8175 pmem_info.offset = (OMX_U32) offset; 8176 pmem_entry.entry = (void *) &pmem_info; 8177 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 8178 pmem_list.entryList = &pmem_entry; 8179 pmem_list.nEntries = 1; 8180 ouput_egl_buffers = true; 8181 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, 8182 (void *)&pmem_list, drv_ctx.op_buf.buffer_size, 8183 (OMX_U8 *)pmemPtr)) { 8184 DEBUG_PRINT_ERROR("use buffer call failed for egl image"); 8185 return OMX_ErrorInsufficientResources; 8186 } 8187 return OMX_ErrorNone; 8188} 8189 8190/* ====================================================================== 8191 FUNCTION 8192 omx_vdec::ComponentRoleEnum 8193 8194 DESCRIPTION 8195 OMX Component Role Enum method implementation. 8196 8197 PARAMETERS 8198 <TBD>. 8199 8200 RETURN VALUE 8201 OMX Error None if everything is successful. 8202 ========================================================================== */ 8203OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 8204 OMX_OUT OMX_U8* role, 8205 OMX_IN OMX_U32 index) 8206{ 8207 (void) hComp; 8208 OMX_ERRORTYPE eRet = OMX_ErrorNone; 8209 8210 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 8211 if ((0 == index) && role) { 8212 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 8213 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8214 } else { 8215 eRet = OMX_ErrorNoMore; 8216 } 8217 } 8218 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 8219 if ((0 == index) && role) { 8220 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 8221 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8222 } else { 8223 eRet = OMX_ErrorNoMore; 8224 } 8225 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 8226 if ((0 == index) && role) { 8227 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 8228 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8229 } else { 8230 DEBUG_PRINT_LOW("No more roles"); 8231 eRet = OMX_ErrorNoMore; 8232 } 8233 } 8234 8235 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 8236 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) { 8237 if ((0 == index) && role) { 8238 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 8239 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8240 } else { 8241 DEBUG_PRINT_LOW("No more roles"); 8242 eRet = OMX_ErrorNoMore; 8243 } 8244 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 8245 if ((0 == index) && role) { 8246 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 8247 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8248 } else { 8249 DEBUG_PRINT_LOW("No more roles"); 8250 eRet = OMX_ErrorNoMore; 8251 } 8252 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) { 8253 if ((0 == index) && role) { 8254 strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE); 8255 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8256 } else { 8257 DEBUG_PRINT_LOW("No more roles"); 8258 eRet = OMX_ErrorNoMore; 8259 } 8260 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 8261 if ((0 == index) && role) { 8262 strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE); 8263 DEBUG_PRINT_LOW("component_role_enum: role %s", role); 8264 } else { 8265 DEBUG_PRINT_LOW("No more roles"); 8266 eRet = OMX_ErrorNoMore; 8267 } 8268 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 8269 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 8270 ) { 8271 if ((0 == index) && role) { 8272 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 8273 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8274 } else { 8275 DEBUG_PRINT_LOW("No more roles"); 8276 eRet = OMX_ErrorNoMore; 8277 } 8278 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 8279 if ((0 == index) && role) { 8280 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 8281 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8282 } else { 8283 DEBUG_PRINT_LOW("No more roles"); 8284 eRet = OMX_ErrorNoMore; 8285 } 8286 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) { 8287 if ((0 == index) && role) { 8288 strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE); 8289 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 8290 } else { 8291 DEBUG_PRINT_LOW("No more roles"); 8292 eRet = OMX_ErrorNoMore; 8293 } 8294 } else { 8295 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component"); 8296 eRet = OMX_ErrorInvalidComponentName; 8297 } 8298 return eRet; 8299} 8300 8301 8302 8303 8304/* ====================================================================== 8305 FUNCTION 8306 omx_vdec::AllocateDone 8307 8308 DESCRIPTION 8309 Checks if entire buffer pool is allocated by IL Client or not. 8310 Need this to move to IDLE state. 8311 8312 PARAMETERS 8313 None. 8314 8315 RETURN VALUE 8316 true/false. 8317 8318 ========================================================================== */ 8319bool omx_vdec::allocate_done(void) 8320{ 8321 bool bRet = false; 8322 bool bRet_In = false; 8323 bool bRet_Out = false; 8324 8325 bRet_In = allocate_input_done(); 8326 bRet_Out = allocate_output_done(); 8327 8328 if (bRet_In && bRet_Out) { 8329 bRet = true; 8330 } 8331 8332 return bRet; 8333} 8334/* ====================================================================== 8335 FUNCTION 8336 omx_vdec::AllocateInputDone 8337 8338 DESCRIPTION 8339 Checks if I/P buffer pool is allocated by IL Client or not. 8340 8341 PARAMETERS 8342 None. 8343 8344 RETURN VALUE 8345 true/false. 8346 8347 ========================================================================== */ 8348bool omx_vdec::allocate_input_done(void) 8349{ 8350 bool bRet = false; 8351 unsigned i=0; 8352 8353 if (m_inp_mem_ptr == NULL) { 8354 return bRet; 8355 } 8356 if (m_inp_mem_ptr ) { 8357 for (; i<drv_ctx.ip_buf.actualcount; i++) { 8358 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 8359 break; 8360 } 8361 } 8362 } 8363 if (i == drv_ctx.ip_buf.actualcount) { 8364 bRet = true; 8365 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers"); 8366 } 8367 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) { 8368 m_inp_bPopulated = OMX_TRUE; 8369 } 8370 return bRet; 8371} 8372/* ====================================================================== 8373 FUNCTION 8374 omx_vdec::AllocateOutputDone 8375 8376 DESCRIPTION 8377 Checks if entire O/P buffer pool is allocated by IL Client or not. 8378 8379 PARAMETERS 8380 None. 8381 8382 RETURN VALUE 8383 true/false. 8384 8385 ========================================================================== */ 8386bool omx_vdec::allocate_output_done(void) 8387{ 8388 bool bRet = false; 8389 unsigned j=0; 8390 8391 if (m_out_mem_ptr == NULL) { 8392 return bRet; 8393 } 8394 8395 if (m_out_mem_ptr) { 8396 for (; j < drv_ctx.op_buf.actualcount; j++) { 8397 if (BITMASK_ABSENT(&m_out_bm_count,j)) { 8398 break; 8399 } 8400 } 8401 } 8402 8403 if (j == drv_ctx.op_buf.actualcount) { 8404 bRet = true; 8405 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers"); 8406 if (m_out_bEnabled) 8407 m_out_bPopulated = OMX_TRUE; 8408 } 8409 8410 return bRet; 8411} 8412 8413/* ====================================================================== 8414 FUNCTION 8415 omx_vdec::ReleaseDone 8416 8417 DESCRIPTION 8418 Checks if IL client has released all the buffers. 8419 8420 PARAMETERS 8421 None. 8422 8423 RETURN VALUE 8424 true/false 8425 8426 ========================================================================== */ 8427bool omx_vdec::release_done(void) 8428{ 8429 bool bRet = false; 8430 8431 if (release_input_done()) { 8432 if (release_output_done()) { 8433 bRet = true; 8434 } 8435 } 8436 return bRet; 8437} 8438 8439 8440/* ====================================================================== 8441 FUNCTION 8442 omx_vdec::ReleaseOutputDone 8443 8444 DESCRIPTION 8445 Checks if IL client has released all the buffers. 8446 8447 PARAMETERS 8448 None. 8449 8450 RETURN VALUE 8451 true/false 8452 8453 ========================================================================== */ 8454bool omx_vdec::release_output_done(void) 8455{ 8456 bool bRet = false; 8457 unsigned i=0,j=0; 8458 8459 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr); 8460 if (m_out_mem_ptr) { 8461 for (; j < drv_ctx.op_buf.actualcount ; j++) { 8462 if (BITMASK_PRESENT(&m_out_bm_count,j)) { 8463 break; 8464 } 8465 } 8466 if (j == drv_ctx.op_buf.actualcount) { 8467 m_out_bm_count = 0; 8468 bRet = true; 8469 } 8470 } else { 8471 m_out_bm_count = 0; 8472 bRet = true; 8473 } 8474 return bRet; 8475} 8476/* ====================================================================== 8477 FUNCTION 8478 omx_vdec::ReleaseInputDone 8479 8480 DESCRIPTION 8481 Checks if IL client has released all the buffers. 8482 8483 PARAMETERS 8484 None. 8485 8486 RETURN VALUE 8487 true/false 8488 8489 ========================================================================== */ 8490bool omx_vdec::release_input_done(void) 8491{ 8492 bool bRet = false; 8493 unsigned i=0,j=0; 8494 8495 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 8496 if (m_inp_mem_ptr) { 8497 for (; j<drv_ctx.ip_buf.actualcount; j++) { 8498 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) { 8499 break; 8500 } 8501 } 8502 if (j==drv_ctx.ip_buf.actualcount) { 8503 bRet = true; 8504 } 8505 } else { 8506 bRet = true; 8507 } 8508 return bRet; 8509} 8510 8511OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 8512 OMX_BUFFERHEADERTYPE * buffer) 8513{ 8514 VIDC_TRACE_NAME_HIGH("FBD"); 8515 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 8516 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) { 8517 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer); 8518 return OMX_ErrorBadParameter; 8519 } else if (output_flush_progress) { 8520 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); 8521 buffer->nFilledLen = 0; 8522 buffer->nTimeStamp = 0; 8523 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 8524 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 8525 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; 8526 } 8527 8528 if (m_debug_extradata) { 8529 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 8530 DEBUG_PRINT_HIGH("***************************************************"); 8531 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received"); 8532 DEBUG_PRINT_HIGH("***************************************************"); 8533 } 8534 8535 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) { 8536 DEBUG_PRINT_HIGH("***************************************************"); 8537 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 8538 DEBUG_PRINT_HIGH("***************************************************"); 8539 } 8540 } 8541 8542 8543 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld", 8544 buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp); 8545 pending_output_buffers --; 8546 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers); 8547 8548 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8549 DEBUG_PRINT_HIGH("Output EOS has been reached"); 8550 if (!output_flush_progress) 8551 post_event((unsigned)NULL, (unsigned)NULL, 8552 OMX_COMPONENT_GENERATE_EOS_DONE); 8553 8554 if (psource_frame) { 8555 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); 8556 psource_frame = NULL; 8557 } 8558 if (pdest_frame) { 8559 pdest_frame->nFilledLen = 0; 8560 m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL, 8561 (unsigned)NULL); 8562 pdest_frame = NULL; 8563 } 8564 } 8565 8566#ifdef OUTPUT_EXTRADATA_LOG 8567 if (outputExtradataFile) { 8568 int buf_index = buffer - m_out_mem_ptr; 8569 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr); 8570 8571 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 8572 p_extra = (OMX_OTHER_EXTRADATATYPE *) 8573 ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3)); 8574 8575 while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) { 8576 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x", 8577 p_extra->nSize, p_extra->eType); 8578 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); 8579 8580 if (p_extra->eType == OMX_ExtraDataNone) { 8581 break; 8582 } 8583 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8584 } 8585 } 8586#endif 8587 8588 /* For use buffer we need to copy the data */ 8589 if (!output_flush_progress) { 8590 /* This is the error check for non-recoverable errros */ 8591 bool is_duplicate_ts_valid = true; 8592 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive); 8593 8594 if (output_capability == V4L2_PIX_FMT_MPEG4 || 8595 output_capability == V4L2_PIX_FMT_MPEG2 || 8596 output_capability == V4L2_PIX_FMT_DIVX || 8597 output_capability == V4L2_PIX_FMT_DIVX_311) 8598 is_duplicate_ts_valid = false; 8599 8600 if ((output_capability == V4L2_PIX_FMT_H264 || 8601 output_capability == V4L2_PIX_FMT_H264_MVC) && 8602 is_interlaced) { 8603 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) { 8604 is_interlaced = false; 8605 } 8606 } 8607 8608 if (buffer->nFilledLen > 0) { 8609 time_stamp_dts.get_next_timestamp(buffer, 8610 is_interlaced && is_duplicate_ts_valid); 8611 if (m_debug_timestamp) { 8612 { 8613 OMX_TICKS expected_ts = 0; 8614 m_timestamp_list.pop_min_ts(expected_ts); 8615 if (is_interlaced && is_duplicate_ts_valid) { 8616 m_timestamp_list.pop_min_ts(expected_ts); 8617 } 8618 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", 8619 buffer->nTimeStamp, expected_ts); 8620 8621 if (buffer->nTimeStamp != expected_ts) { 8622 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check"); 8623 } 8624 } 8625 } 8626 } 8627 } 8628 VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000); 8629 8630 if (m_cb.FillBufferDone) { 8631 if (buffer->nFilledLen > 0) { 8632 if (arbitrary_bytes) 8633 adjust_timestamp(buffer->nTimeStamp); 8634 else 8635 set_frame_rate(buffer->nTimeStamp); 8636 8637 proc_frms++; 8638 if (perf_flag) { 8639 if (1 == proc_frms) { 8640 dec_time.stop(); 8641 latency = dec_time.processing_time_us() - latency; 8642 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); 8643 dec_time.start(); 8644 fps_metrics.start(); 8645 } 8646 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8647 OMX_U64 proc_time = 0; 8648 fps_metrics.stop(); 8649 proc_time = fps_metrics.processing_time_us(); 8650 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)", 8651 (unsigned int)proc_frms, (float)proc_time / 1e6, 8652 (float)(1e6 * proc_frms) / proc_time); 8653 } 8654 } 8655 } 8656 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 8657 prev_ts = LLONG_MAX; 8658 rst_prev_ts = true; 8659 proc_frms = 0; 8660 } 8661 8662 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 8663 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 8664 buffer->pPlatformPrivate)->entryList->entry; 8665 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd); 8666 OMX_BUFFERHEADERTYPE *il_buffer; 8667 il_buffer = client_buffers.get_il_buf_hdr(buffer); 8668 OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator); 8669 8670 if (il_buffer && m_last_rendered_TS >= 0) { 8671 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS); 8672 8673 // Current frame can be send for rendering if 8674 // (a) current FPS is <= 60 8675 // (b) is the next frame after the frame with TS 0 8676 // (c) is the first frame after seek 8677 // (d) the delta TS b\w two consecutive frames is > 16 ms 8678 // (e) its TS is equal to previous frame TS 8679 // (f) if marked EOS 8680 8681 if(current_framerate <= 60 || m_last_rendered_TS == 0 || 8682 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 || 8683 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 8684 m_last_rendered_TS = il_buffer->nTimeStamp; 8685 } else { 8686 //mark for droping 8687 buffer->nFilledLen = 0; 8688 } 8689 8690 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)", 8691 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS, 8692 il_buffer->nTimeStamp,ts_delta); 8693 8694 //above code makes sure that delta b\w two consecutive frames is not 8695 //greater than 16ms, slow-mo feature, so cap fps to max 60 8696 if (current_framerate > 60 ) { 8697 current_framerate = 60; 8698 } 8699 } 8700 8701 // add current framerate to gralloc meta data 8702 if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && m_out_mem_ptr) { 8703 // If valid fps was received, directly send it to display for the 1st fbd. 8704 // Otherwise, calculate fps using fbd timestamps 8705 float refresh_rate = m_fps_prev; 8706 if (m_fps_received) { 8707 if (1 == proc_frms) { 8708 refresh_rate = m_fps_received / (float)(1<<16); 8709 } 8710 } else { 8711 // check if dynamic refresh rate change feature enabled or not 8712 if (m_drc_enable) { 8713 // set coarse fps when 2 fbds received and 8714 // set fps again when 30 fbds received as it should be 8715 // more accurate than the one set when only 2 fbds received. 8716 if (2 == proc_frms || 30 == proc_frms) { 8717 if (drv_ctx.frame_rate.fps_denominator) { 8718 refresh_rate = drv_ctx.frame_rate.fps_numerator / 8719 (float) drv_ctx.frame_rate.fps_denominator; 8720 } 8721 } 8722 } else { 8723 // calculate and set refresh rate for every frame from second frame onwards 8724 // display will assume the default refresh rate for first frame (which is 60 fps) 8725 if (m_fps_prev) { 8726 if (drv_ctx.frame_rate.fps_denominator) { 8727 refresh_rate = drv_ctx.frame_rate.fps_numerator / 8728 (float) drv_ctx.frame_rate.fps_denominator; 8729 } 8730 } 8731 } 8732 } 8733 if (refresh_rate > 60) { 8734 refresh_rate = 60; 8735 } 8736 DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms); 8737 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8738 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 8739 UPDATE_REFRESH_RATE, (void*)&refresh_rate); 8740 m_fps_prev = refresh_rate; 8741 } 8742 8743 if (buffer->nFilledLen && m_enable_android_native_buffers && m_out_mem_ptr) { 8744 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8745 DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode); 8746 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 8747 S3D_FORMAT, (void*)&stereo_output_mode); 8748 } 8749 8750 if (il_buffer) { 8751 log_output_buffers(il_buffer); 8752 if (dynamic_buf_mode) { 8753 unsigned int nPortIndex = 0; 8754 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 8755 8756 // Since we're passing around handles, adjust nFilledLen and nAllocLen 8757 // to size of the handle. Do it _after_ log_output_buffers which 8758 // requires the respective sizes to be accurate. 8759 8760 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); 8761 buffer->nFilledLen = buffer->nFilledLen ? 8762 sizeof(struct VideoDecoderOutputMetaData) : 0; 8763 8764 //Clear graphic buffer handles in dynamic mode 8765 if (nPortIndex < drv_ctx.op_buf.actualcount && 8766 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) { 8767 native_buffer[nPortIndex].privatehandle = NULL; 8768 native_buffer[nPortIndex].nativehandle = NULL; 8769 } else { 8770 DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex); 8771 return OMX_ErrorBadParameter; 8772 } 8773 } 8774 m_cb.FillBufferDone (hComp,m_app_data,il_buffer); 8775 } else { 8776 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); 8777 return OMX_ErrorBadParameter; 8778 } 8779 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd); 8780 } else { 8781 return OMX_ErrorBadParameter; 8782 } 8783 8784#ifdef ADAPTIVE_PLAYBACK_SUPPORTED 8785 if (m_smoothstreaming_mode && m_out_mem_ptr) { 8786 OMX_U32 buf_index = buffer - m_out_mem_ptr; 8787 BufferDim_t dim; 8788 private_handle_t *private_handle = NULL; 8789 dim.sliceWidth = framesize.nWidth; 8790 dim.sliceHeight = framesize.nHeight; 8791 if (buf_index < drv_ctx.op_buf.actualcount && 8792 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 8793 native_buffer[buf_index].privatehandle) 8794 private_handle = native_buffer[buf_index].privatehandle; 8795 if (private_handle) { 8796 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d", 8797 dim.sliceWidth, dim.sliceHeight); 8798 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim); 8799 } 8800 } 8801#endif 8802 8803 return OMX_ErrorNone; 8804} 8805 8806OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 8807 OMX_BUFFERHEADERTYPE* buffer) 8808{ 8809 VIDC_TRACE_NAME_HIGH("EBD"); 8810 int nBufferIndex = buffer - m_inp_mem_ptr; 8811 8812 if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) { 8813 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer); 8814 return OMX_ErrorBadParameter; 8815 } 8816 8817 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x", 8818 buffer, buffer->pBuffer, buffer->nFlags); 8819 pending_input_buffers--; 8820 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 8821 8822 if (arbitrary_bytes) { 8823 if (pdest_frame == NULL && input_flush_progress == false) { 8824 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); 8825 pdest_frame = buffer; 8826 buffer->nFilledLen = 0; 8827 buffer->nTimeStamp = LLONG_MAX; 8828 push_input_buffer (hComp); 8829 } else { 8830 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); 8831 buffer->nFilledLen = 0; 8832 if (!m_input_free_q.insert_entry((unsigned long)buffer, 8833 (unsigned)NULL, (unsigned)NULL)) { 8834 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error"); 8835 } 8836 } 8837 } else if (m_cb.EmptyBufferDone) { 8838 buffer->nFilledLen = 0; 8839 if (input_use_buffer == true) { 8840 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; 8841 } 8842 8843 /* Restore the FD that we over-wrote in ETB */ 8844 if (m_input_pass_buffer_fd) { 8845 buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd; 8846 } 8847 8848 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 8849 } 8850 return OMX_ErrorNone; 8851} 8852 8853int omx_vdec::async_message_process (void *context, void* message) 8854{ 8855 omx_vdec* omx = NULL; 8856 struct vdec_msginfo *vdec_msg = NULL; 8857 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 8858 struct v4l2_buffer *v4l2_buf_ptr = NULL; 8859 struct v4l2_plane *plane = NULL; 8860 struct vdec_output_frameinfo *output_respbuf = NULL; 8861 int rc=1; 8862 if (context == NULL || message == NULL) { 8863 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check"); 8864 return -1; 8865 } 8866 vdec_msg = (struct vdec_msginfo *)message; 8867 8868 omx = reinterpret_cast<omx_vdec*>(context); 8869 8870 switch (vdec_msg->msgcode) { 8871 8872 case VDEC_MSG_EVT_HW_ERROR: 8873 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8874 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 8875 break; 8876 8877 case VDEC_MSG_EVT_HW_OVERLOAD: 8878 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8879 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD); 8880 break; 8881 8882 case VDEC_MSG_EVT_HW_UNSUPPORTED: 8883 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8884 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); 8885 break; 8886 8887 case VDEC_MSG_RESP_START_DONE: 8888 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8889 OMX_COMPONENT_GENERATE_START_DONE); 8890 break; 8891 8892 case VDEC_MSG_RESP_STOP_DONE: 8893 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8894 OMX_COMPONENT_GENERATE_STOP_DONE); 8895 break; 8896 8897 case VDEC_MSG_RESP_RESUME_DONE: 8898 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8899 OMX_COMPONENT_GENERATE_RESUME_DONE); 8900 break; 8901 8902 case VDEC_MSG_RESP_PAUSE_DONE: 8903 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8904 OMX_COMPONENT_GENERATE_PAUSE_DONE); 8905 break; 8906 8907 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 8908 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8909 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 8910 break; 8911 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 8912 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8913 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 8914 break; 8915 case VDEC_MSG_RESP_INPUT_FLUSHED: 8916 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 8917 8918 /* omxhdr = (OMX_BUFFERHEADERTYPE* ) 8919 vdec_msg->msgdata.input_frame_clientdata; */ 8920 8921 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; 8922 if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL || 8923 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) { 8924 omxhdr = NULL; 8925 vdec_msg->status_code = VDEC_S_EFATAL; 8926 break; 8927 8928 } 8929 omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index; 8930 8931 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) { 8932 DEBUG_PRINT_HIGH("Unsupported input"); 8933 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 8934 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 8935 } 8936 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 8937 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 8938 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; 8939 } 8940 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 8941 8942 DEBUG_PRINT_LOW("Decrement codec_config buffer counter"); 8943 android_atomic_dec(&omx->m_queued_codec_config_count); 8944 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) && 8945 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) { 8946 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer"); 8947 sem_post(&omx->m_safe_flush); 8948 } 8949 } 8950 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || 8951 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 8952 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 8953 } 8954 omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code, 8955 OMX_COMPONENT_GENERATE_EBD); 8956 break; 8957 case VDEC_MSG_EVT_INFO_FIELD_DROPPED: 8958 int64_t *timestamp; 8959 timestamp = (int64_t *) malloc(sizeof(int64_t)); 8960 if (timestamp) { 8961 *timestamp = vdec_msg->msgdata.output_frame.time_stamp; 8962 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code, 8963 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); 8964 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", 8965 (long long)vdec_msg->msgdata.output_frame.time_stamp); 8966 } 8967 break; 8968 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 8969 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 8970 8971 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; 8972 if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL || 8973 v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) { 8974 omxhdr = NULL; 8975 vdec_msg->status_code = VDEC_S_EFATAL; 8976 break; 8977 } 8978 plane = v4l2_buf_ptr->m.planes; 8979 omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index; 8980 8981 if (omxhdr && omxhdr->pOutputPortPrivate && 8982 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) && 8983 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 8984 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) { 8985 8986 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) { 8987 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 8988 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 8989 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 8990 omxhdr->nFlags = 0; 8991 8992 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) { 8993 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; 8994 //rc = -1; 8995 } 8996 if (omxhdr->nFilledLen) { 8997 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; 8998 } 8999 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { 9000 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 9001 } else { 9002 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; 9003 } 9004 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) { 9005 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 9006 } 9007 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) { 9008 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; 9009 } 9010 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) { 9011 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF; 9012 } 9013 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) { 9014 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY; 9015 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d", 9016 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd); 9017 } 9018 9019 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && 9020 !omx->output_flush_progress && 9021 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && 9022 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) { 9023 omx->time_stamp_dts.remove_time_stamp( 9024 omxhdr->nTimeStamp, 9025 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 9026 ?true:false); 9027 9028 omxhdr->nFilledLen = 0; 9029 omx->pending_output_buffers--; 9030 omx->post_event ((unsigned long)NULL,(unsigned long)omx->client_buffers.get_il_buf_hdr(omxhdr), 9031 OMX_COMPONENT_GENERATE_FTB); 9032 break; 9033 } 9034 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { 9035 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 9036 } 9037 9038 output_respbuf = (struct vdec_output_frameinfo *)\ 9039 omxhdr->pOutputPortPrivate; 9040 if (!output_respbuf) { 9041 DEBUG_PRINT_ERROR("async_message_process: invalid output buf received"); 9042 return -1; 9043 } 9044 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 9045 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 9046 9047 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) { 9048 output_respbuf->pic_type = PICTURE_TYPE_I; 9049 } 9050 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) { 9051 output_respbuf->pic_type = PICTURE_TYPE_P; 9052 } 9053 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { 9054 output_respbuf->pic_type = PICTURE_TYPE_B; 9055 } 9056 9057 if (vdec_msg->msgdata.output_frame.len) { 9058 if (!omx->output_flush_progress && (omxhdr->nFilledLen > 0)) { 9059 // set the default colorspace advised by client, since the bitstream may be 9060 // devoid of colorspace-info. 9061 if (omx->m_enable_android_native_buffers) { 9062 ColorSpace_t color_space = ITU_R_601; 9063 9064 // Disabled ? 9065 // WA for VP8. Vp8 encoder does not embed color-info (yet!). 9066 // Encoding RGBA results in 601-LR for all resolutions. 9067 // This conflicts with the client't defaults which are based on resolution. 9068 // Eg: 720p will be encoded as 601-LR. Client will say 709. 9069 // Re-enable this code once vp8 encoder generates color-info and hence the 9070 // decoder will be able to override with the correct source color. 9071#if 0 9072 switch (omx->m_client_color_space.sAspects.mPrimaries) { 9073 case ColorAspects::PrimariesBT601_6_625: 9074 case ColorAspects::PrimariesBT601_6_525: 9075 { 9076 color_space = omx->m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ? 9077 ITU_R_601_FR : ITU_R_601; 9078 break; 9079 } 9080 case ColorAspects::PrimariesBT709_5: 9081 { 9082 color_space = ITU_R_709; 9083 break; 9084 } 9085 default: 9086 { 9087 break; 9088 } 9089 } 9090#endif 9091 DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)", 9092 color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); 9093 omx->set_colorspace_in_handle(color_space, omxhdr - omx->m_out_mem_ptr); 9094 } 9095 } 9096 9097 DEBUG_PRINT_LOW("Processing extradata"); 9098 omx->handle_extradata(omxhdr); 9099 9100 if (omx->m_extradata_info.output_crop_updated) { 9101 DEBUG_PRINT_LOW("Read FBD crop from output extra data"); 9102 vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft; 9103 vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop; 9104 vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth; 9105 vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight; 9106 vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width; 9107 vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height; 9108 } else { 9109 DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields"); 9110 vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2]; 9111 vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3]; 9112 vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4]; 9113 vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5]; 9114 vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6]; 9115 vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7]; 9116 9117 /* Copy these values back to OMX internal variables to make both handlign same*/ 9118 9119 omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left; 9120 omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top; 9121 omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right; 9122 omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; 9123 omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width; 9124 omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height; 9125 } 9126 } 9127 9128 vdec_msg->msgdata.output_frame.bufferaddr = 9129 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; 9130 9131 if (vdec_msg->msgdata.output_frame.len) 9132 memcpy(&omx->drv_ctx.frame_size, 9133 &vdec_msg->msgdata.output_frame.framesize, 9134 sizeof(struct vdec_framesize)); 9135 9136 DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)" 9137 " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)", 9138 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd, 9139 omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp, 9140 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags, 9141 (unsigned int)vdec_msg->msgdata.output_frame.len, 9142 vdec_msg->msgdata.output_frame.framesize.left, 9143 vdec_msg->msgdata.output_frame.framesize.top, 9144 vdec_msg->msgdata.output_frame.framesize.right, 9145 vdec_msg->msgdata.output_frame.framesize.bottom); 9146 9147 /* Post event if resolution OR crop changed */ 9148 /* filled length will be changed if resolution changed */ 9149 /* Crop parameters can be changed even without resolution change */ 9150 if (omxhdr->nFilledLen 9151 && ((omx->prev_n_filled_len != omxhdr->nFilledLen) 9152 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left) 9153 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top) 9154 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right) 9155 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom) 9156 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width) 9157 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) { 9158 9159 DEBUG_PRINT_HIGH("Parameters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u", 9160 omx->prev_n_filled_len, 9161 omx->drv_ctx.video_resolution.frame_width, 9162 omx->drv_ctx.video_resolution.frame_height, 9163 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top, 9164 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom, 9165 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width, 9166 vdec_msg->msgdata.output_frame.picsize.frame_height, 9167 vdec_msg->msgdata.output_frame.framesize.left, 9168 vdec_msg->msgdata.output_frame.framesize.top, 9169 vdec_msg->msgdata.output_frame.framesize.right, 9170 vdec_msg->msgdata.output_frame.framesize.bottom); 9171 9172 omx->drv_ctx.video_resolution.frame_width = 9173 vdec_msg->msgdata.output_frame.picsize.frame_width; 9174 omx->drv_ctx.video_resolution.frame_height = 9175 vdec_msg->msgdata.output_frame.picsize.frame_height; 9176 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 9177 omx->drv_ctx.video_resolution.stride = 9178 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width); 9179 omx->drv_ctx.video_resolution.scan_lines = 9180 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height); 9181 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 9182 omx->drv_ctx.video_resolution.stride = 9183 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width); 9184 omx->drv_ctx.video_resolution.scan_lines = 9185 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height); 9186 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 9187 omx->drv_ctx.video_resolution.stride = 9188 VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width); 9189 omx->drv_ctx.video_resolution.scan_lines = 9190 VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height); 9191 } 9192 9193 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX, 9194 OMX_IndexConfigCommonOutputCrop, 9195 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 9196 } 9197 9198 if (omxhdr->nFilledLen) 9199 omx->prev_n_filled_len = omxhdr->nFilledLen; 9200 9201 if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) { 9202 omx->request_perf_level(VIDC_NOMINAL); 9203 } 9204 if (omx->output_use_buffer && omxhdr->pBuffer && 9205 vdec_msg->msgdata.output_frame.bufferaddr) 9206 memcpy ( omxhdr->pBuffer, (void *) 9207 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + 9208 (unsigned long)vdec_msg->msgdata.output_frame.offset), 9209 vdec_msg->msgdata.output_frame.len); 9210 } else { 9211 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u", 9212 (unsigned int)vdec_msg->msgdata.output_frame.len, 9213 omxhdr->nAllocLen, omx->prev_n_filled_len); 9214 omxhdr->nFilledLen = 0; 9215 } 9216 9217 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code, 9218 OMX_COMPONENT_GENERATE_FBD); 9219 9220 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) { 9221 omx->post_event ((unsigned long)NULL, vdec_msg->status_code, 9222 OMX_COMPONENT_GENERATE_EOS_DONE); 9223 } else { 9224 omx->post_event ((unsigned int)NULL, vdec_msg->status_code, 9225 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 9226 } 9227 break; 9228 case VDEC_MSG_EVT_CONFIG_CHANGED: 9229 DEBUG_PRINT_HIGH("Port settings changed"); 9230 omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width; 9231 omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height; 9232 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, 9233 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 9234 if (!omx->m_need_turbo) { 9235 omx->request_perf_level(VIDC_NOMINAL); 9236 } 9237 break; 9238 default: 9239 break; 9240 } 9241 return rc; 9242} 9243 9244OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 9245 OMX_HANDLETYPE hComp, 9246 OMX_BUFFERHEADERTYPE *buffer 9247 ) 9248{ 9249 unsigned address,p2,id; 9250 DEBUG_PRINT_LOW("Empty this arbitrary"); 9251 9252 if (buffer == NULL) { 9253 return OMX_ErrorBadParameter; 9254 } 9255 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 9256 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld", 9257 (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp); 9258 9259 /* return zero length and not an EOS buffer */ 9260 /* return buffer if input flush in progress */ 9261 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && 9262 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) { 9263 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); 9264 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 9265 return OMX_ErrorNone; 9266 } 9267 9268 if (psource_frame == NULL) { 9269 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp); 9270 psource_frame = buffer; 9271 DEBUG_PRINT_LOW("Try to Push One Input Buffer "); 9272 push_input_buffer (hComp); 9273 } else { 9274 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); 9275 if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL, 9276 (unsigned)NULL)) { 9277 return OMX_ErrorBadParameter; 9278 } 9279 } 9280 9281 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 9282 codec_config_flag = false; 9283 } 9284 return OMX_ErrorNone; 9285} 9286 9287OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 9288{ 9289 unsigned long address,p2,id; 9290 OMX_ERRORTYPE ret = OMX_ErrorNone; 9291 9292 if (pdest_frame == NULL || psource_frame == NULL) { 9293 /*Check if we have a destination buffer*/ 9294 if (pdest_frame == NULL) { 9295 DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); 9296 if (m_input_free_q.m_size) { 9297 m_input_free_q.pop_entry(&address,&p2,&id); 9298 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 9299 pdest_frame->nFilledLen = 0; 9300 pdest_frame->nTimeStamp = LLONG_MAX; 9301 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); 9302 } 9303 } 9304 9305 /*Check if we have a destination buffer*/ 9306 if (psource_frame == NULL) { 9307 DEBUG_PRINT_LOW("Get a source buffer from the queue"); 9308 if (m_input_pending_q.m_size) { 9309 m_input_pending_q.pop_entry(&address,&p2,&id); 9310 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 9311 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 9312 psource_frame->nTimeStamp); 9313 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 9314 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9315 9316 } 9317 } 9318 9319 } 9320 9321 while ((pdest_frame != NULL) && (psource_frame != NULL)) { 9322 switch (codec_type_parse) { 9323 case CODEC_TYPE_MPEG4: 9324 case CODEC_TYPE_H263: 9325 case CODEC_TYPE_MPEG2: 9326 ret = push_input_sc_codec(hComp); 9327 break; 9328 case CODEC_TYPE_H264: 9329 ret = push_input_h264(hComp); 9330 break; 9331 case CODEC_TYPE_HEVC: 9332 ret = push_input_hevc(hComp); 9333 break; 9334 case CODEC_TYPE_VC1: 9335 ret = push_input_vc1(hComp); 9336 break; 9337 default: 9338 break; 9339 } 9340 if (ret != OMX_ErrorNone) { 9341 DEBUG_PRINT_ERROR("Pushing input Buffer Failed"); 9342 omx_report_error (); 9343 break; 9344 } 9345 } 9346 9347 return ret; 9348} 9349 9350OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 9351{ 9352 OMX_U32 partial_frame = 1; 9353 OMX_BOOL generate_ebd = OMX_TRUE; 9354 unsigned long address = 0, p2 = 0, id = 0; 9355 9356 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld", 9357 psource_frame,psource_frame->nTimeStamp); 9358 if (m_frame_parser.parse_sc_frame(psource_frame, 9359 pdest_frame,&partial_frame) == -1) { 9360 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9361 return OMX_ErrorBadParameter; 9362 } 9363 9364 if (partial_frame == 0) { 9365 DEBUG_PRINT_LOW("Frame size %u source %p frame count %d", 9366 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count); 9367 9368 9369 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp); 9370 /*First Parsed buffer will have only header Hence skip*/ 9371 if (frame_count == 0) { 9372 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); 9373 9374 if (codec_type_parse == CODEC_TYPE_MPEG4 || 9375 codec_type_parse == CODEC_TYPE_DIVX) { 9376 mp4StreamType psBits; 9377 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; 9378 psBits.numBytes = pdest_frame->nFilledLen; 9379 mp4_headerparser.parseHeader(&psBits); 9380 } 9381 9382 frame_count++; 9383 } else { 9384 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9385 if (pdest_frame->nFilledLen) { 9386 /*Push the frame to the Decoder*/ 9387 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9388 return OMX_ErrorBadParameter; 9389 } 9390 frame_count++; 9391 pdest_frame = NULL; 9392 9393 if (m_input_free_q.m_size) { 9394 m_input_free_q.pop_entry(&address,&p2,&id); 9395 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9396 pdest_frame->nFilledLen = 0; 9397 } 9398 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) { 9399 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL"); 9400 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL, 9401 (unsigned)NULL); 9402 pdest_frame = NULL; 9403 } 9404 } 9405 } else { 9406 DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen); 9407 /*Check if Destination Buffer is full*/ 9408 if (pdest_frame->nAllocLen == 9409 pdest_frame->nFilledLen + pdest_frame->nOffset) { 9410 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled"); 9411 return OMX_ErrorStreamCorrupt; 9412 } 9413 } 9414 9415 if (psource_frame->nFilledLen == 0) { 9416 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9417 if (pdest_frame) { 9418 pdest_frame->nFlags |= psource_frame->nFlags; 9419 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 9420 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld", 9421 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9422 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 9423 (unsigned int)pdest_frame->nFilledLen,frame_count++); 9424 /*Push the frame to the Decoder*/ 9425 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9426 return OMX_ErrorBadParameter; 9427 } 9428 frame_count++; 9429 pdest_frame = NULL; 9430 } else { 9431 DEBUG_PRINT_LOW("Last frame in else dest addr") ; 9432 generate_ebd = OMX_FALSE; 9433 } 9434 } 9435 if (generate_ebd) { 9436 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); 9437 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 9438 psource_frame = NULL; 9439 9440 if (m_input_pending_q.m_size) { 9441 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 9442 m_input_pending_q.pop_entry(&address,&p2,&id); 9443 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 9444 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame, 9445 psource_frame->nTimeStamp); 9446 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u", 9447 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9448 } 9449 } 9450 } 9451 return OMX_ErrorNone; 9452} 9453 9454OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 9455{ 9456 OMX_U32 partial_frame = 1; 9457 unsigned long address = 0, p2 = 0, id = 0; 9458 OMX_BOOL isNewFrame = OMX_FALSE; 9459 OMX_BOOL generate_ebd = OMX_TRUE; 9460 9461 if (h264_scratch.pBuffer == NULL) { 9462 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated"); 9463 return OMX_ErrorBadParameter; 9464 } 9465 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u " 9466 "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal); 9467 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen); 9468 if (h264_scratch.nFilledLen && look_ahead_nal) { 9469 look_ahead_nal = false; 9470 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9471 h264_scratch.nFilledLen) { 9472 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9473 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9474 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9475 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); 9476 h264_scratch.nFilledLen = 0; 9477 } else { 9478 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264"); 9479 return OMX_ErrorBadParameter; 9480 } 9481 } 9482 9483 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result 9484 in EOS flag getting associated with the destination 9485 */ 9486 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) && 9487 pdest_frame->nFilledLen) { 9488 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'"); 9489 generate_ebd = OMX_FALSE; 9490 } 9491 9492 if (nal_length == 0) { 9493 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); 9494 if (m_frame_parser.parse_sc_frame(psource_frame, 9495 &h264_scratch,&partial_frame) == -1) { 9496 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9497 return OMX_ErrorBadParameter; 9498 } 9499 } else { 9500 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); 9501 if (m_frame_parser.parse_h264_nallength(psource_frame, 9502 &h264_scratch,&partial_frame) == -1) { 9503 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 9504 return OMX_ErrorBadParameter; 9505 } 9506 } 9507 9508 if (partial_frame == 0) { 9509 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 9510 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 9511 nal_count++; 9512 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 9513 h264_scratch.nFlags = psource_frame->nFlags; 9514 } else { 9515 DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen); 9516 if (h264_scratch.nFilledLen) { 9517 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, 9518 NALU_TYPE_SPS); 9519#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9520 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 9521 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 9522 h264_scratch.nFilledLen, NALU_TYPE_SEI); 9523 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 9524 // If timeinfo is present frame info from SEI is already processed 9525 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 9526 h264_scratch.nFilledLen, NALU_TYPE_SEI); 9527#endif 9528 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 9529 nal_count++; 9530 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { 9531 pdest_frame->nTimeStamp = h264_last_au_ts; 9532 pdest_frame->nFlags = h264_last_au_flags; 9533#ifdef PANSCAN_HDLR 9534 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 9535 h264_parser->update_panscan_data(h264_last_au_ts); 9536#endif 9537 } 9538 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || 9539 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { 9540 h264_last_au_ts = h264_scratch.nTimeStamp; 9541 h264_last_au_flags = h264_scratch.nFlags; 9542#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9543 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 9544 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); 9545 if (!VALID_TS(h264_last_au_ts)) 9546 h264_last_au_ts = ts_in_sei; 9547 } 9548#endif 9549 } else 9550 h264_last_au_ts = LLONG_MAX; 9551 } 9552 9553 if (!isNewFrame) { 9554 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9555 h264_scratch.nFilledLen) { 9556 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u", 9557 (unsigned int)h264_scratch.nFilledLen); 9558 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9559 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9560 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9561 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) 9562 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 9563 h264_scratch.nFilledLen = 0; 9564 } else { 9565 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264"); 9566 return OMX_ErrorBadParameter; 9567 } 9568 } else if(h264_scratch.nFilledLen) { 9569 look_ahead_nal = true; 9570 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu", 9571 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9572 DEBUG_PRINT_LOW("Found a frame size = %u number = %d", 9573 (unsigned int)pdest_frame->nFilledLen,frame_count++); 9574 9575 if (pdest_frame->nFilledLen == 0) { 9576 DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); 9577 look_ahead_nal = false; 9578 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9579 h264_scratch.nFilledLen) { 9580 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9581 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9582 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9583 h264_scratch.nFilledLen = 0; 9584 } else { 9585 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264"); 9586 return OMX_ErrorBadParameter; 9587 } 9588 } else { 9589 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 9590 DEBUG_PRINT_LOW("Reset the EOS Flag"); 9591 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9592 } 9593 /*Push the frame to the Decoder*/ 9594 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9595 return OMX_ErrorBadParameter; 9596 } 9597 //frame_count++; 9598 pdest_frame = NULL; 9599 if (m_input_free_q.m_size) { 9600 m_input_free_q.pop_entry(&address,&p2,&id); 9601 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9602 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); 9603 pdest_frame->nFilledLen = 0; 9604 pdest_frame->nFlags = 0; 9605 pdest_frame->nTimeStamp = LLONG_MAX; 9606 } 9607 } 9608 } 9609 } 9610 } else { 9611 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen); 9612 /*Check if Destination Buffer is full*/ 9613 if (h264_scratch.nAllocLen == 9614 h264_scratch.nFilledLen + h264_scratch.nOffset) { 9615 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 9616 return OMX_ErrorStreamCorrupt; 9617 } 9618 } 9619 9620 if (!psource_frame->nFilledLen) { 9621 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); 9622 9623 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9624 if (pdest_frame) { 9625 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 9626 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 9627 h264_scratch.nFilledLen) { 9628 if(pdest_frame->nFilledLen == 0) { 9629 /* No residual frame from before, send whatever 9630 * we have left */ 9631 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9632 h264_scratch.pBuffer, h264_scratch.nFilledLen); 9633 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9634 h264_scratch.nFilledLen = 0; 9635 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 9636 } else { 9637 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 9638 if(!isNewFrame) { 9639 /* Have a residual frame, but we know that the 9640 * AU in this frame is belonging to whatever 9641 * frame we had left over. So append it */ 9642 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 9643 h264_scratch.pBuffer,h264_scratch.nFilledLen); 9644 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 9645 h264_scratch.nFilledLen = 0; 9646 if (h264_last_au_ts != LLONG_MAX) 9647 pdest_frame->nTimeStamp = h264_last_au_ts; 9648 } else { 9649 /* Completely new frame, let's just push what 9650 * we have now. The resulting EBD would trigger 9651 * another push */ 9652 generate_ebd = OMX_FALSE; 9653 pdest_frame->nTimeStamp = h264_last_au_ts; 9654 h264_last_au_ts = h264_scratch.nTimeStamp; 9655 } 9656 } 9657 } else { 9658 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264"); 9659 return OMX_ErrorBadParameter; 9660 } 9661 9662 /* Iff we coalesced two buffers, inherit the flags of both bufs */ 9663 if(generate_ebd == OMX_TRUE) { 9664 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 9665 } 9666 9667 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu", 9668 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 9669 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); 9670#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 9671 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 9672 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); 9673 if (!VALID_TS(pdest_frame->nTimeStamp)) 9674 pdest_frame->nTimeStamp = ts_in_sei; 9675 } 9676#endif 9677 /*Push the frame to the Decoder*/ 9678 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 9679 return OMX_ErrorBadParameter; 9680 } 9681 frame_count++; 9682 pdest_frame = NULL; 9683 } else { 9684 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 9685 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 9686 generate_ebd = OMX_FALSE; 9687 } 9688 } 9689 } 9690 if (generate_ebd && !psource_frame->nFilledLen) { 9691 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 9692 psource_frame = NULL; 9693 if (m_input_pending_q.m_size) { 9694 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 9695 m_input_pending_q.pop_entry(&address,&p2,&id); 9696 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 9697 DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u", 9698 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen); 9699 } 9700 } 9701 return OMX_ErrorNone; 9702} 9703 9704OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) 9705{ 9706 OMX_ERRORTYPE rc = OMX_ErrorNone; 9707 if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) { 9708 memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); 9709 if (pDst->nTimeStamp == LLONG_MAX) { 9710 pDst->nTimeStamp = pSrc->nTimeStamp; 9711 DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp); 9712 } 9713 pDst->nFilledLen += pSrc->nFilledLen; 9714 pSrc->nFilledLen = 0; 9715 } else { 9716 DEBUG_PRINT_ERROR("Error: Destination buffer overflow"); 9717 rc = OMX_ErrorBadParameter; 9718 } 9719 return rc; 9720} 9721 9722OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp) 9723{ 9724 OMX_U32 partial_frame = 1; 9725 unsigned long address,p2,id; 9726 OMX_BOOL isNewFrame = OMX_FALSE; 9727 OMX_BOOL generate_ebd = OMX_TRUE; 9728 OMX_ERRORTYPE rc = OMX_ErrorNone; 9729 if (h264_scratch.pBuffer == NULL) { 9730 DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated"); 9731 return OMX_ErrorBadParameter; 9732 } 9733 9734 DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \ 9735 pdest_frame nFilledLen %u nTimeStamp %lld", 9736 (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9737 9738 if (h264_scratch.nFilledLen && look_ahead_nal) { 9739 look_ahead_nal = false; 9740 rc = copy_buffer(pdest_frame, &h264_scratch); 9741 if (rc != OMX_ErrorNone) { 9742 return rc; 9743 } 9744 } 9745 9746 if (nal_length == 0) { 9747 if (m_frame_parser.parse_sc_frame(psource_frame, 9748 &h264_scratch,&partial_frame) == -1) { 9749 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 9750 return OMX_ErrorBadParameter; 9751 } 9752 } else { 9753 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length); 9754 if (m_frame_parser.parse_h264_nallength(psource_frame, 9755 &h264_scratch,&partial_frame) == -1) { 9756 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 9757 return OMX_ErrorBadParameter; 9758 } 9759 } 9760 9761 if (partial_frame == 0) { 9762 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 9763 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 9764 nal_count++; 9765 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 9766 h264_scratch.nFlags = psource_frame->nFlags; 9767 } else { 9768 DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen); 9769 if (h264_scratch.nFilledLen) { 9770 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame); 9771 nal_count++; 9772 } 9773 9774 if (!isNewFrame) { 9775 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \ 9776 nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld", 9777 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp, 9778 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9779 rc = copy_buffer(pdest_frame, &h264_scratch); 9780 if (rc != OMX_ErrorNone) { 9781 return rc; 9782 } 9783 } else { 9784 look_ahead_nal = true; 9785 if (pdest_frame->nFilledLen == 0) { 9786 look_ahead_nal = false; 9787 DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer"); 9788 rc = copy_buffer(pdest_frame, &h264_scratch); 9789 if (rc != OMX_ErrorNone) { 9790 return OMX_ErrorBadParameter; 9791 } 9792 } else { 9793 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 9794 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 9795 } 9796 DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \ 9797 nTimeStamp %lld, look_ahead_nal in h264_scratch \ 9798 nFilledLen %u nTimeStamp %lld", 9799 frame_count++, (unsigned int)pdest_frame->nFilledLen, 9800 pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen, 9801 h264_scratch.nTimeStamp); 9802 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 9803 return OMX_ErrorBadParameter; 9804 } 9805 pdest_frame = NULL; 9806 if (m_input_free_q.m_size) { 9807 m_input_free_q.pop_entry(&address, &p2, &id); 9808 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 9809 DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame); 9810 pdest_frame->nFilledLen = 0; 9811 pdest_frame->nFlags = 0; 9812 pdest_frame->nTimeStamp = LLONG_MAX; 9813 } 9814 } 9815 } 9816 } 9817 } else { 9818 DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \ 9819 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \ 9820 nFilledLen %u nTimeStamp %lld", 9821 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp, 9822 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp, 9823 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp); 9824 9825 if (h264_scratch.nAllocLen == 9826 h264_scratch.nFilledLen + h264_scratch.nOffset) { 9827 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 9828 return OMX_ErrorStreamCorrupt; 9829 } 9830 } 9831 9832 if (!psource_frame->nFilledLen) { 9833 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame); 9834 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 9835 if (pdest_frame) { 9836 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 9837 rc = copy_buffer(pdest_frame, &h264_scratch); 9838 if ( rc != OMX_ErrorNone ) { 9839 return rc; 9840 } 9841 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 9842 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 9843 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld", 9844 frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 9845 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) { 9846 return OMX_ErrorBadParameter; 9847 } 9848 frame_count++; 9849 pdest_frame = NULL; 9850 } else { 9851 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u", 9852 pdest_frame, (unsigned int)h264_scratch.nFilledLen); 9853 generate_ebd = OMX_FALSE; 9854 } 9855 } 9856 } 9857 9858 if (generate_ebd && !psource_frame->nFilledLen) { 9859 m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame); 9860 psource_frame = NULL; 9861 if (m_input_pending_q.m_size) { 9862 m_input_pending_q.pop_entry(&address, &p2, &id); 9863 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 9864 DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld", 9865 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp); 9866 } 9867 } 9868 return OMX_ErrorNone; 9869} 9870 9871OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp) 9872{ 9873 OMX_U8 *buf, *pdest; 9874 OMX_U32 partial_frame = 1; 9875 OMX_U32 buf_len, dest_len; 9876 9877 if (first_frame == 0) { 9878 first_frame = 1; 9879 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); 9880 if (!m_vendor_config.pData) { 9881 DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); 9882 buf = psource_frame->pBuffer; 9883 buf_len = psource_frame->nFilledLen; 9884 9885 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 9886 VC1_SP_MP_START_CODE) { 9887 m_vc1_profile = VC1_SP_MP_RCV; 9888 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) { 9889 m_vc1_profile = VC1_AP; 9890 } else { 9891 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer"); 9892 return OMX_ErrorStreamCorrupt; 9893 } 9894 } else { 9895 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 9896 pdest_frame->nOffset; 9897 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 9898 pdest_frame->nOffset); 9899 9900 if (dest_len < m_vendor_config.nDataSize) { 9901 DEBUG_PRINT_ERROR("Destination buffer full"); 9902 return OMX_ErrorBadParameter; 9903 } else { 9904 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 9905 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 9906 } 9907 } 9908 } 9909 9910 switch (m_vc1_profile) { 9911 case VC1_AP: 9912 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); 9913 if (push_input_sc_codec(hComp) != OMX_ErrorNone) { 9914 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code"); 9915 return OMX_ErrorBadParameter; 9916 } 9917 break; 9918 9919 case VC1_SP_MP_RCV: 9920 default: 9921 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode"); 9922 return OMX_ErrorBadParameter; 9923 } 9924 return OMX_ErrorNone; 9925} 9926 9927#ifndef USE_ION 9928bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 9929 OMX_U32 alignment) 9930{ 9931 struct pmem_allocation allocation; 9932 allocation.size = buffer_size; 9933 allocation.align = clip2(alignment); 9934 if (allocation.align < 4096) { 9935 allocation.align = 4096; 9936 } 9937 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) { 9938 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)", 9939 allocation.align, allocation.size); 9940 return false; 9941 } 9942 return true; 9943} 9944#endif 9945#ifdef USE_ION 9946int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, 9947 OMX_U32 alignment, struct ion_allocation_data *alloc_data, 9948 struct ion_fd_data *fd_data, int flag) 9949{ 9950 int fd = -EINVAL; 9951 int rc = -EINVAL; 9952 int ion_dev_flag; 9953 struct vdec_ion ion_buf_info; 9954 if (!alloc_data || buffer_size <= 0 || !fd_data) { 9955 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory"); 9956 return -EINVAL; 9957 } 9958 ion_dev_flag = O_RDONLY; 9959 fd = open (MEM_DEVICE, ion_dev_flag); 9960 if (fd < 0) { 9961 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd); 9962 return fd; 9963 } 9964 9965 alloc_data->flags = flag; 9966 alloc_data->len = buffer_size; 9967 alloc_data->align = clip2(alignment); 9968 if (alloc_data->align < 4096) { 9969 alloc_data->align = 4096; 9970 } 9971 9972 alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID); 9973 if (secure_mode && (alloc_data->flags & ION_SECURE)) { 9974 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 9975 } 9976 9977 /* Use secure display cma heap for obvious reasons. */ 9978 if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) { 9979 alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID); 9980 } 9981 9982 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); 9983 if (rc || !alloc_data->handle) { 9984 DEBUG_PRINT_ERROR("ION ALLOC memory failed"); 9985 alloc_data->handle = 0; 9986 close(fd); 9987 fd = -ENOMEM; 9988 return fd; 9989 } 9990 fd_data->handle = alloc_data->handle; 9991 rc = ioctl(fd,ION_IOC_MAP,fd_data); 9992 if (rc) { 9993 DEBUG_PRINT_ERROR("ION MAP failed "); 9994 ion_buf_info.ion_alloc_data = *alloc_data; 9995 ion_buf_info.ion_device_fd = fd; 9996 ion_buf_info.fd_ion_data = *fd_data; 9997 free_ion_memory(&ion_buf_info); 9998 fd_data->fd =-1; 9999 fd = -ENOMEM; 10000 } 10001 10002 return fd; 10003} 10004 10005void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) 10006{ 10007 10008 if (!buf_ion_info) { 10009 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata"); 10010 return; 10011 } 10012 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 10013 &buf_ion_info->ion_alloc_data.handle)) { 10014 DEBUG_PRINT_ERROR("ION: free failed" ); 10015 } 10016 close(buf_ion_info->ion_device_fd); 10017 buf_ion_info->ion_device_fd = -1; 10018 buf_ion_info->ion_alloc_data.handle = 0; 10019 buf_ion_info->fd_ion_data.fd = -1; 10020} 10021#endif 10022void omx_vdec::free_output_buffer_header() 10023{ 10024 DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); 10025 output_use_buffer = false; 10026 ouput_egl_buffers = false; 10027 10028 if (m_out_mem_ptr) { 10029 free (m_out_mem_ptr); 10030 m_out_mem_ptr = NULL; 10031 } 10032 10033 if (m_platform_list) { 10034 free(m_platform_list); 10035 m_platform_list = NULL; 10036 } 10037 10038 if (drv_ctx.ptr_respbuffer) { 10039 free (drv_ctx.ptr_respbuffer); 10040 drv_ctx.ptr_respbuffer = NULL; 10041 } 10042 if (drv_ctx.ptr_outputbuffer) { 10043 free (drv_ctx.ptr_outputbuffer); 10044 drv_ctx.ptr_outputbuffer = NULL; 10045 } 10046#ifdef USE_ION 10047 if (drv_ctx.op_buf_ion_info) { 10048 DEBUG_PRINT_LOW("Free o/p ion context"); 10049 free(drv_ctx.op_buf_ion_info); 10050 drv_ctx.op_buf_ion_info = NULL; 10051 } 10052#endif 10053 free(drv_ctx.op_buf_map_info); 10054 drv_ctx.op_buf_map_info = NULL; 10055 buf_ref_remove(); 10056} 10057 10058void omx_vdec::free_input_buffer_header() 10059{ 10060 input_use_buffer = false; 10061 if (arbitrary_bytes) { 10062 if (m_inp_heap_ptr) { 10063 DEBUG_PRINT_LOW("Free input Heap Pointer"); 10064 free (m_inp_heap_ptr); 10065 m_inp_heap_ptr = NULL; 10066 } 10067 10068 if (m_phdr_pmem_ptr) { 10069 DEBUG_PRINT_LOW("Free input pmem header Pointer"); 10070 free (m_phdr_pmem_ptr); 10071 m_phdr_pmem_ptr = NULL; 10072 } 10073 } 10074 if (m_inp_mem_ptr) { 10075 DEBUG_PRINT_LOW("Free input pmem Pointer area"); 10076 free (m_inp_mem_ptr); 10077 m_inp_mem_ptr = NULL; 10078 } 10079 /* We just freed all the buffer headers, every thing in m_input_free_q, 10080 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */ 10081 while (m_input_free_q.m_size) { 10082 unsigned long address, p2, id; 10083 m_input_free_q.pop_entry(&address, &p2, &id); 10084 } 10085 while (m_input_pending_q.m_size) { 10086 unsigned long address, p2, id; 10087 m_input_pending_q.pop_entry(&address, &p2, &id); 10088 } 10089 pdest_frame = NULL; 10090 psource_frame = NULL; 10091 if (drv_ctx.ptr_inputbuffer) { 10092 DEBUG_PRINT_LOW("Free Driver Context pointer"); 10093 free (drv_ctx.ptr_inputbuffer); 10094 drv_ctx.ptr_inputbuffer = NULL; 10095 } 10096#ifdef USE_ION 10097 if (drv_ctx.ip_buf_ion_info) { 10098 DEBUG_PRINT_LOW("Free ion context"); 10099 free(drv_ctx.ip_buf_ion_info); 10100 drv_ctx.ip_buf_ion_info = NULL; 10101 } 10102#endif 10103} 10104 10105int omx_vdec::stream_off(OMX_U32 port) 10106{ 10107 enum v4l2_buf_type btype; 10108 int rc = 0; 10109 enum v4l2_ports v4l2_port = OUTPUT_PORT; 10110 10111 if (port == OMX_CORE_INPUT_PORT_INDEX) { 10112 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10113 v4l2_port = OUTPUT_PORT; 10114 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 10115 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10116 v4l2_port = CAPTURE_PORT; 10117 } else if (port == OMX_ALL) { 10118 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); 10119 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 10120 10121 if (!rc_input) 10122 return rc_input; 10123 else 10124 return rc_output; 10125 } 10126 10127 if (!streaming[v4l2_port]) { 10128 // already streamed off, warn and move on 10129 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," 10130 " which is already streamed off", v4l2_port); 10131 return 0; 10132 } 10133 10134 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); 10135 10136 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); 10137 if (rc) { 10138 /*TODO: How to handle this case */ 10139 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port); 10140 } else { 10141 streaming[v4l2_port] = false; 10142 } 10143 10144 return rc; 10145} 10146 10147OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) 10148{ 10149 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10150 struct v4l2_requestbuffers bufreq; 10151 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0; 10152 unsigned int final_extra_data_size = 0; 10153 struct v4l2_format fmt; 10154 int ret = 0; 10155 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 10156 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10157 bufreq.memory = V4L2_MEMORY_USERPTR; 10158 bufreq.count = 1; 10159 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10160 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10161 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10162 fmt.fmt.pix_mp.pixelformat = output_capability; 10163 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10164 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10165 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10166 fmt.fmt.pix_mp.pixelformat = capture_capability; 10167 } else { 10168 eRet = OMX_ErrorBadParameter; 10169 } 10170 if (eRet==OMX_ErrorNone) { 10171 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10172 } 10173 if (ret) { 10174 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 10175 /*TODO: How to handle this case */ 10176 eRet = OMX_ErrorInsufficientResources; 10177 return eRet; 10178 } else { 10179 bool is_res_1080p_or_below = (drv_ctx.video_resolution.frame_width <= 1920 && 10180 drv_ctx.video_resolution.frame_height <= 1088) || 10181 (drv_ctx.video_resolution.frame_height <= 1088 && 10182 drv_ctx.video_resolution.frame_width <= 1920); 10183 10184 int fps = drv_ctx.frame_rate.fps_numerator / (float)drv_ctx.frame_rate.fps_denominator; 10185 bool fps_above_180 = (fps >= 180 || operating_frame_rate >= 180) ? true : false; 10186 bool increase_output = (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) && (bufreq.count >= 16); 10187 10188 if (increase_output && fps_above_180 && 10189 output_capability == V4L2_PIX_FMT_H264 && 10190 is_res_1080p_or_below) { 10191 m_need_turbo |= TURBO_MODE_HIGH_FPS; 10192 DEBUG_PRINT_LOW("High fps - fps = %d operating_rate = %d", fps, operating_frame_rate); 10193 DEBUG_PRINT_LOW("getbufreq[output]: Increase buffer count (%d) to (%d) to support high fps", 10194 bufreq.count, bufreq.count + 10); 10195 bufreq.count += 10; 10196 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10197 if (ret) { 10198 DEBUG_PRINT_ERROR("(Failed to set updated buffer count to driver"); 10199 eRet = OMX_ErrorInsufficientResources; 10200 return eRet; 10201 } 10202 DEBUG_PRINT_LOW("new buf count = %d set to driver", bufreq.count); 10203 request_perf_level(VIDC_TURBO); 10204 } 10205 10206 buffer_prop->actualcount = bufreq.count; 10207 buffer_prop->mincount = bufreq.count; 10208 DEBUG_PRINT_HIGH("Count = %d",bufreq.count); 10209 } 10210 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)", 10211 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10212 10213 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10214 10215 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 10216 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; 10217 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); 10218 10219 if (ret) { 10220 /*TODO: How to handle this case */ 10221 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 10222 eRet = OMX_ErrorInsufficientResources; 10223 } else { 10224 int extra_idx = 0; 10225 10226 eRet = is_video_session_supported(); 10227 if (eRet) 10228 return eRet; 10229 10230 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 10231 buf_size = buffer_prop->buffer_size; 10232 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 10233 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 10234 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 10235 } else if (extra_idx >= VIDEO_MAX_PLANES) { 10236 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 10237 return OMX_ErrorBadParameter; 10238 } 10239 10240 default_extra_data_size = VENUS_EXTRADATA_SIZE( 10241 drv_ctx.video_resolution.frame_height, 10242 drv_ctx.video_resolution.frame_width); 10243 final_extra_data_size = extra_data_size > default_extra_data_size ? 10244 extra_data_size : default_extra_data_size; 10245 10246 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) & 10247 (~(buffer_prop->alignment - 1)); 10248 10249 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size; 10250 drv_ctx.extradata_info.count = buffer_prop->actualcount; 10251 drv_ctx.extradata_info.buffer_size = final_extra_data_size; 10252 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 10253 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)", 10254 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size); 10255 if (extra_data_size) 10256 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)", 10257 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size); 10258 10259 if (in_reconfig) // BufReq will be set to driver when port is disabled 10260 buffer_prop->buffer_size = buf_size; 10261 else if (buf_size != buffer_prop->buffer_size) { 10262 buffer_prop->buffer_size = buf_size; 10263 eRet = set_buffer_req(buffer_prop); 10264 } 10265 } 10266 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)", 10267 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10268 return eRet; 10269} 10270 10271OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) 10272{ 10273 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10274 unsigned buf_size = 0; 10275 struct v4l2_format fmt, c_fmt; 10276 struct v4l2_requestbuffers bufreq; 10277 int ret = 0; 10278 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)", 10279 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size); 10280 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 10281 if (buf_size != buffer_prop->buffer_size) { 10282 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)", 10283 (unsigned int)buffer_prop->buffer_size, buf_size); 10284 eRet = OMX_ErrorBadParameter; 10285 } else { 10286 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 10287 memset(&c_fmt, 0x0, sizeof(struct v4l2_format)); 10288 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 10289 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 10290 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size; 10291 10292 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10293 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10294 fmt.fmt.pix_mp.pixelformat = output_capability; 10295 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 10296 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10297 c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10298 c_fmt.fmt.pix_mp.pixelformat = capture_capability; 10299 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt); 10300 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size; 10301 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt); 10302 } else { 10303 eRet = OMX_ErrorBadParameter; 10304 } 10305 10306 if (ret) { 10307 /*TODO: How to handle this case */ 10308 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); 10309 eRet = OMX_ErrorInsufficientResources; 10310 } 10311 10312 bufreq.memory = V4L2_MEMORY_USERPTR; 10313 bufreq.count = buffer_prop->actualcount; 10314 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 10315 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10316 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 10317 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10318 } else { 10319 eRet = OMX_ErrorBadParameter; 10320 } 10321 10322 if (eRet==OMX_ErrorNone) { 10323 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 10324 } 10325 10326 if (ret) { 10327 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); 10328 /*TODO: How to handle this case */ 10329 eRet = OMX_ErrorInsufficientResources; 10330 } else if (bufreq.count < buffer_prop->actualcount) { 10331 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" 10332 " on v4l2 port %d to %d (prefers %d)", bufreq.type, 10333 buffer_prop->actualcount, bufreq.count); 10334 eRet = OMX_ErrorInsufficientResources; 10335 } else { 10336 if (!client_buffers.update_buffer_req()) { 10337 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); 10338 eRet = OMX_ErrorInsufficientResources; 10339 } 10340 } 10341 } 10342 return eRet; 10343} 10344 10345OMX_ERRORTYPE omx_vdec::update_picture_resolution() 10346{ 10347 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10348 return eRet; 10349} 10350 10351OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 10352{ 10353 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10354 struct v4l2_format fmt; 10355 if (!portDefn) { 10356 return OMX_ErrorBadParameter; 10357 } 10358 DEBUG_PRINT_LOW("omx_vdec::update_portdef"); 10359 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 10360 portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 10361 portDefn->eDomain = OMX_PortDomainVideo; 10362 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 10363 if (0 == portDefn->nPortIndex) { 10364 portDefn->eDir = OMX_DirInput; 10365 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; 10366 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; 10367 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; 10368 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 10369 portDefn->format.video.eCompressionFormat = eCompressionFormat; 10370 //for input port, always report the fps value set by client, 10371 //to distinguish whether client got valid fps from parser. 10372 portDefn->format.video.xFramerate = m_fps_received; 10373 portDefn->bEnabled = m_inp_bEnabled; 10374 portDefn->bPopulated = m_inp_bPopulated; 10375 10376 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10377 fmt.fmt.pix_mp.pixelformat = output_capability; 10378 ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10379 } else if (1 == portDefn->nPortIndex) { 10380 unsigned int buf_size = 0; 10381 int ret = 0; 10382 if (in_reconfig && !is_down_scalar_enabled) { 10383 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10384 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10385 fmt.fmt.pix_mp.pixelformat = capture_capability; 10386 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10387 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 10388 } 10389 10390 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10391 fmt.fmt.pix_mp.pixelformat = capture_capability; 10392 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 10393 if (ret) { 10394 DEBUG_PRINT_ERROR("Get Resolution failed"); 10395 return OMX_ErrorHardware; 10396 } 10397 drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 10398 if (!client_buffers.update_buffer_req()) { 10399 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed"); 10400 return OMX_ErrorHardware; 10401 } 10402 10403 if (!client_buffers.get_buffer_req(buf_size)) { 10404 DEBUG_PRINT_ERROR("update buffer requirements"); 10405 return OMX_ErrorHardware; 10406 } 10407 portDefn->nBufferSize = buf_size; 10408 portDefn->eDir = OMX_DirOutput; 10409 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; 10410 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; 10411 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 10412 if (drv_ctx.frame_rate.fps_denominator > 0) 10413 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator / 10414 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format 10415 else { 10416 DEBUG_PRINT_ERROR("Error: Divide by zero"); 10417 return OMX_ErrorBadParameter; 10418 } 10419 portDefn->bEnabled = m_out_bEnabled; 10420 portDefn->bPopulated = m_out_bPopulated; 10421 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { 10422 DEBUG_PRINT_ERROR("Error in getting color format"); 10423 return OMX_ErrorHardware; 10424 } 10425 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10426 fmt.fmt.pix_mp.pixelformat = capture_capability; 10427 } else { 10428 portDefn->eDir = OMX_DirMax; 10429 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 10430 (int)portDefn->nPortIndex); 10431 eRet = OMX_ErrorBadPortIndex; 10432 } 10433 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, 10434 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); 10435 10436 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; 10437 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; 10438 portDefn->format.video.nStride = drv_ctx.video_resolution.stride; 10439 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; 10440 10441 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) || 10442 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) { 10443 portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16); 10444 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height; 10445 } 10446 DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d " 10447 "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u", 10448 (unsigned int)portDefn->nPortIndex, 10449 (unsigned int)portDefn->format.video.nFrameWidth, 10450 (unsigned int)portDefn->format.video.nFrameHeight, 10451 (int)portDefn->format.video.nStride, 10452 (unsigned int)portDefn->format.video.nSliceHeight, 10453 (unsigned int)portDefn->format.video.eColorFormat, 10454 (unsigned int)portDefn->nBufferSize, 10455 (unsigned int)portDefn->nBufferCountActual); 10456 10457 return eRet; 10458} 10459 10460OMX_ERRORTYPE omx_vdec::allocate_output_headers() 10461{ 10462 OMX_ERRORTYPE eRet = OMX_ErrorNone; 10463 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 10464 unsigned i= 0; 10465 10466 if (!m_out_mem_ptr) { 10467 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); 10468 int nBufHdrSize = 0; 10469 int nPlatformEntrySize = 0; 10470 int nPlatformListSize = 0; 10471 int nPMEMInfoSize = 0; 10472 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 10473 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 10474 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 10475 10476 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", 10477 drv_ctx.op_buf.actualcount); 10478 nBufHdrSize = drv_ctx.op_buf.actualcount * 10479 sizeof(OMX_BUFFERHEADERTYPE); 10480 10481 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 10482 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 10483 nPlatformListSize = drv_ctx.op_buf.actualcount * 10484 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 10485 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 10486 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 10487 10488 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize, 10489 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE), 10490 nPMEMInfoSize, 10491 nPlatformListSize); 10492 DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize, 10493 m_out_bm_count); 10494 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 10495 // Alloc mem for platform specific info 10496 char *pPtr=NULL; 10497 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 10498 nPMEMInfoSize,1); 10499 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 10500 calloc (sizeof(struct vdec_bufferpayload), 10501 drv_ctx.op_buf.actualcount); 10502 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 10503 calloc (sizeof (struct vdec_output_frameinfo), 10504 drv_ctx.op_buf.actualcount); 10505 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) { 10506 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer"); 10507 return OMX_ErrorInsufficientResources; 10508 } 10509 10510#ifdef USE_ION 10511 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ 10512 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); 10513 if (!drv_ctx.op_buf_ion_info) { 10514 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info"); 10515 return OMX_ErrorInsufficientResources; 10516 } 10517#endif 10518 if (dynamic_buf_mode) { 10519 out_dynamic_list = (struct dynamic_buf_list *) \ 10520 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount); 10521 if (out_dynamic_list) { 10522 for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++) 10523 out_dynamic_list[i].dup_fd = -1; 10524 } 10525 } 10526 10527 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 10528 && drv_ctx.ptr_respbuffer) { 10529 bufHdr = m_out_mem_ptr; 10530 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 10531 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 10532 (((char *) m_platform_list) + nPlatformListSize); 10533 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 10534 (((char *) m_platform_entry) + nPlatformEntrySize); 10535 pPlatformList = m_platform_list; 10536 pPlatformEntry = m_platform_entry; 10537 pPMEMInfo = m_pmem_info; 10538 10539 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 10540 10541 // Settting the entire storage nicely 10542 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, 10543 m_out_mem_ptr,pPlatformEntry); 10544 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 10545 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 10546 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 10547 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 10548 // Set the values when we determine the right HxW param 10549 bufHdr->nAllocLen = 0; 10550 bufHdr->nFilledLen = 0; 10551 bufHdr->pAppPrivate = NULL; 10552 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 10553 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 10554 pPlatformEntry->entry = pPMEMInfo; 10555 // Initialize the Platform List 10556 pPlatformList->nEntries = 1; 10557 pPlatformList->entryList = pPlatformEntry; 10558 // Keep pBuffer NULL till vdec is opened 10559 bufHdr->pBuffer = NULL; 10560 pPMEMInfo->offset = 0; 10561 pPMEMInfo->pmem_fd = -1; 10562 bufHdr->pPlatformPrivate = pPlatformList; 10563 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 10564#ifdef USE_ION 10565 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 10566#endif 10567 /*Create a mapping between buffers*/ 10568 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 10569 drv_ctx.ptr_respbuffer[i].client_data = (void *) \ 10570 &drv_ctx.ptr_outputbuffer[i]; 10571 // Move the buffer and buffer header pointers 10572 bufHdr++; 10573 pPMEMInfo++; 10574 pPlatformEntry++; 10575 pPlatformList++; 10576 } 10577 } else { 10578 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 10579 m_out_mem_ptr, pPtr); 10580 if (m_out_mem_ptr) { 10581 free(m_out_mem_ptr); 10582 m_out_mem_ptr = NULL; 10583 } 10584 if (pPtr) { 10585 free(pPtr); 10586 pPtr = NULL; 10587 } 10588 if (drv_ctx.ptr_outputbuffer) { 10589 free(drv_ctx.ptr_outputbuffer); 10590 drv_ctx.ptr_outputbuffer = NULL; 10591 } 10592 if (drv_ctx.ptr_respbuffer) { 10593 free(drv_ctx.ptr_respbuffer); 10594 drv_ctx.ptr_respbuffer = NULL; 10595 } 10596#ifdef USE_ION 10597 if (drv_ctx.op_buf_ion_info) { 10598 DEBUG_PRINT_LOW("Free o/p ion context"); 10599 free(drv_ctx.op_buf_ion_info); 10600 drv_ctx.op_buf_ion_info = NULL; 10601 } 10602#endif 10603 free(drv_ctx.op_buf_map_info); 10604 drv_ctx.op_buf_map_info = NULL; 10605 eRet = OMX_ErrorInsufficientResources; 10606 } 10607 } else { 10608 eRet = OMX_ErrorInsufficientResources; 10609 } 10610 return eRet; 10611} 10612 10613void omx_vdec::complete_pending_buffer_done_cbs() 10614{ 10615 unsigned long p1, p2, ident; 10616 omx_cmd_queue tmp_q, pending_bd_q; 10617 pthread_mutex_lock(&m_lock); 10618 // pop all pending GENERATE FDB from ftb queue 10619 while (m_ftb_q.m_size) { 10620 m_ftb_q.pop_entry(&p1,&p2,&ident); 10621 if (ident == OMX_COMPONENT_GENERATE_FBD) { 10622 pending_bd_q.insert_entry(p1,p2,ident); 10623 } else { 10624 tmp_q.insert_entry(p1,p2,ident); 10625 } 10626 } 10627 //return all non GENERATE FDB to ftb queue 10628 while (tmp_q.m_size) { 10629 tmp_q.pop_entry(&p1,&p2,&ident); 10630 m_ftb_q.insert_entry(p1,p2,ident); 10631 } 10632 // pop all pending GENERATE EDB from etb queue 10633 while (m_etb_q.m_size) { 10634 m_etb_q.pop_entry(&p1,&p2,&ident); 10635 if (ident == OMX_COMPONENT_GENERATE_EBD) { 10636 pending_bd_q.insert_entry(p1,p2,ident); 10637 } else { 10638 tmp_q.insert_entry(p1,p2,ident); 10639 } 10640 } 10641 //return all non GENERATE FDB to etb queue 10642 while (tmp_q.m_size) { 10643 tmp_q.pop_entry(&p1,&p2,&ident); 10644 m_etb_q.insert_entry(p1,p2,ident); 10645 } 10646 pthread_mutex_unlock(&m_lock); 10647 // process all pending buffer dones 10648 while (pending_bd_q.m_size) { 10649 pending_bd_q.pop_entry(&p1,&p2,&ident); 10650 switch (ident) { 10651 case OMX_COMPONENT_GENERATE_EBD: 10652 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 10653 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); 10654 omx_report_error (); 10655 } 10656 break; 10657 10658 case OMX_COMPONENT_GENERATE_FBD: 10659 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 10660 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); 10661 omx_report_error (); 10662 } 10663 break; 10664 } 10665 } 10666} 10667 10668void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) 10669{ 10670 OMX_U32 new_frame_interval = 0; 10671 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts 10672 && llabs(act_timestamp - prev_ts) > 2000) { 10673 new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ? 10674 llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual); 10675 if (new_frame_interval != frm_int || frm_int == 0) { 10676 frm_int = new_frame_interval; 10677 if (frm_int) { 10678 drv_ctx.frame_rate.fps_numerator = 1e6; 10679 drv_ctx.frame_rate.fps_denominator = frm_int; 10680 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", 10681 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator / 10682 (float)drv_ctx.frame_rate.fps_denominator); 10683 m_perf_control.request_cores(frm_int); 10684 /* We need to report the difference between this FBD and the previous FBD 10685 * back to the driver for clock scaling purposes. */ 10686 struct v4l2_outputparm oparm; 10687 /*XXX: we're providing timing info as seconds per frame rather than frames 10688 * per second.*/ 10689 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; 10690 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; 10691 10692 struct v4l2_streamparm sparm; 10693 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 10694 sparm.parm.output = oparm; 10695 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) { 10696 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ 10697 performance might be affected"); 10698 } 10699 10700 } 10701 } 10702 } 10703 prev_ts = act_timestamp; 10704} 10705 10706void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) 10707{ 10708 if (rst_prev_ts && VALID_TS(act_timestamp)) { 10709 prev_ts = act_timestamp; 10710 prev_ts_actual = act_timestamp; 10711 rst_prev_ts = false; 10712 } else if (VALID_TS(prev_ts)) { 10713 bool codec_cond = (drv_ctx.timestamp_adjust)? 10714 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) : 10715 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual); 10716 prev_ts_actual = act_timestamp; //unadjusted previous timestamp 10717 if (frm_int > 0 && codec_cond) { 10718 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); 10719 act_timestamp = prev_ts + frm_int; 10720 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); 10721 prev_ts = act_timestamp; 10722 } else { 10723 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) { 10724 // ensure that timestamps can never step backwards when in display order 10725 act_timestamp = prev_ts; 10726 } 10727 set_frame_rate(act_timestamp); 10728 } 10729 } else if (frm_int > 0) // In this case the frame rate was set along 10730 { // with the port definition, start ts with 0 10731 act_timestamp = prev_ts = 0; // and correct if a valid ts is received. 10732 rst_prev_ts = true; 10733 } 10734} 10735 10736OMX_BUFFERHEADERTYPE* omx_vdec::get_omx_output_buffer_header(int index) 10737{ 10738 return m_out_mem_ptr + index; 10739} 10740 10741void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range, 10742 OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects) 10743{ 10744 switch (primaries) { 10745 case MSM_VIDC_BT709_5: 10746 *color_space = ITU_R_709; 10747 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 10748 break; 10749 case MSM_VIDC_BT470_6_M: 10750 aspects->mPrimaries = ColorAspects::PrimariesBT470_6M; 10751 break; 10752 case MSM_VIDC_BT601_6_625: 10753 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 10754 break; 10755 case MSM_VIDC_BT601_6_525: 10756 *color_space = range ? ITU_R_601_FR : ITU_R_601; 10757 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525; 10758 break; 10759 case MSM_VIDC_GENERIC_FILM: 10760 aspects->mPrimaries = ColorAspects::PrimariesGenericFilm; 10761 break; 10762 case MSM_VIDC_BT2020: 10763 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 10764 break; 10765 case MSM_VIDC_UNSPECIFIED: 10766 //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default 10767 default: 10768 //aspects->mPrimaries = ColorAspects::PrimariesOther; 10769 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10770 break; 10771 } 10772 10773 aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited; 10774 10775 switch (transfer) { 10776 case MSM_VIDC_TRANSFER_BT709_5: 10777 case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625: 10778 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10779 break; 10780 case MSM_VIDC_TRANSFER_BT_470_6_M: 10781 aspects->mTransfer = ColorAspects::TransferGamma22; 10782 break; 10783 case MSM_VIDC_TRANSFER_BT_470_6_BG: 10784 aspects->mTransfer = ColorAspects::TransferGamma28; 10785 break; 10786 case MSM_VIDC_TRANSFER_SMPTE_240M: 10787 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 10788 break; 10789 case MSM_VIDC_TRANSFER_LINEAR: 10790 aspects->mTransfer = ColorAspects::TransferLinear; 10791 break; 10792 case MSM_VIDC_TRANSFER_IEC_61966: 10793 aspects->mTransfer = ColorAspects::TransferXvYCC; 10794 break; 10795 case MSM_VIDC_TRANSFER_BT_1361: 10796 aspects->mTransfer = ColorAspects::TransferBT1361; 10797 break; 10798 case MSM_VIDC_TRANSFER_SRGB: 10799 aspects->mTransfer = ColorAspects::TransferSRGB; 10800 break; 10801 default: 10802 //aspects->mTransfer = ColorAspects::TransferOther; 10803 aspects->mTransfer = m_client_color_space.sAspects.mTransfer; 10804 break; 10805 } 10806 10807 switch (matrix) { 10808 case MSM_VIDC_MATRIX_BT_709_5: 10809 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10810 break; 10811 case MSM_VIDC_MATRIX_FCC_47: 10812 aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M; 10813 break; 10814 case MSM_VIDC_MATRIX_601_6_625: 10815 case MSM_VIDC_MATRIX_601_6_525: 10816 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 10817 break; 10818 case MSM_VIDC_MATRIX_SMPTE_240M: 10819 aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M; 10820 break; 10821 case MSM_VIDC_MATRIX_BT_2020: 10822 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 10823 break; 10824 case MSM_VIDC_MATRIX_BT_2020_CONST: 10825 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant; 10826 break; 10827 default: 10828 //aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 10829 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 10830 break; 10831 } 10832} 10833 10834void omx_vdec::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) { 10835 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d", 10836 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs); 10837} 10838 10839void omx_vdec::prepare_color_aspects_metadata(OMX_U32 primaries, OMX_U32 range, 10840 OMX_U32 transfer, OMX_U32 matrix, 10841 ColorMetaData *color_mdata) 10842{ 10843 10844 /* ColorAspects in qdMetaData */ 10845 color_mdata->colorPrimaries = (enum ColorPrimaries) primaries; 10846 color_mdata->range = (enum ColorRange)range; 10847 color_mdata->transfer = (enum GammaTransfer)transfer; 10848 color_mdata->matrixCoefficients = (enum MatrixCoEfficients)matrix; 10849} 10850 10851bool omx_vdec::handle_color_space_info(void *data, 10852 ColorSpace_t *color_space, 10853 ColorMetaData *color_mdata, 10854 bool& set_color_aspects_only) 10855{ 10856 ColorAspects tempAspects; 10857 memset(&tempAspects, 0x0, sizeof(ColorAspects)); 10858 ColorAspects *aspects = &tempAspects; 10859 10860 /* Set default ColorAspects */ 10861 prepare_color_aspects_metadata(ColorPrimaries_BT601_6_625, Range_Full, 10862 Transfer_SMPTE_170M, MatrixCoEff_BT601_6_625, 10863 color_mdata); 10864 10865 switch(output_capability) { 10866 case V4L2_PIX_FMT_MPEG2: 10867 { 10868 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload; 10869 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data; 10870 10871 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to 10872 * understand this code */ 10873 10874 if (seqdisp_payload && seqdisp_payload->color_descp) { 10875 10876 convert_color_space_info(seqdisp_payload->color_primaries, 1, 10877 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs, 10878 color_space,aspects); 10879 m_disp_hor_size = seqdisp_payload->disp_width; 10880 m_disp_vert_size = seqdisp_payload->disp_height; 10881 set_color_aspects_only = true; 10882 prepare_color_aspects_metadata(seqdisp_payload->color_primaries, 1, 10883 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs, 10884 color_mdata); 10885 } 10886 } 10887 break; 10888 case V4L2_PIX_FMT_H264: 10889 case V4L2_PIX_FMT_HEVC: 10890 { 10891 struct msm_vidc_vui_display_info_payload *display_info_payload; 10892 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data; 10893 10894 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */ 10895 10896 if (display_info_payload->video_signal_present_flag && 10897 display_info_payload->color_description_present_flag) { 10898 convert_color_space_info(display_info_payload->color_primaries, 10899 display_info_payload->video_full_range_flag, 10900 display_info_payload->transfer_characteristics, 10901 display_info_payload->matrix_coefficients, 10902 color_space,aspects); 10903 set_color_aspects_only = true; 10904 prepare_color_aspects_metadata(display_info_payload->color_primaries, 10905 display_info_payload->video_full_range_flag, 10906 display_info_payload->transfer_characteristics, 10907 display_info_payload->matrix_coefficients, 10908 color_mdata); 10909 } 10910 } 10911 break; 10912 case V4L2_PIX_FMT_VC1_ANNEX_G: 10913 case V4L2_PIX_FMT_VC1_ANNEX_L: 10914 { 10915 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload; 10916 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data; 10917 10918 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23 10919 * SMPTE 421M to understand this code */ 10920 10921 if (m_enable_android_native_buffers && 10922 vc1_seq_disp_payload->color_primaries) { 10923 10924 convert_color_space_info(vc1_seq_disp_payload->color_primaries, 10925 1, 10926 vc1_seq_disp_payload->transfer_char, 10927 vc1_seq_disp_payload->matrix_coeffs, 10928 color_space,aspects); 10929 set_color_aspects_only = true; 10930 prepare_color_aspects_metadata(vc1_seq_disp_payload->color_primaries, 10931 1, 10932 vc1_seq_disp_payload->transfer_char, 10933 vc1_seq_disp_payload->matrix_coeffs, 10934 color_mdata); 10935 } 10936 } 10937 break; 10938 case V4L2_PIX_FMT_VP8: 10939 { 10940 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 10941 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 10942 set_color_aspects_only = false; 10943 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011 10944 * to understand this code */ 10945 10946 if (vpx_color_space_payload->color_space == 0) { 10947 *color_space = ITU_R_601; 10948 } else { 10949 DEBUG_PRINT_ERROR("Unsupported Color space for VP8"); 10950 break; 10951 } 10952 } 10953 break; 10954 case V4L2_PIX_FMT_VP9: 10955 { 10956 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload; 10957 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data; 10958 set_color_aspects_only = false; 10959 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016 10960 * to understand this code */ 10961 10962 switch(vpx_color_space_payload->color_space) { 10963 case MSM_VIDC_CS_BT_601: 10964 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6; 10965 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10966 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625; 10967 aspects->mRange = m_client_color_space.sAspects.mRange; 10968 break; 10969 case MSM_VIDC_CS_BT_709: 10970 *color_space = ITU_R_709; 10971 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10972 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10973 aspects->mPrimaries = ColorAspects::PrimariesBT709_5; 10974 aspects->mRange = m_client_color_space.sAspects.mRange; 10975 break; 10976 case MSM_VIDC_CS_SMPTE_170: 10977 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 10978 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 10979 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10980 aspects->mRange = m_client_color_space.sAspects.mRange; 10981 break; 10982 case MSM_VIDC_CS_SMPTE_240: 10983 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs; 10984 aspects->mTransfer = ColorAspects::TransferSMPTE240M; 10985 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries; 10986 aspects->mRange = m_client_color_space.sAspects.mRange; 10987 break; 10988 case MSM_VIDC_CS_BT_2020: 10989 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020; 10990 aspects->mTransfer = ColorAspects:: TransferSMPTE170M; 10991 aspects->mPrimaries = ColorAspects::PrimariesBT2020; 10992 aspects->mRange = m_client_color_space.sAspects.mRange; 10993 break; 10994 case MSM_VIDC_CS_RESERVED: 10995 aspects->mMatrixCoeffs = ColorAspects::MatrixOther; 10996 aspects->mTransfer = ColorAspects::TransferOther; 10997 aspects->mPrimaries = ColorAspects::PrimariesOther; 10998 aspects->mRange = m_client_color_space.sAspects.mRange; 10999 break; 11000 case MSM_VIDC_CS_RGB: 11001 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5; 11002 aspects->mTransfer = ColorAspects::TransferSMPTE170M; 11003 aspects->mPrimaries = ColorAspects::PrimariesOther; 11004 aspects->mRange = m_client_color_space.sAspects.mRange; 11005 break; 11006 default: 11007 break; 11008 } 11009 } 11010 break; 11011 default: 11012 break; 11013 } 11014 11015 print_debug_color_aspects(aspects, "Bitstream"); 11016 11017 if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries || 11018 m_internal_color_space.sAspects.mTransfer != aspects->mTransfer || 11019 m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs || 11020 m_internal_color_space.sAspects.mRange != aspects->mRange) { 11021 memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects)); 11022 m_internal_color_space.bDataSpaceChanged = OMX_TRUE; 11023 11024 m_color_mdata.colorPrimaries = color_mdata->colorPrimaries; 11025 m_color_mdata.range = color_mdata->range; 11026 m_color_mdata.transfer = color_mdata->transfer; 11027 m_color_mdata.matrixCoefficients = color_mdata->matrixCoefficients; 11028 11029 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change"); 11030 print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal"); 11031 print_debug_color_aspects(&(m_client_color_space.sAspects), "Client"); 11032 11033 post_event(OMX_CORE_OUTPUT_PORT_INDEX, 11034 OMX_QTIIndexConfigDescribeColorAspects, 11035 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 11036 return true; 11037 } 11038 return false; 11039} 11040 11041void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) { 11042 private_handle_t *private_handle = NULL; 11043 if (buf_index < drv_ctx.op_buf.actualcount && 11044 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 11045 native_buffer[buf_index].privatehandle) { 11046 private_handle = native_buffer[buf_index].privatehandle; 11047 } 11048 if (private_handle) { 11049 setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space); 11050 } 11051} 11052 11053void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix) 11054{ 11055 if (!hdr_info->mID) { 11056 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix, 11057 hdr_info->sType1.mR.x, hdr_info->sType1.mR.y); 11058 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix, 11059 hdr_info->sType1.mG.x, hdr_info->sType1.mG.y); 11060 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix, 11061 hdr_info->sType1.mB.x, hdr_info->sType1.mB.y); 11062 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix, 11063 hdr_info->sType1.mW.x, hdr_info->sType1.mW.y); 11064 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix, 11065 hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance); 11066 DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix, 11067 hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel); 11068 } 11069 11070} 11071 11072void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata) 11073{ 11074 DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u", 11075 color_mdata->colorPrimaries, color_mdata->range, 11076 color_mdata->transfer, color_mdata->matrixCoefficients); 11077 11078 for(uint8_t i = 0; i < 3; i++) { 11079 for(uint8_t j = 0; j < 2; j++) { 11080 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]); 11081 } 11082 } 11083 11084 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d", 11085 color_mdata->masteringDisplayInfo.primaries.whitePoint[0], 11086 color_mdata->masteringDisplayInfo.primaries.whitePoint[1]); 11087 11088 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d", 11089 color_mdata->masteringDisplayInfo.maxDisplayLuminance, 11090 color_mdata->masteringDisplayInfo.minDisplayLuminance); 11091 11092 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d", 11093 color_mdata->contentLightLevel.maxContentLightLevel, 11094 color_mdata->contentLightLevel.minPicAverageLightLevel); 11095 11096 11097} 11098 11099bool omx_vdec::handle_content_light_level_info(void* data, ContentLightLevel* light_level_mdata) 11100{ 11101 struct msm_vidc_content_light_level_sei_payload *light_level_payload = 11102 (msm_vidc_content_light_level_sei_payload*)(data); 11103 11104 light_level_mdata->lightLevelSEIEnabled = true; 11105 light_level_mdata->maxContentLightLevel = light_level_payload->nMaxContentLight; 11106 light_level_mdata->minPicAverageLightLevel = light_level_payload->nMaxPicAverageLight; 11107 11108 if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) || 11109 (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) { 11110 m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight; 11111 m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight; 11112 return true; 11113 } 11114 return false; 11115} 11116 11117bool omx_vdec::handle_mastering_display_color_info(void* data, MasteringDisplay* mastering_display_mdata) 11118{ 11119 struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload = 11120 (msm_vidc_mastering_display_colour_sei_payload*)(data); 11121 HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo; 11122 bool internal_disp_changed_flag = false; 11123 11124 mastering_display_mdata->colorVolumeSEIEnabled = true; 11125 for (uint8_t i = 0; i < 3; i++) { 11126 mastering_display_mdata->primaries.rgbPrimaries[i][0] = mastering_display_payload->nDisplayPrimariesX[i]; 11127 mastering_display_mdata->primaries.rgbPrimaries[i][1] = mastering_display_payload->nDisplayPrimariesY[i]; 11128 } 11129 mastering_display_mdata->primaries.whitePoint[0] = mastering_display_payload->nWhitePointX; 11130 mastering_display_mdata->primaries.whitePoint[1] = mastering_display_payload->nWhitePointY; 11131 mastering_display_mdata->maxDisplayLuminance = mastering_display_payload->nMaxDisplayMasteringLuminance; 11132 mastering_display_mdata->minDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance; 11133 11134 internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[0]) || 11135 (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[0]); 11136 internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[1]) || 11137 (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[1]); 11138 internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[2]) || 11139 (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[2]); 11140 11141 internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) || 11142 (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY); 11143 11144 /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension 11145 requires it in cd/m2, so dividing by 10000 and rounding the value after division 11146 */ 11147 uint16_t max_display_luminance_cd_m2 = 11148 static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5); 11149 internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) || 11150 (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance); 11151 11152 if (internal_disp_changed_flag) { 11153 hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[0]; 11154 hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[0]; 11155 hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[1]; 11156 hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[1]; 11157 hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[2]; 11158 hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[2]; 11159 hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX; 11160 hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY; 11161 11162 hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2; 11163 hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance; 11164 } 11165 11166 return internal_disp_changed_flag; 11167} 11168 11169void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index) 11170{ 11171 private_handle_t *private_handle = NULL; 11172 if (buf_index < drv_ctx.op_buf.actualcount && 11173 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && 11174 native_buffer[buf_index].privatehandle) { 11175 private_handle = native_buffer[buf_index].privatehandle; 11176 } 11177 if (private_handle) { 11178 setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata); 11179 } 11180} 11181 11182void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) 11183{ 11184 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL; 11185 OMX_U8 *pBuffer = NULL; 11186 OMX_U32 num_conceal_MB = 0; 11187 OMX_TICKS time_stamp = 0; 11188 OMX_U32 frame_rate = 0; 11189 unsigned long consumed_len = 0; 11190 OMX_U32 num_MB_in_frame; 11191 OMX_U32 recovery_sei_flags = 1; 11192 int enable = OMX_InterlaceFrameProgressive; 11193 bool internal_hdr_info_changed_flag = false; 11194 bool color_event = false; 11195 ColorMetaData color_mdata; 11196 memset(&color_mdata, 0x0, sizeof(ColorMetaData)); 11197 bool set_disp_color_aspects_only = false; 11198 ColorSpace_t color_space = ITU_R_601; 11199 11200 int buf_index = p_buf_hdr - m_out_mem_ptr; 11201 if (buf_index >= drv_ctx.extradata_info.count) { 11202 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)", 11203 buf_index, drv_ctx.extradata_info.count); 11204 return; 11205 } 11206 struct msm_vidc_panscan_window_payload *panscan_payload = NULL; 11207 11208 if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) { 11209 DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL"); 11210 return; 11211 } 11212 11213 if (!drv_ctx.extradata_info.uaddr) { 11214 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr"); 11215 return; 11216 } 11217 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) { 11218 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data"); 11219 p_extra = NULL; 11220 return; 11221 } 11222 if (!secure_mode) { 11223 pBuffer = (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len, 11224 PROT_READ|PROT_WRITE, MAP_SHARED, drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0); 11225 if (pBuffer == MAP_FAILED) { 11226 DEBUG_PRINT_ERROR("handle_extradata output buffer mmap failed - errno: %d", errno); 11227 return; 11228 } 11229 p_extra = (OMX_OTHER_EXTRADATATYPE *) 11230 ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); 11231 } else 11232 p_extra = m_other_extradata; 11233 11234 AutoUnmap autounmap(pBuffer, drv_ctx.ptr_outputbuffer[buf_index].buffer_len); 11235 if (m_client_extradata_info.getBase() && 11236 m_client_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) { 11237 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (m_client_extradata_info.getBase() + 11238 buf_index * m_client_extradata_info.getSize()); 11239 } 11240 11241 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; 11242 11243 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 11244 p_extra = NULL; 11245 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 11246 return; 11247 } 11248 m_extradata_info.output_crop_updated = OMX_FALSE; 11249 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; 11250 if (data && p_extra) { 11251 while ((consumed_len < drv_ctx.extradata_info.buffer_size) 11252 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) { 11253 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) { 11254 DEBUG_PRINT_LOW("Invalid extra data size"); 11255 break; 11256 } 11257 11258 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { 11259 p_extra = NULL; 11260 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra"); 11261 return; 11262 } 11263 11264 DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType); 11265 switch ((unsigned long)data->eType) { 11266 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO: 11267 struct msm_vidc_interlace_payload *payload; 11268 OMX_U32 interlace_color_format; 11269 payload = (struct msm_vidc_interlace_payload *)(void *)data->data; 11270 if (payload) { 11271 enable = OMX_InterlaceFrameProgressive; 11272 switch (payload->format) { 11273 case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE: 11274 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11275 break; 11276 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST: 11277 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 11278 enable = OMX_InterlaceInterleaveFrameTopFieldFirst; 11279 break; 11280 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST: 11281 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst; 11282 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst; 11283 break; 11284 default: 11285 DEBUG_PRINT_LOW("default case - set to progressive"); 11286 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11287 } 11288 switch (payload->color_format) { 11289 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12: 11290 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11291 break; 11292 case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC: 11293 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 11294 break; 11295 default: 11296 interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 11297 DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame"); 11298 } 11299 } 11300 11301 if (m_enable_android_native_buffers) { 11302 DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d", 11303 payload->format, interlace_color_format ,enable, 11304 (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false); 11305 11306 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11307 PP_PARAM_INTERLACED, (void*)&enable); 11308 11309 if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 11310 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11311 LINEAR_FORMAT, (void*)&interlace_color_format); 11312 } else if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) { 11313 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 11314 LINEAR_FORMAT, NULL); 11315 } 11316 } 11317 if (client_extradata & OMX_INTERLACE_EXTRADATA) { 11318 append_interlace_extradata(p_extra, payload->format); 11319 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11320 if (p_client_extra) { 11321 append_interlace_extradata(p_client_extra, payload->format); 11322 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) 11323 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11324 } 11325 } 11326 break; 11327 case MSM_VIDC_EXTRADATA_FRAME_RATE: 11328 struct msm_vidc_framerate_payload *frame_rate_payload; 11329 frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data; 11330 frame_rate = frame_rate_payload->frame_rate; 11331 break; 11332 case MSM_VIDC_EXTRADATA_TIMESTAMP: 11333 struct msm_vidc_ts_payload *time_stamp_payload; 11334 time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data; 11335 time_stamp = time_stamp_payload->timestamp_lo; 11336 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); 11337 p_buf_hdr->nTimeStamp = time_stamp; 11338 break; 11339 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB: 11340 struct msm_vidc_concealmb_payload *conceal_mb_payload; 11341 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data; 11342 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 11343 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 11344 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); 11345 break; 11346 case MSM_VIDC_EXTRADATA_INDEX: 11347 int *etype; 11348 etype = (int *)(void *)data->data; 11349 if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) { 11350 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; 11351 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype); 11352 if (aspect_ratio_payload) { 11353 ((struct vdec_output_frameinfo *) 11354 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; 11355 ((struct vdec_output_frameinfo *) 11356 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; 11357 } 11358 } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) { 11359 struct msm_vidc_output_crop_payload *output_crop_payload; 11360 output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype); 11361 if (output_crop_payload) { 11362 m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left; 11363 m_extradata_info.output_crop_rect.nTop = output_crop_payload->top; 11364 m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width; 11365 m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height; 11366 m_extradata_info.output_width = output_crop_payload->width; 11367 m_extradata_info.output_height = output_crop_payload->height; 11368 m_extradata_info.output_crop_updated = OMX_TRUE; 11369 } 11370 } 11371 break; 11372 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI: 11373 struct msm_vidc_recoverysei_payload *recovery_sei_payload; 11374 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data; 11375 recovery_sei_flags = recovery_sei_payload->flags; 11376 if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) { 11377 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 11378 DEBUG_PRINT_HIGH("***************************************************"); 11379 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received"); 11380 DEBUG_PRINT_HIGH("***************************************************"); 11381 } 11382 break; 11383 case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW: 11384 panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data; 11385 if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) { 11386 DEBUG_PRINT_ERROR("Panscan windows are more than supported\n"); 11387 DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n", 11388 MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows); 11389 return; 11390 } 11391 break; 11392 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP: 11393 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO: 11394 case MSM_VIDC_EXTRADATA_VC1_SEQDISP: 11395 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO: 11396 color_event = handle_color_space_info((void *)data->data, &color_space, &color_mdata, set_disp_color_aspects_only); 11397 break; 11398 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING: 11399 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload; 11400 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data; 11401 switch (s3d_frame_packing_payload->fpa_type) { 11402 case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE: 11403 if (s3d_frame_packing_payload->content_interprtation_type == 1) 11404 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R; 11405 else if (s3d_frame_packing_payload->content_interprtation_type == 2) 11406 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L; 11407 else { 11408 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type"); 11409 stereo_output_mode = HAL_NO_3D; 11410 } 11411 break; 11412 case MSM_VIDC_FRAMEPACK_TOP_BOTTOM: 11413 stereo_output_mode = HAL_3D_TOP_BOTTOM; 11414 break; 11415 default: 11416 DEBUG_PRINT_ERROR("Unsupported framepacking type"); 11417 stereo_output_mode = HAL_NO_3D; 11418 } 11419 DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d", 11420 s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode); 11421 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) { 11422 append_framepack_extradata(p_extra, s3d_frame_packing_payload); 11423 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11424 if (p_client_extra) { 11425 append_framepack_extradata(p_client_extra, s3d_frame_packing_payload); 11426 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11427 } 11428 } 11429 break; 11430 case MSM_VIDC_EXTRADATA_FRAME_QP: 11431 struct msm_vidc_frame_qp_payload *qp_payload; 11432 qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data; 11433 if (client_extradata & OMX_QP_EXTRADATA) { 11434 append_qp_extradata(p_extra, qp_payload); 11435 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11436 if (p_client_extra) { 11437 append_qp_extradata(p_client_extra, qp_payload); 11438 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11439 } 11440 } 11441 break; 11442 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO: 11443 struct msm_vidc_frame_bits_info_payload *bits_info_payload; 11444 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data; 11445 if (client_extradata & OMX_BITSINFO_EXTRADATA) { 11446 append_bitsinfo_extradata(p_extra, bits_info_payload); 11447 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11448 if (p_client_extra) { 11449 append_bitsinfo_extradata(p_client_extra, bits_info_payload); 11450 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11451 } 11452 } 11453 break; 11454 case MSM_VIDC_EXTRADATA_STREAM_USERDATA: 11455 if (client_extradata & OMX_EXTNUSER_EXTRADATA) { 11456 append_user_extradata(p_extra, data); 11457 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11458 if (p_client_extra) { 11459 append_user_extradata(p_client_extra, data); 11460 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11461 } 11462 } 11463 break; 11464 case MSM_VIDC_EXTRADATA_VQZIP_SEI: 11465 struct msm_vidc_vqzip_sei_payload *vqzip_payload; 11466 vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data; 11467 if (client_extradata & OMX_VQZIPSEI_EXTRADATA) { 11468 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11469 append_vqzip_extradata(p_extra, vqzip_payload); 11470 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11471 if (p_client_extra) { 11472 append_vqzip_extradata(p_client_extra, vqzip_payload); 11473 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11474 } 11475 } 11476 break; 11477 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: 11478 11479 internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data, 11480 &(color_mdata.contentLightLevel)); 11481 break; 11482 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI: 11483 internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data, 11484 &(color_mdata.masteringDisplayInfo)); 11485 break; 11486 default: 11487 DEBUG_PRINT_LOW("Unrecognized extradata"); 11488 goto unrecognized_extradata; 11489 } 11490 consumed_len += data->nSize; 11491 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 11492 } 11493 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) { 11494 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11495 append_frame_info_extradata(p_extra, 11496 num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 11497 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *) 11498 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 11499 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11500 if (p_client_extra) { 11501 append_frame_info_extradata(p_client_extra, 11502 num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 11503 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *) 11504 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 11505 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11506 } 11507 } 11508 if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) { 11509 append_frame_dimension_extradata(p_extra); 11510 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4)); 11511 if (p_client_extra) { 11512 append_frame_dimension_extradata(p_client_extra); 11513 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4)); 11514 } 11515 } 11516 11517 if(internal_hdr_info_changed_flag) { 11518 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal"); 11519 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client"); 11520 memcpy(&m_color_mdata, &color_mdata, sizeof(ColorMetaData)); 11521 auto_lock lock(m_hdr_info_client_lock); 11522 m_change_client_hdr_info = true; 11523 if(!color_event) { 11524 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change"); 11525 post_event(OMX_CORE_OUTPUT_PORT_INDEX, 11526 OMX_QTIIndexConfigDescribeHDRColorInfo, 11527 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 11528 } 11529 } 11530 11531 if (m_enable_android_native_buffers) { 11532 if (set_disp_color_aspects_only) { 11533 print_debug_hdr_color_info_mdata(&m_color_mdata); 11534 set_colormetadata_in_handle(&m_color_mdata, buf_index); 11535 } else { 11536 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); 11537 set_colorspace_in_handle(color_space, buf_index); 11538 } 11539 } 11540 11541 } 11542unrecognized_extradata: 11543 if (client_extradata && p_extra) { 11544 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 11545 append_terminator_extradata(p_extra); 11546 if (p_client_extra) { 11547 append_terminator_extradata(p_client_extra); 11548 } 11549 } 11550 if (secure_mode && p_extradata && m_other_extradata) { 11551 struct vdec_output_frameinfo *ptr_extradatabuff = NULL; 11552 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size); 11553 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate; 11554 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata; 11555 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size; 11556 ptr_extradatabuff->metadata_info.fd = drv_ctx.extradata_info.ion.fd_ion_data.fd; 11557 ptr_extradatabuff->metadata_info.offset = buf_index * drv_ctx.extradata_info.buffer_size; 11558 ptr_extradatabuff->metadata_info.buffer_size = drv_ctx.extradata_info.size; 11559 } 11560 return; 11561} 11562 11563OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata, 11564 bool is_internal, bool enable) 11565{ 11566 OMX_ERRORTYPE ret = OMX_ErrorNone; 11567 struct v4l2_control control; 11568 if (m_state != OMX_StateLoaded) { 11569 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); 11570 return OMX_ErrorIncorrectStateOperation; 11571 } 11572 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d", 11573 (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal); 11574 11575 if (!is_internal) { 11576 if (enable) 11577 client_extradata |= requested_extradata; 11578 else 11579 client_extradata = client_extradata & ~requested_extradata; 11580 } 11581 11582 if (enable) { 11583 if (requested_extradata & OMX_INTERLACE_EXTRADATA) { 11584 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11585 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; 11586 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11587 DEBUG_PRINT_HIGH("Failed to set interlaced extradata." 11588 " Quality of interlaced clips might be impacted."); 11589 } 11590 } 11591 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) { 11592 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11593 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; 11594 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11595 DEBUG_PRINT_HIGH("Failed to set framerate extradata"); 11596 } 11597 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11598 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; 11599 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11600 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata"); 11601 } 11602 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11603 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; 11604 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11605 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata"); 11606 } 11607 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11608 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; 11609 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11610 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11611 } 11612 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11613 control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO; 11614 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11615 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11616 } 11617 if (output_capability == V4L2_PIX_FMT_MPEG2) { 11618 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11619 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 11620 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11621 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 11622 } 11623 } 11624 } 11625 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) { 11626 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11627 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; 11628 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11629 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata"); 11630 } 11631 } 11632 if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) { 11633 if (output_capability == V4L2_PIX_FMT_H264) { 11634 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA"); 11635 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11636 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING; 11637 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11638 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata"); 11639 } 11640 } else { 11641 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only"); 11642 } 11643 } 11644 if (requested_extradata & OMX_QP_EXTRADATA) { 11645 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11646 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 11647 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11648 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 11649 } 11650 } 11651 if (requested_extradata & OMX_BITSINFO_EXTRADATA) { 11652 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11653 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO; 11654 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11655 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata"); 11656 } 11657 } 11658 if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) { 11659 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11660 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA; 11661 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11662 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata"); 11663 } 11664 } 11665 if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) { 11666 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11667 control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI; 11668 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11669 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata"); 11670 } 11671 client_extradata |= OMX_VQZIPSEI_EXTRADATA; 11672 11673 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11674 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP; 11675 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11676 DEBUG_PRINT_HIGH("Failed to set QP extradata"); 11677 } 11678 client_extradata |= OMX_QP_EXTRADATA; 11679 } 11680 if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) { 11681 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11682 control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP; 11683 DEBUG_PRINT_LOW("Enable output crop extra data"); 11684 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11685 DEBUG_PRINT_HIGH("Failed to set output crop extradata"); 11686 } 11687 } 11688 if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) { 11689 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11690 switch(output_capability) { 11691 case V4L2_PIX_FMT_H264: 11692 case V4L2_PIX_FMT_HEVC: 11693 control.value = V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY; 11694 break; 11695 case CODEC_TYPE_MPEG2: 11696 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; 11697 break; 11698 case V4L2_PIX_FMT_VP8: 11699 case V4L2_PIX_FMT_VP9: 11700 control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE; 11701 break; 11702 case V4L2_PIX_FMT_VC1_ANNEX_G: 11703 case V4L2_PIX_FMT_VC1_ANNEX_L: 11704 control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP; 11705 break; 11706 default: 11707 DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind); 11708 return ret; 11709 } 11710 11711 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11712 DEBUG_PRINT_HIGH("Failed to set Display info extradata"); 11713 } 11714 } 11715 if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) { 11716 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 11717 if (output_capability == V4L2_PIX_FMT_H264 || 11718 output_capability == V4L2_PIX_FMT_HEVC) { 11719 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI; 11720 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11721 DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata"); 11722 } 11723 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI; 11724 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 11725 DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata"); 11726 } 11727 } 11728 } 11729 } 11730 ret = get_buffer_req(&drv_ctx.op_buf); 11731 return ret; 11732} 11733 11734OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11735{ 11736 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; 11737 OMX_U8 *data_ptr = extra->data, data = 0; 11738 while (byte_count < extra->nDataSize) { 11739 data = *data_ptr; 11740 while (data) { 11741 num_MB += (data&0x01); 11742 data >>= 1; 11743 } 11744 data_ptr++; 11745 byte_count++; 11746 } 11747 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 11748 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 11749 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); 11750} 11751 11752void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11753{ 11754 if (!m_debug_extradata || !extra) 11755 return; 11756 11757 11758 DEBUG_PRINT_HIGH( 11759 "============== Extra Data ==============\n" 11760 " Size: %u\n" 11761 " Version: %u\n" 11762 " PortIndex: %u\n" 11763 " Type: %x\n" 11764 " DataSize: %u", 11765 (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion, 11766 (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize); 11767 11768 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) { 11769 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 11770 DEBUG_PRINT_HIGH( 11771 "------ Interlace Format ------\n" 11772 " Size: %u\n" 11773 " Version: %u\n" 11774 " PortIndex: %u\n" 11775 " Is Interlace Format: %d\n" 11776 " Interlace Formats: %u\n" 11777 "=========== End of Interlace ===========", 11778 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex, 11779 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats); 11780 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) { 11781 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 11782 11783 DEBUG_PRINT_HIGH( 11784 "-------- Frame Format --------\n" 11785 " Picture Type: %d\n" 11786 " Interlace Type: %d\n" 11787 " Pan Scan Total Frame Num: %u\n" 11788 " Concealed Macro Blocks: %u\n" 11789 " Recovery SEI Flag: %u\n" 11790 " frame rate: %u\n" 11791 " Time Stamp: %llu\n" 11792 " Aspect Ratio X: %u\n" 11793 " Aspect Ratio Y: %u", 11794 fminfo->ePicType, 11795 fminfo->interlaceType, 11796 (unsigned int)fminfo->panScan.numWindows, 11797 (unsigned int)fminfo->nConcealedMacroblocks, 11798 (unsigned int)fminfo->nRecoverySeiFlag, 11799 (unsigned int)fminfo->nFrameRate, 11800 fminfo->nTimeStamp, 11801 (unsigned int)fminfo->aspectRatio.aspectRatioX, 11802 (unsigned int)fminfo->aspectRatio.aspectRatioY); 11803 11804 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) { 11805 DEBUG_PRINT_HIGH( 11806 "------------------------------" 11807 " Pan Scan Frame Num: %u\n" 11808 " Rectangle x: %d\n" 11809 " Rectangle y: %d\n" 11810 " Rectangle dx: %d\n" 11811 " Rectangle dy: %d", 11812 (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y, 11813 (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy); 11814 } 11815 11816 DEBUG_PRINT_HIGH("========= End of Frame Format =========="); 11817 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) { 11818 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 11819 DEBUG_PRINT_HIGH( 11820 "------------------ Framepack Format ----------\n" 11821 " id: %u \n" 11822 " cancel_flag: %u \n" 11823 " type: %u \n" 11824 " quincunx_sampling_flagFormat: %u \n" 11825 " content_interpretation_type: %u \n" 11826 " spatial_flipping_flag: %u \n" 11827 " frame0_flipped_flag: %u \n" 11828 " field_views_flag: %u \n" 11829 " current_frame_is_frame0_flag: %u \n" 11830 " frame0_self_contained_flag: %u \n" 11831 " frame1_self_contained_flag: %u \n" 11832 " frame0_grid_position_x: %u \n" 11833 " frame0_grid_position_y: %u \n" 11834 " frame1_grid_position_x: %u \n" 11835 " frame1_grid_position_y: %u \n" 11836 " reserved_byte: %u \n" 11837 " repetition_period: %u \n" 11838 " extension_flag: %u \n" 11839 "================== End of Framepack ===========", 11840 (unsigned int)framepack->id, 11841 (unsigned int)framepack->cancel_flag, 11842 (unsigned int)framepack->type, 11843 (unsigned int)framepack->quincunx_sampling_flag, 11844 (unsigned int)framepack->content_interpretation_type, 11845 (unsigned int)framepack->spatial_flipping_flag, 11846 (unsigned int)framepack->frame0_flipped_flag, 11847 (unsigned int)framepack->field_views_flag, 11848 (unsigned int)framepack->current_frame_is_frame0_flag, 11849 (unsigned int)framepack->frame0_self_contained_flag, 11850 (unsigned int)framepack->frame1_self_contained_flag, 11851 (unsigned int)framepack->frame0_grid_position_x, 11852 (unsigned int)framepack->frame0_grid_position_y, 11853 (unsigned int)framepack->frame1_grid_position_x, 11854 (unsigned int)framepack->frame1_grid_position_y, 11855 (unsigned int)framepack->reserved_byte, 11856 (unsigned int)framepack->repetition_period, 11857 (unsigned int)framepack->extension_flag); 11858 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) { 11859 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 11860 DEBUG_PRINT_HIGH( 11861 "---- QP (Frame quantization parameter) ----\n" 11862 " Frame QP: %u \n" 11863 "================ End of QP ================\n", 11864 (unsigned int)qp->nQP); 11865 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) { 11866 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data; 11867 DEBUG_PRINT_HIGH( 11868 "--------- Input bits information --------\n" 11869 " Header bits: %u \n" 11870 " Frame bits: %u \n" 11871 "===== End of Input bits information =====\n", 11872 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits); 11873 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) { 11874 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data; 11875 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data; 11876 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type); 11877 OMX_U32 i = 0; 11878 DEBUG_PRINT_HIGH( 11879 "-------------- Userdata -------------\n" 11880 " Stream userdata type: %u\n" 11881 " userdata size: %u\n" 11882 " STREAM_USERDATA:", 11883 (unsigned int)userdata->type, (unsigned int)userdata_size); 11884 for (i = 0; i < userdata_size; i+=4) { 11885 DEBUG_PRINT_HIGH(" %x %x %x %x", 11886 data_ptr[i], data_ptr[i+1], 11887 data_ptr[i+2], data_ptr[i+3]); 11888 } 11889 DEBUG_PRINT_HIGH( 11890 "=========== End of Userdata ==========="); 11891 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) { 11892 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 11893 DEBUG_PRINT_HIGH( 11894 "-------------- VQZip -------------\n" 11895 " Size: %u\n", 11896 (unsigned int)vq->nSize); 11897 DEBUG_PRINT_HIGH( "=========== End of VQZip ==========="); 11898 } else if (extra->eType == OMX_ExtraDataNone) { 11899 DEBUG_PRINT_HIGH("========== End of Terminator ==========="); 11900 } else { 11901 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); 11902 } 11903} 11904 11905void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11906 OMX_U32 interlaced_format_type) 11907{ 11908 OMX_STREAMINTERLACEFORMAT *interlace_format; 11909 11910 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { 11911 return; 11912 } 11913 if (!extra) { 11914 DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input"); 11915 return; 11916 } 11917 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; 11918 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11919 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11920 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; 11921 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); 11922 interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data; 11923 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); 11924 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; 11925 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11926 11927 if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) { 11928 interlace_format->bInterlaceFormat = OMX_FALSE; 11929 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 11930 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11931 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) { 11932 interlace_format->bInterlaceFormat = OMX_TRUE; 11933 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 11934 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 11935 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) { 11936 interlace_format->bInterlaceFormat = OMX_TRUE; 11937 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst; 11938 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst; 11939 } else { 11940 //default case - set to progressive 11941 interlace_format->bInterlaceFormat = OMX_FALSE; 11942 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 11943 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 11944 } 11945 print_debug_extradata(extra); 11946} 11947 11948void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra) 11949{ 11950 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension; 11951 if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) { 11952 return; 11953 } 11954 extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE; 11955 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11956 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11957 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension; 11958 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION); 11959 frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data; 11960 frame_dimension->nDecWidth = rectangle.nLeft; 11961 frame_dimension->nDecHeight = rectangle.nTop; 11962 frame_dimension->nActualWidth = rectangle.nWidth; 11963 frame_dimension->nActualHeight = rectangle.nHeight; 11964} 11965 11966void omx_vdec::fill_aspect_ratio_info( 11967 struct vdec_aspectratioinfo *aspect_ratio_info, 11968 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 11969{ 11970 m_extradata = frame_info; 11971 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; 11972 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; 11973 DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX, 11974 (unsigned int)m_extradata->aspectRatio.aspectRatioY); 11975} 11976 11977void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, 11978 OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate, 11979 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload, 11980 struct vdec_aspectratioinfo *aspect_ratio_info) 11981{ 11982 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; 11983 struct msm_vidc_panscan_window *panscan_window; 11984 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { 11985 return; 11986 } 11987 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; 11988 extra->nVersion.nVersion = OMX_SPEC_VERSION; 11989 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 11990 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; 11991 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); 11992 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data; 11993 switch (picture_type) { 11994 case PICTURE_TYPE_I: 11995 frame_info->ePicType = OMX_VIDEO_PictureTypeI; 11996 break; 11997 case PICTURE_TYPE_P: 11998 frame_info->ePicType = OMX_VIDEO_PictureTypeP; 11999 break; 12000 case PICTURE_TYPE_B: 12001 frame_info->ePicType = OMX_VIDEO_PictureTypeB; 12002 break; 12003 default: 12004 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; 12005 } 12006 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 12007 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 12008 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 12009 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 12010 else 12011 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; 12012 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); 12013 frame_info->nConcealedMacroblocks = num_conceal_mb; 12014 frame_info->nRecoverySeiFlag = recovery_sei_flag; 12015 frame_info->nFrameRate = frame_rate; 12016 frame_info->nTimeStamp = time_stamp; 12017 frame_info->panScan.numWindows = 0; 12018 if (output_capability == V4L2_PIX_FMT_MPEG2) { 12019 if (m_disp_hor_size && m_disp_vert_size) { 12020 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; 12021 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; 12022 } else { 12023 frame_info->displayAspectRatio.displayHorizontalSize = 0; 12024 frame_info->displayAspectRatio.displayVerticalSize = 0; 12025 } 12026 } 12027 12028 if (panscan_payload) { 12029 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; 12030 panscan_window = &panscan_payload->wnd[0]; 12031 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) { 12032 frame_info->panScan.window[i].x = panscan_window->panscan_window_width; 12033 frame_info->panScan.window[i].y = panscan_window->panscan_window_height; 12034 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; 12035 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; 12036 panscan_window++; 12037 } 12038 } 12039 fill_aspect_ratio_info(aspect_ratio_info, frame_info); 12040 print_debug_extradata(extra); 12041} 12042 12043void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12044{ 12045 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; 12046 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; 12047 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12048 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12049 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; 12050 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 12051 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data; 12052 *portDefn = m_port_def; 12053 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u " 12054 "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight, 12055 (unsigned int)portDefn->format.video.nFrameWidth, 12056 (unsigned int)portDefn->format.video.nStride, 12057 (unsigned int)portDefn->format.video.nSliceHeight); 12058} 12059 12060void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12061 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload) 12062{ 12063 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack; 12064 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) { 12065 DEBUG_PRINT_ERROR("frame packing size mismatch"); 12066 return; 12067 } 12068 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE; 12069 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12070 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12071 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement; 12072 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 12073 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data; 12074 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT); 12075 framepack->nVersion.nVersion = OMX_SPEC_VERSION; 12076 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12077 memcpy(&framepack->id, s3d_frame_packing_payload, 12078 sizeof(struct msm_vidc_s3d_frame_packing_payload)); 12079 memcpy(&m_frame_pack_arrangement, framepack, 12080 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT)); 12081 print_debug_extradata(extra); 12082} 12083 12084void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12085 struct msm_vidc_frame_qp_payload *qp_payload) 12086{ 12087 OMX_QCOM_EXTRADATA_QP * qp = NULL; 12088 if (!qp_payload) { 12089 DEBUG_PRINT_ERROR("QP payload is NULL"); 12090 return; 12091 } 12092 extra->nSize = OMX_QP_EXTRADATA_SIZE; 12093 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12094 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12095 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP; 12096 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP); 12097 qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data; 12098 qp->nQP = qp_payload->frame_qp; 12099 print_debug_extradata(extra); 12100} 12101 12102void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12103 struct msm_vidc_frame_bits_info_payload *bits_payload) 12104{ 12105 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL; 12106 if (!bits_payload) { 12107 DEBUG_PRINT_ERROR("bits info payload is NULL"); 12108 return; 12109 } 12110 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE; 12111 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12112 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12113 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo; 12114 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO); 12115 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data; 12116 bits->frame_bits = bits_payload->frame_bits; 12117 bits->header_bits = bits_payload->header_bits; 12118 print_debug_extradata(extra); 12119} 12120 12121void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12122 OMX_OTHER_EXTRADATATYPE *p_user) 12123{ 12124 int userdata_size = 0; 12125 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL; 12126 userdata_payload = 12127 (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data; 12128 userdata_size = p_user->nDataSize; 12129 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size; 12130 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12131 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12132 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData; 12133 extra->nDataSize = userdata_size; 12134 if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize)) 12135 memcpy(extra->data, p_user->data, extra->nDataSize); 12136 print_debug_extradata(extra); 12137} 12138 12139void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) 12140{ 12141 if (!client_extradata) { 12142 return; 12143 } 12144 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 12145 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12146 extra->eType = OMX_ExtraDataNone; 12147 extra->nDataSize = 0; 12148 extra->data[0] = 0; 12149 12150 print_debug_extradata(extra); 12151} 12152 12153void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra, 12154 struct msm_vidc_vqzip_sei_payload *vqzip_payload) 12155{ 12156 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL; 12157 12158 extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size; 12159 extra->nVersion.nVersion = OMX_SPEC_VERSION; 12160 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12161 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI; 12162 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size; 12163 12164 vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data; 12165 vq->nSize = vqzip_payload->size; 12166 memcpy(vq->data, vqzip_payload->data, vqzip_payload->size); 12167 12168 print_debug_extradata(extra); 12169} 12170 12171OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) 12172{ 12173 OMX_ERRORTYPE eRet = OMX_ErrorNone; 12174 if (index >= drv_ctx.ip_buf.actualcount) { 12175 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found"); 12176 return OMX_ErrorInsufficientResources; 12177 } 12178 if (m_desc_buffer_ptr == NULL) { 12179 m_desc_buffer_ptr = (desc_buffer_hdr*) \ 12180 calloc( (sizeof(desc_buffer_hdr)), 12181 drv_ctx.ip_buf.actualcount); 12182 if (m_desc_buffer_ptr == NULL) { 12183 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed "); 12184 return OMX_ErrorInsufficientResources; 12185 } 12186 } 12187 12188 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); 12189 if (m_desc_buffer_ptr[index].buf_addr == NULL) { 12190 DEBUG_PRINT_ERROR("desc buffer Allocation failed "); 12191 return OMX_ErrorInsufficientResources; 12192 } 12193 12194 return eRet; 12195} 12196 12197void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) 12198{ 12199 DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries); 12200 if (m_demux_entries < 8192) { 12201 m_demux_offsets[m_demux_entries++] = address_offset; 12202 } 12203 return; 12204} 12205 12206void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) 12207{ 12208 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; 12209 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; 12210 OMX_U32 index = 0; 12211 12212 m_demux_entries = 0; 12213 12214 while (index < bytes_to_parse) { 12215 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 12216 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || 12217 ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 12218 (buf[index+2] == 0x01)) ) { 12219 //Found start code, insert address offset 12220 insert_demux_addr_offset(index); 12221 if (buf[index+2] == 0x01) // 3 byte start code 12222 index += 3; 12223 else //4 byte start code 12224 index += 4; 12225 } else 12226 index++; 12227 } 12228 DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries); 12229 return; 12230} 12231 12232OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) 12233{ 12234 //fix this, handle 3 byte start code, vc1 terminator entry 12235 OMX_U8 *p_demux_data = NULL; 12236 OMX_U32 desc_data = 0; 12237 OMX_U32 start_addr = 0; 12238 OMX_U32 nal_size = 0; 12239 OMX_U32 suffix_byte = 0; 12240 OMX_U32 demux_index = 0; 12241 OMX_U32 buffer_index = 0; 12242 12243 if (m_desc_buffer_ptr == NULL) { 12244 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); 12245 return OMX_ErrorBadParameter; 12246 } 12247 12248 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 12249 if (buffer_index > drv_ctx.ip_buf.actualcount) { 12250 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index); 12251 return OMX_ErrorBadParameter; 12252 } 12253 12254 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; 12255 12256 if ( ((OMX_U8*)p_demux_data == NULL) || 12257 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) { 12258 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); 12259 return OMX_ErrorBadParameter; 12260 } else { 12261 for (; demux_index < m_demux_entries; demux_index++) { 12262 desc_data = 0; 12263 start_addr = m_demux_offsets[demux_index]; 12264 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) { 12265 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; 12266 } else { 12267 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; 12268 } 12269 if (demux_index < (m_demux_entries - 1)) { 12270 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; 12271 } else { 12272 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; 12273 } 12274 DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)", 12275 (unsigned int)start_addr, 12276 (unsigned int)suffix_byte, 12277 (unsigned int)nal_size, 12278 (unsigned int)demux_index); 12279 desc_data = (start_addr >> 3) << 1; 12280 desc_data |= (start_addr & 7) << 21; 12281 desc_data |= suffix_byte << 24; 12282 12283 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 12284 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); 12285 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 12286 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 12287 12288 p_demux_data += 16; 12289 } 12290 if (codec_type_parse == CODEC_TYPE_VC1) { 12291 DEBUG_PRINT_LOW("VC1 terminator entry"); 12292 desc_data = 0; 12293 desc_data = 0x82 << 24; 12294 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 12295 memset(p_demux_data + 4, 0, sizeof(OMX_U32)); 12296 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 12297 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 12298 p_demux_data += 16; 12299 m_demux_entries++; 12300 } 12301 //Add zero word to indicate end of descriptors 12302 memset(p_demux_data, 0, sizeof(OMX_U32)); 12303 12304 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); 12305 DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size); 12306 } 12307 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 12308 m_demux_entries = 0; 12309 DEBUG_PRINT_LOW("Demux table complete!"); 12310 return OMX_ErrorNone; 12311} 12312 12313void omx_vdec::request_perf_level(enum vidc_perf_level perf_level) 12314{ 12315 struct v4l2_control control; 12316 char property_value[PROPERTY_VALUE_MAX] = {0}; 12317 12318 property_get("vidc.debug.turbo", property_value, "0"); 12319 memset(&control, 0, sizeof(v4l2_control)); 12320 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 12321 switch (perf_level) { 12322 case VIDC_NOMINAL: 12323 if (atoi(property_value)) 12324 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 12325 else 12326 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 12327 break; 12328 case VIDC_TURBO: 12329 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 12330 break; 12331 default: 12332 DEBUG_PRINT_ERROR("Requested PERF level not supported"); 12333 break; 12334 } 12335 if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig) 12336 return; 12337 12338 DEBUG_PRINT_HIGH("changing performance level to %d", control.value); 12339 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 12340 current_perf_level = control.value; 12341 } else { 12342 DEBUG_PRINT_ERROR("Failed to set PERF level"); 12343 } 12344} 12345 12346omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() 12347{ 12348 enabled = false; 12349 omx = NULL; 12350 init_members(); 12351 ColorFormat = OMX_COLOR_FormatMax; 12352 dest_format = YCbCr420P; 12353 m_c2d_width = 0; 12354 m_c2d_height = 0; 12355} 12356 12357void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) 12358{ 12359 omx = reinterpret_cast<omx_vdec*>(client); 12360} 12361 12362void omx_vdec::allocate_color_convert_buf::init_members() 12363{ 12364 allocated_count = 0; 12365 buffer_size_req = 0; 12366 buffer_alignment_req = 0; 12367 m_c2d_width = m_c2d_height = 0; 12368 memset(m_platform_list_client,0,sizeof(m_platform_list_client)); 12369 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); 12370 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); 12371 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); 12372#ifdef USE_ION 12373 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); 12374#endif 12375 for (int i = 0; i < MAX_COUNT; i++) 12376 pmem_fd[i] = -1; 12377} 12378 12379omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() 12380{ 12381 c2d.destroy(); 12382} 12383 12384bool omx_vdec::allocate_color_convert_buf::update_buffer_req() 12385{ 12386 bool status = true; 12387 unsigned int src_size = 0, destination_size = 0; 12388 unsigned int height, width; 12389 struct v4l2_format fmt; 12390 OMX_COLOR_FORMATTYPE drv_color_format; 12391 12392 if (!omx) { 12393 DEBUG_PRINT_ERROR("Invalid client in color convert"); 12394 return false; 12395 } 12396 if (!enabled) { 12397 DEBUG_PRINT_HIGH("No color conversion required"); 12398 return status; 12399 } 12400 pthread_mutex_lock(&omx->c_lock); 12401 12402 memset(&fmt, 0x0, sizeof(struct v4l2_format)); 12403 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 12404 fmt.fmt.pix_mp.pixelformat = omx->capture_capability; 12405 ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 12406 width = fmt.fmt.pix_mp.width; 12407 height = fmt.fmt.pix_mp.height; 12408 12409 bool resolution_upgrade = (height > m_c2d_height || 12410 width > m_c2d_width); 12411 if (resolution_upgrade) { 12412 // resolution upgraded ? ensure we are yet to allocate; 12413 // failing which, c2d buffers will never be reallocated and bad things will happen 12414 if (allocated_count > 0) { 12415 DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations", 12416 allocated_count); 12417 status = false; 12418 goto fail_update_buf_req; 12419 } 12420 } 12421 12422 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && 12423 ColorFormat != OMX_COLOR_FormatYUV420Planar) { 12424 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion"); 12425 status = false; 12426 goto fail_update_buf_req; 12427 } 12428 c2d.close(); 12429 status = c2d.open(height, 12430 width, 12431 NV12_128m,dest_format); 12432 if (status) { 12433 status = c2d.get_buffer_size(C2D_INPUT,src_size); 12434 if (status) 12435 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); 12436 } 12437 if (status) { 12438 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || 12439 !destination_size) { 12440 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d" 12441 "driver size %u destination size %d", 12442 src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size, 12443 destination_size); 12444 status = false; 12445 c2d.close(); 12446 buffer_size_req = 0; 12447 // TODO: make this fatal. Driver is not supposed to quote size 12448 // smaller than what C2D needs !! 12449 } else { 12450 buffer_size_req = destination_size; 12451 m_c2d_height = height; 12452 m_c2d_width = width; 12453 } 12454 } 12455fail_update_buf_req: 12456 pthread_mutex_unlock(&omx->c_lock); 12457 return status; 12458} 12459 12460bool omx_vdec::allocate_color_convert_buf::set_color_format( 12461 OMX_COLOR_FORMATTYPE dest_color_format) 12462{ 12463 bool status = true, drv_colorformat_c2d_enable = false; 12464 bool dest_color_format_c2d_enable = false; 12465 OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused; 12466 if (!omx) { 12467 DEBUG_PRINT_ERROR("Invalid client in color convert"); 12468 return false; 12469 } 12470 pthread_mutex_lock(&omx->c_lock); 12471 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 12472 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 12473 drv_color_format = (OMX_COLOR_FORMATTYPE) 12474 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 12475 else 12476 drv_color_format = (OMX_COLOR_FORMATTYPE) 12477 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 12478 else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) { 12479 drv_color_format = (OMX_COLOR_FORMATTYPE) 12480 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 12481 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) { 12482 drv_color_format = (OMX_COLOR_FORMATTYPE) 12483 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed; 12484 } else { 12485 DEBUG_PRINT_ERROR("Incorrect color format"); 12486 status = false; 12487 } 12488 drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) && 12489 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12490 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) && 12491 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12492 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) && 12493 (drv_color_format != (OMX_COLOR_FORMATTYPE) 12494 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed); 12495 12496 dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE) 12497 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) && 12498 (dest_color_format != (OMX_COLOR_FORMATTYPE) 12499 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed); 12500 12501 if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) { 12502 DEBUG_PRINT_LOW("Enabling C2D"); 12503 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) && 12504 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) { 12505 DEBUG_PRINT_ERROR("Unsupported color format for c2d"); 12506 status = false; 12507 } else { 12508 ColorFormat = dest_color_format; 12509 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ? 12510 YCbCr420P : YCbCr420SP; 12511 if (enabled) 12512 c2d.destroy(); 12513 enabled = false; 12514 if (!c2d.init()) { 12515 DEBUG_PRINT_ERROR("open failed for c2d"); 12516 status = false; 12517 } else 12518 enabled = true; 12519 } 12520 } else { 12521 if (enabled) 12522 c2d.destroy(); 12523 enabled = false; 12524 } 12525 pthread_mutex_unlock(&omx->c_lock); 12526 return status; 12527} 12528 12529OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() 12530{ 12531 if (!omx) { 12532 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12533 return NULL; 12534 } 12535 if (!enabled) 12536 return omx->m_out_mem_ptr; 12537 return m_out_mem_ptr_client; 12538} 12539 12540 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr 12541(OMX_BUFFERHEADERTYPE *bufadd) 12542{ 12543 if (!omx) { 12544 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12545 return NULL; 12546 } 12547 if (!enabled) 12548 return bufadd; 12549 12550 unsigned index = 0; 12551 index = bufadd - omx->m_out_mem_ptr; 12552 if (index < omx->drv_ctx.op_buf.actualcount) { 12553 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); 12554 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; 12555 bool status; 12556 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { 12557 pthread_mutex_lock(&omx->c_lock); 12558 cache_clean_buffer(index); 12559 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, 12560 omx->drv_ctx.op_buf_map_info[index].base_address, bufadd->pBuffer, pmem_fd[index], 12561 pmem_baseaddress[index], pmem_baseaddress[index]); 12562 if (!status) { 12563 DEBUG_PRINT_ERROR("Failed color conversion %d", status); 12564 m_out_mem_ptr_client[index].nFilledLen = 0; 12565 pthread_mutex_unlock(&omx->c_lock); 12566 return &m_out_mem_ptr_client[index]; 12567 } else { 12568 unsigned int filledLen = 0; 12569 c2d.get_output_filled_length(filledLen); 12570 m_out_mem_ptr_client[index].nFilledLen = filledLen; 12571 cache_clean_invalidate_buffer(index); 12572 } 12573 pthread_mutex_unlock(&omx->c_lock); 12574 } else 12575 m_out_mem_ptr_client[index].nFilledLen = 0; 12576 return &m_out_mem_ptr_client[index]; 12577 } 12578 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr"); 12579 return NULL; 12580} 12581 12582 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr 12583(OMX_BUFFERHEADERTYPE *bufadd) 12584{ 12585 if (!omx) { 12586 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 12587 return NULL; 12588 } 12589 if (!enabled) 12590 return bufadd; 12591 unsigned index = 0; 12592 index = bufadd - m_out_mem_ptr_client; 12593 if (index < omx->drv_ctx.op_buf.actualcount) { 12594 return &omx->m_out_mem_ptr[index]; 12595 } 12596 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr"); 12597 return NULL; 12598} 12599 bool omx_vdec::allocate_color_convert_buf::get_buffer_req 12600(unsigned int &buffer_size) 12601{ 12602 bool status = true; 12603 pthread_mutex_lock(&omx->c_lock); 12604 if (!enabled) 12605 buffer_size = omx->drv_ctx.op_buf.buffer_size; 12606 else { 12607 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { 12608 DEBUG_PRINT_ERROR("Get buffer size failed"); 12609 status = false; 12610 goto fail_get_buffer_size; 12611 } 12612 } 12613fail_get_buffer_size: 12614 pthread_mutex_unlock(&omx->c_lock); 12615 return status; 12616} 12617 12618OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req( 12619 OMX_U32 buffer_size, OMX_U32 actual_count) { 12620 OMX_U32 expectedSize = enabled ? buffer_size_req : omx->drv_ctx.op_buf.buffer_size; 12621 12622 if (buffer_size < expectedSize) { 12623 DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)", 12624 buffer_size, expectedSize); 12625 return OMX_ErrorBadParameter; 12626 } 12627 if (actual_count < omx->drv_ctx.op_buf.actualcount) { 12628 DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)", 12629 actual_count, omx->drv_ctx.op_buf.actualcount); 12630 return OMX_ErrorBadParameter; 12631 } 12632 12633 bool reqs_updated = false; 12634 if (enabled) { 12635 // disallow changing buffer size/count while we have active allocated buffers 12636 if (allocated_count > 0) { 12637 DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations", 12638 buffer_size_req, buffer_size, allocated_count); 12639 return OMX_ErrorInvalidState; 12640 } 12641 12642 buffer_size_req = buffer_size; 12643 } else { 12644 if (buffer_size > omx->drv_ctx.op_buf.buffer_size) { 12645 omx->drv_ctx.op_buf.buffer_size = buffer_size; 12646 reqs_updated = true; 12647 } 12648 } 12649 12650 if (actual_count > omx->drv_ctx.op_buf.actualcount) { 12651 omx->drv_ctx.op_buf.actualcount = actual_count; 12652 reqs_updated = true; 12653 } 12654 12655 if (reqs_updated) { 12656 omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount; 12657 omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count * 12658 omx->drv_ctx.extradata_info.buffer_size; 12659 return omx->set_buffer_req(&(omx->drv_ctx.op_buf)); 12660 } 12661 return OMX_ErrorNone; 12662} 12663 12664OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( 12665 OMX_BUFFERHEADERTYPE *bufhdr) 12666{ 12667 unsigned int index = 0; 12668 12669 if (!enabled) 12670 return omx->free_output_buffer(bufhdr); 12671 if (enabled && omx->is_component_secure()) 12672 return OMX_ErrorNone; 12673 if (!allocated_count || !bufhdr) { 12674 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); 12675 return OMX_ErrorBadParameter; 12676 } 12677 index = bufhdr - m_out_mem_ptr_client; 12678 if (index >= omx->drv_ctx.op_buf.actualcount) { 12679 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer"); 12680 return OMX_ErrorBadParameter; 12681 } 12682 if (pmem_fd[index] >= 0) { 12683 munmap(pmem_baseaddress[index], buffer_size_req); 12684 close(pmem_fd[index]); 12685 } 12686 pmem_fd[index] = -1; 12687#ifdef USE_ION 12688 omx->free_ion_memory(&op_buf_ion_info[index]); 12689#endif 12690 m_heap_ptr[index].video_heap_ptr = NULL; 12691 if (allocated_count > 0) 12692 allocated_count--; 12693 else 12694 allocated_count = 0; 12695 if (!allocated_count) { 12696 pthread_mutex_lock(&omx->c_lock); 12697 c2d.close(); 12698 init_members(); 12699 pthread_mutex_unlock(&omx->c_lock); 12700 } 12701 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); 12702} 12703 12704OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, 12705 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) 12706{ 12707 OMX_ERRORTYPE eRet = OMX_ErrorNone; 12708 if (!enabled) { 12709 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 12710 return eRet; 12711 } 12712 if (enabled && omx->is_component_secure()) { 12713 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d", 12714 omx->is_component_secure()); 12715 return OMX_ErrorUnsupportedSetting; 12716 } 12717 if (!bufferHdr || bytes > buffer_size_req) { 12718 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr); 12719 DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u", 12720 (unsigned int)buffer_size_req, (unsigned int)bytes); 12721 return OMX_ErrorBadParameter; 12722 } 12723 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { 12724 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert"); 12725 return OMX_ErrorInsufficientResources; 12726 } 12727 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; 12728 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, 12729 port,appData,omx->drv_ctx.op_buf.buffer_size); 12730 if (eRet != OMX_ErrorNone || !temp_bufferHdr) { 12731 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert"); 12732 return eRet; 12733 } 12734 if ((temp_bufferHdr - omx->m_out_mem_ptr) >= 12735 (int)omx->drv_ctx.op_buf.actualcount) { 12736 DEBUG_PRINT_ERROR("Invalid header index %ld", 12737 (long int)(temp_bufferHdr - omx->m_out_mem_ptr)); 12738 return OMX_ErrorUndefined; 12739 } 12740 unsigned int i = allocated_count; 12741#ifdef USE_ION 12742 // Allocate color-conversion buffers as cached to improve software-reading 12743 // performance of YUV (thumbnails). NOTE: These buffers will need an explicit 12744 // cache invalidation. 12745 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( 12746 buffer_size_req,buffer_alignment_req, 12747 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, 12748 ION_FLAG_CACHED); 12749 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; 12750 if (op_buf_ion_info[i].ion_device_fd < 0) { 12751 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert"); 12752 return OMX_ErrorInsufficientResources; 12753 } 12754 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, 12755 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); 12756 12757 if (pmem_baseaddress[i] == MAP_FAILED) { 12758 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req); 12759 close(pmem_fd[i]); 12760 omx->free_ion_memory(&op_buf_ion_info[i]); 12761 return OMX_ErrorInsufficientResources; 12762 } 12763 m_heap_ptr[i].video_heap_ptr = new VideoHeap ( 12764 op_buf_ion_info[i].ion_device_fd,buffer_size_req, 12765 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); 12766#endif 12767 m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get(); 12768 m_pmem_info_client[i].offset = 0; 12769 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; 12770 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 12771 m_platform_list_client[i].nEntries = 1; 12772 m_platform_list_client[i].entryList = &m_platform_entry_client[i]; 12773 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; 12774 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; 12775 m_out_mem_ptr_client[i].nFilledLen = 0; 12776 m_out_mem_ptr_client[i].nFlags = 0; 12777 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 12778 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); 12779 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; 12780 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; 12781 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; 12782 m_out_mem_ptr_client[i].pAppPrivate = appData; 12783 *bufferHdr = &m_out_mem_ptr_client[i]; 12784 DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr); 12785 allocated_count++; 12786 return eRet; 12787} 12788 12789bool omx_vdec::is_component_secure() 12790{ 12791 return secure_mode; 12792} 12793 12794bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) 12795{ 12796 bool status = true; 12797 if (!enabled) { 12798 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) { 12799 if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) 12800 dest_color_format = (OMX_COLOR_FORMATTYPE) 12801 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView; 12802 else 12803 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 12804 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){ 12805 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 12806 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC){ 12807 dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed; 12808 } else 12809 status = false; 12810 } else { 12811 if (ColorFormat == OMX_COLOR_FormatYUV420Planar || 12812 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 12813 dest_color_format = ColorFormat; 12814 } else 12815 status = false; 12816 } 12817 return status; 12818} 12819 12820OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops( 12821 unsigned int index, unsigned int cmd) 12822{ 12823 if (!enabled) { 12824 return OMX_ErrorNone; 12825 } 12826 12827 if (!omx || index >= omx->drv_ctx.op_buf.actualcount) { 12828 DEBUG_PRINT_ERROR("%s: Invalid param", __func__); 12829 return OMX_ErrorBadParameter; 12830 } 12831 12832 struct ion_flush_data flush_data; 12833 struct ion_custom_data custom_data; 12834 12835 memset(&flush_data, 0x0, sizeof(flush_data)); 12836 memset(&custom_data, 0x0, sizeof(custom_data)); 12837 12838 flush_data.vaddr = pmem_baseaddress[index]; 12839 flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd; 12840 flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle; 12841 flush_data.length = buffer_size_req; 12842 custom_data.cmd = cmd; 12843 custom_data.arg = (unsigned long)&flush_data; 12844 12845 DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d", 12846 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 12847 flush_data.fd, flush_data.handle, flush_data.vaddr, 12848 flush_data.length); 12849 int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data); 12850 if (ret < 0) { 12851 DEBUG_PRINT_ERROR("Cache %s failed: %s\n", 12852 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate", 12853 strerror(errno)); 12854 return OMX_ErrorUndefined; 12855 } 12856 return OMX_ErrorNone; 12857} 12858 12859void omx_vdec::buf_ref_add(int nPortIndex) 12860{ 12861 unsigned long i = 0; 12862 bool buf_present = false; 12863 long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 12864 OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 12865 12866 if (!dynamic_buf_mode || !out_dynamic_list) { 12867 return; 12868 } 12869 12870 pthread_mutex_lock(&m_lock); 12871 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 12872 //check the buffer fd, offset, uv addr with list contents 12873 //If present increment reference. 12874 if ((out_dynamic_list[i].fd == fd) && 12875 (out_dynamic_list[i].offset == offset)) { 12876 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u", 12877 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 12878 if (!secure_mode) { 12879 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr; 12880 } 12881 buf_present = true; 12882 break; 12883 } 12884 } 12885 if (!buf_present) { 12886 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 12887 //search for a entry to insert details of the new buffer 12888 if (out_dynamic_list[i].dup_fd < 0) { 12889 out_dynamic_list[i].fd = fd; 12890 out_dynamic_list[i].offset = offset; 12891 out_dynamic_list[i].dup_fd = dup(fd); 12892 out_dynamic_list[i].ref_count++; 12893 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u", 12894 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 12895 12896 if (!secure_mode) { 12897 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = 12898 (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len, 12899 PROT_READ|PROT_WRITE, MAP_SHARED, 12900 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0); 12901 //mmap returns (void *)-1 on failure and sets error code in errno. 12902 if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) { 12903 DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno); 12904 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL; 12905 break; 12906 } 12907 out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr; 12908 out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len; 12909 DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 12910 } 12911 break; 12912 } 12913 } 12914 } 12915 pthread_mutex_unlock(&m_lock); 12916} 12917 12918void omx_vdec::buf_ref_remove() 12919{ 12920 unsigned long i = 0; 12921 12922 if (!dynamic_buf_mode || !out_dynamic_list) { 12923 return; 12924 } 12925 12926 pthread_mutex_lock(&m_lock); 12927 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { 12928 if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) { 12929 DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size); 12930 munmap(out_dynamic_list[i].buffaddr, 12931 out_dynamic_list[i].mapped_size); 12932 } 12933 12934 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u", 12935 (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); 12936 close(out_dynamic_list[i].dup_fd); 12937 out_dynamic_list[i].dup_fd = -1; 12938 } 12939 pthread_mutex_unlock(&m_lock); 12940 12941 if (out_dynamic_list) { 12942 free(out_dynamic_list); 12943 out_dynamic_list = NULL; 12944 } 12945} 12946 12947#ifdef _MSM8974_ 12948void omx_vdec::send_codec_config() { 12949 if (codec_config_flag) { 12950 unsigned long p1 = 0; // Parameter - 1 12951 unsigned long p2 = 0; // Parameter - 2 12952 unsigned long ident = 0; 12953 pthread_mutex_lock(&m_lock); 12954 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n"); 12955 while (m_etb_q.m_size) { 12956 m_etb_q.pop_entry(&p1,&p2,&ident); 12957 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 12958 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 12959 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 12960 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 12961 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); 12962 omx_report_error(); 12963 } 12964 } else { 12965 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 12966 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 12967 } 12968 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 12969 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 12970 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 12971 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 12972 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); 12973 omx_report_error (); 12974 } 12975 } else { 12976 pending_input_buffers++; 12977 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); 12978 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 12979 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 12980 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 12981 } 12982 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 12983 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", 12984 (OMX_BUFFERHEADERTYPE *)p1); 12985 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 12986 } 12987 } 12988 pthread_mutex_unlock(&m_lock); 12989 } 12990} 12991#endif 12992 12993omx_vdec::perf_control::perf_control() 12994{ 12995 m_perf_lib = NULL; 12996 m_perf_handle = 0; 12997 m_perf_lock_acquire = NULL; 12998 m_perf_lock_release = NULL; 12999} 13000 13001omx_vdec::perf_control::~perf_control() 13002{ 13003 if (m_perf_handle != 0 && m_perf_lock_release) { 13004 DEBUG_PRINT_LOW("NOTE2: release perf lock"); 13005 m_perf_lock_release(m_perf_handle); 13006 } 13007 if (m_perf_lib) { 13008 dlclose(m_perf_lib); 13009 } 13010} 13011 13012struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0}; 13013 13014omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock; 13015 13016void omx_vdec::perf_control::send_hint_to_mpctl(bool state) 13017{ 13018 if (load_lib() == false) { 13019 return; 13020 } 13021 m_perf_lock.lock(); 13022 /* 0x4401 maps to video decode playback hint 13023 * in perflock, enum number is 44 and state 13024 * being sent on perflock acquire is 01 (true) 13025 */ 13026 int arg = 0x4401; 13027 13028 if (state == true) { 13029 mpctl_obj.vid_inst_count++; 13030 } else if (state == false) { 13031 mpctl_obj.vid_inst_count--; 13032 } 13033 13034 if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) { 13035 mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int)); 13036 mpctl_obj.vid_acquired = true; 13037 DEBUG_PRINT_INFO("Video slvp perflock acquired"); 13038 } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) { 13039 m_perf_lock_release(mpctl_obj.vid_disp_handle); 13040 mpctl_obj.vid_acquired = false; 13041 DEBUG_PRINT_INFO("Video slvp perflock released"); 13042 } 13043 m_perf_lock.unlock(); 13044} 13045 13046void omx_vdec::perf_control::request_cores(int frame_duration_us) 13047{ 13048 if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) { 13049 return; 13050 } 13051 bool retVal = load_lib(); 13052 if (retVal && m_perf_lock_acquire && m_perf_handle == 0) { 13053 int arg = 0x700 /*base value*/ + 2 /*cores*/; 13054 m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int)); 13055 if (m_perf_handle) { 13056 DEBUG_PRINT_HIGH("perf lock acquired"); 13057 } 13058 } 13059} 13060 13061bool omx_vdec::perf_control::load_lib() 13062{ 13063 char perf_lib_path[PROPERTY_VALUE_MAX] = {0}; 13064 if (m_perf_lib) 13065 return true; 13066 13067 if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) { 13068 DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library"); 13069 goto handle_err; 13070 } 13071 13072 if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) { 13073 DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror()); 13074 goto handle_err; 13075 } else { 13076 m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq"); 13077 if (m_perf_lock_acquire == NULL) { 13078 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq"); 13079 goto handle_err; 13080 } 13081 m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel"); 13082 if (m_perf_lock_release == NULL) { 13083 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel"); 13084 goto handle_err; 13085 } 13086 } 13087 return true; 13088 13089handle_err: 13090 if (m_perf_lib) { 13091 dlclose(m_perf_lib); 13092 } 13093 m_perf_lib = NULL; 13094 return false; 13095} 13096 13097OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth, 13098 unsigned long nMaxFrameHeight) 13099{ 13100 13101 OMX_ERRORTYPE eRet = OMX_ErrorNone; 13102 int ret = 0; 13103 unsigned long min_res_buf_count = 0; 13104 13105 eRet = enable_smoothstreaming(); 13106 if (eRet != OMX_ErrorNone) { 13107 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver"); 13108 return eRet; 13109 } 13110 13111 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu", 13112 nMaxFrameWidth, 13113 nMaxFrameHeight); 13114 m_smoothstreaming_mode = true; 13115 m_smoothstreaming_width = nMaxFrameWidth; 13116 m_smoothstreaming_height = nMaxFrameHeight; 13117 13118 //Get upper limit buffer count for min supported resolution 13119 struct v4l2_format fmt; 13120 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 13121 fmt.fmt.pix_mp.height = m_decoder_capability.min_height; 13122 fmt.fmt.pix_mp.width = m_decoder_capability.min_width; 13123 fmt.fmt.pix_mp.pixelformat = output_capability; 13124 13125 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 13126 if (ret) { 13127 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u", 13128 m_decoder_capability.min_height, 13129 m_decoder_capability.min_width); 13130 return OMX_ErrorUnsupportedSetting; 13131 } 13132 13133 eRet = get_buffer_req(&drv_ctx.op_buf); 13134 if (eRet != OMX_ErrorNone) { 13135 DEBUG_PRINT_ERROR("failed to get_buffer_req"); 13136 return eRet; 13137 } 13138 13139 min_res_buf_count = drv_ctx.op_buf.mincount; 13140 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u", 13141 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width); 13142 13143 m_extradata_info.output_crop_rect.nLeft = 0; 13144 m_extradata_info.output_crop_rect.nTop = 0; 13145 m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width; 13146 m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height; 13147 13148 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height, 13149 m_smoothstreaming_width, m_smoothstreaming_height); 13150 eRet = is_video_session_supported(); 13151 if (eRet != OMX_ErrorNone) { 13152 DEBUG_PRINT_ERROR("video session is not supported"); 13153 return eRet; 13154 } 13155 13156 //Get upper limit buffer size for max smooth streaming resolution set 13157 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 13158 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 13159 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 13160 fmt.fmt.pix_mp.pixelformat = output_capability; 13161 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 13162 if (ret) { 13163 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback"); 13164 return OMX_ErrorUnsupportedSetting; 13165 } 13166 13167 eRet = get_buffer_req(&drv_ctx.op_buf); 13168 if (eRet != OMX_ErrorNone) { 13169 DEBUG_PRINT_ERROR("failed to get_buffer_req!!"); 13170 return eRet; 13171 } 13172 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u", 13173 (unsigned int)drv_ctx.op_buf.buffer_size); 13174 13175 drv_ctx.op_buf.mincount = min_res_buf_count; 13176 drv_ctx.op_buf.actualcount = min_res_buf_count; 13177 drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size; 13178 eRet = set_buffer_req(&drv_ctx.op_buf); 13179 if (eRet != OMX_ErrorNone) { 13180 DEBUG_PRINT_ERROR("failed to set_buffer_req"); 13181 return eRet; 13182 } 13183 13184 eRet = get_buffer_req(&drv_ctx.op_buf); 13185 if (eRet != OMX_ErrorNone) { 13186 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!"); 13187 return eRet; 13188 } 13189 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u", 13190 drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size); 13191 return eRet; 13192} 13193 13194//static 13195OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) { 13196 13197#ifndef FLEXYUV_SUPPORTED 13198 return OMX_ErrorUndefined; 13199#else 13200 13201 if (pParam == NULL) { 13202 DEBUG_PRINT_ERROR("describeColorFormat: invalid params"); 13203 return OMX_ErrorBadParameter; 13204 } 13205 13206 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam; 13207 13208 MediaImage *img = &(params->sMediaImage); 13209 switch(params->eColorFormat) { 13210 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: 13211 { 13212 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 13213 img->mNumPlanes = 3; 13214 // mWidth and mHeight represent the W x H of the largest plane 13215 // In our case, this happens to be the Stride x Scanlines of Y plane 13216 img->mWidth = params->nFrameWidth; 13217 img->mHeight = params->nFrameHeight; 13218 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13219 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight); 13220 img->mBitDepth = 8; 13221 //Plane 0 (Y) 13222 img->mPlane[MediaImage::Y].mOffset = 0; 13223 img->mPlane[MediaImage::Y].mColInc = 1; 13224 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride 13225 img->mPlane[MediaImage::Y].mHorizSubsampling = 1; 13226 img->mPlane[MediaImage::Y].mVertSubsampling = 1; 13227 //Plane 1 (U) 13228 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight; 13229 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV 13230 img->mPlane[MediaImage::U].mRowInc = 13231 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13232 img->mPlane[MediaImage::U].mHorizSubsampling = 2; 13233 img->mPlane[MediaImage::U].mVertSubsampling = 2; 13234 //Plane 2 (V) 13235 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1; 13236 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV 13237 img->mPlane[MediaImage::V].mRowInc = 13238 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth); 13239 img->mPlane[MediaImage::V].mHorizSubsampling = 2; 13240 img->mPlane[MediaImage::V].mVertSubsampling = 2; 13241 break; 13242 } 13243 13244 case OMX_COLOR_FormatYUV420Planar: 13245 case OMX_COLOR_FormatYUV420SemiPlanar: 13246 // We need not describe the standard OMX linear formats as these are 13247 // understood by client. Fail this deliberately to let client fill-in 13248 return OMX_ErrorUnsupportedSetting; 13249 13250 default: 13251 // Rest all formats which are non-linear cannot be described 13252 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat); 13253 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 13254 return OMX_ErrorNone; 13255 }; 13256 13257 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat); 13258 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight); 13259 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight); 13260 for (size_t i = 0; i < img->mNumPlanes; ++i) { 13261 DEBUG_PRINT_LOW(" Plane[%zu] : offset=%d / xStep=%d / yStep = %d", 13262 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc); 13263 } 13264 return OMX_ErrorNone; 13265#endif //FLEXYUV_SUPPORTED 13266} 13267 13268void omx_vdec::prefetchNewBuffers() { 13269 13270 struct v4l2_decoder_cmd dec; 13271 uint32_t prefetch_count; 13272 uint32_t prefetch_size; 13273 uint32_t want_size; 13274 uint32_t have_size; 13275 int color_fmt, rc; 13276 uint32_t new_calculated_size; 13277 uint32_t new_buffer_size; 13278 uint32_t new_buffer_count; 13279 uint32_t old_buffer_size; 13280 uint32_t old_buffer_count; 13281 13282 memset((void *)&dec, 0 , sizeof(dec)); 13283 DEBUG_PRINT_LOW("Old size : %zu, count : %d, width : %u, height : %u\n", 13284 drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount, 13285 drv_ctx.video_resolution.frame_width, 13286 drv_ctx.video_resolution.frame_height); 13287 dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT; 13288 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 13289 DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno); 13290 } else { 13291 DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n", 13292 dec.raw.data[0], dec.raw.data[1]); 13293 } 13294 13295 switch ((int)drv_ctx.output_format) { 13296 case VDEC_YUV_FORMAT_NV12: 13297 color_fmt = COLOR_FMT_NV12; 13298 break; 13299 case VDEC_YUV_FORMAT_NV12_UBWC: 13300 color_fmt = COLOR_FMT_NV12_UBWC; 13301 break; 13302 case VDEC_YUV_FORMAT_NV12_TP10_UBWC: 13303 color_fmt = COLOR_FMT_NV12_BPP10_UBWC; 13304 break; 13305 default: 13306 color_fmt = -1; 13307 DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format); 13308 return; 13309 } 13310 13311 new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height); 13312 DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n", 13313 m_reconfig_width, m_reconfig_height, new_calculated_size); 13314 new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size; 13315 new_buffer_count = dec.raw.data[1]; 13316 old_buffer_size = drv_ctx.op_buf.buffer_size; 13317 old_buffer_count = drv_ctx.op_buf.actualcount; 13318 13319 new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count; 13320 13321 prefetch_count = new_buffer_count; 13322 prefetch_size = new_buffer_size - old_buffer_size; 13323 want_size = new_buffer_size * new_buffer_count; 13324 have_size = old_buffer_size * old_buffer_count; 13325 13326 if (want_size > have_size) { 13327 DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size); 13328 DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size); 13329 13330 int ion_fd = open(MEM_DEVICE, O_RDONLY); 13331 if (ion_fd < 0) { 13332 DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd); 13333 return; 13334 } 13335 13336 struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data)); 13337 struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data)); 13338 struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions)); 13339 size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count); 13340 13341 if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) { 13342 DEBUG_PRINT_ERROR("prefetch data allocation failed"); 13343 goto prefetch_exit; 13344 } 13345 13346 for (uint32_t i = 0; i < prefetch_count; i++) { 13347 sizes[i] = prefetch_size; 13348 } 13349 13350 regions[0].nr_sizes = prefetch_count; 13351 regions[0].sizes = sizes; 13352 regions[0].vmid = ION_FLAG_CP_PIXEL; 13353 13354 prefetch_data->nr_regions = 1; 13355 prefetch_data->regions = regions; 13356 prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID); 13357 13358 custom_data->cmd = ION_IOC_PREFETCH; 13359 custom_data->arg = (unsigned long )prefetch_data; 13360 13361 rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data); 13362 if (rc) { 13363 DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno); 13364 } 13365 13366prefetch_exit: 13367 close(ion_fd); 13368 free(sizes); 13369 free(regions); 13370 free(prefetch_data); 13371 free(custom_data); 13372 } 13373} 13374