1/*-------------------------------------------------------------------------- 2Copyright (c) 2013-2015, 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*//** @file omx_vdec.cpp 34 This module contains the implementation of the OpenMAX core & component. 35 36*//*========================================================================*/ 37 38////////////////////////////////////////////////////////////////////////////// 39// Include Files 40////////////////////////////////////////////////////////////////////////////// 41 42#include <string.h> 43#include <pthread.h> 44#include <sys/prctl.h> 45#include <stdlib.h> 46#include <unistd.h> 47#include <errno.h> 48#include "omx_vdec_hevc.h" 49#include <fcntl.h> 50#include <limits.h> 51#include <media/msm_media_info.h> 52#include <qdMetaData.h> 53 54#ifndef _ANDROID_ 55#include <sys/ioctl.h> 56#include <sys/mman.h> 57#endif //_ANDROID_ 58 59#ifdef _ANDROID_ 60#include <cutils/properties.h> 61#undef USE_EGL_IMAGE_GPU 62#endif 63 64#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 65#include <gralloc_priv.h> 66#endif 67 68#ifdef USE_EGL_IMAGE_GPU 69#include <EGL/egl.h> 70#include <EGL/eglQCOM.h> 71#define EGL_BUFFER_HANDLE_QCOM 0x4F00 72#define EGL_BUFFER_OFFSET_QCOM 0x4F01 73#endif 74 75#ifdef INPUT_BUFFER_LOG 76#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" 77#define INPUT_BUFFER_FILE_NAME_LEN 30 78FILE *inputBufferFile1; 79char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; 80#endif 81#ifdef OUTPUT_BUFFER_LOG 82FILE *outputBufferFile1; 83char outputfilename [] = "/data/output.yuv"; 84#endif 85#ifdef OUTPUT_EXTRADATA_LOG 86FILE *outputExtradataFile; 87char ouputextradatafilename [] = "/data/extradata"; 88#endif 89 90#ifdef VENUS_HEVC 91#define DEVICE_NAME "/dev/video/venus_dec" 92#else 93#define DEVICE_NAME "/dev/video/q6_dec" 94#endif 95 96#define DEFAULT_FPS 30 97#define MAX_INPUT_ERROR DEFAULT_FPS 98#define MAX_SUPPORTED_FPS 120 99 100#define VC1_SP_MP_START_CODE 0xC5000000 101#define VC1_SP_MP_START_CODE_MASK 0xFF000000 102#define VC1_AP_SEQ_START_CODE 0x0F010000 103#define VC1_STRUCT_C_PROFILE_MASK 0xF0 104#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 105#define VC1_SIMPLE_PROFILE 0 106#define VC1_MAIN_PROFILE 1 107#define VC1_ADVANCE_PROFILE 3 108#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 109#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 110#define VC1_STRUCT_C_LEN 4 111#define VC1_STRUCT_C_POS 8 112#define VC1_STRUCT_A_POS 12 113#define VC1_STRUCT_B_POS 24 114#define VC1_SEQ_LAYER_SIZE 36 115#define POLL_TIMEOUT 0x7fffffff 116 117#define MEM_DEVICE "/dev/ion" 118#define MEM_HEAP_ID ION_CP_MM_HEAP_ID 119 120#ifdef _ANDROID_ 121extern "C" { 122#include<utils/Log.h> 123} 124#endif//_ANDROID_ 125 126#define SZ_4K 0x1000 127#define SZ_1M 0x100000 128 129#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 130#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 131#define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0) 132 133#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA) 134 135void* async_message_thread (void *input) 136{ 137 OMX_BUFFERHEADERTYPE *buffer; 138 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 139 struct pollfd pfd; 140 struct v4l2_buffer v4l2_buf; 141 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 142 struct v4l2_event dqevent; 143 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 144 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 145 pfd.fd = omx->drv_ctx.video_driver_fd; 146 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; 147 DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); 148 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); 149 while (1) { 150 rc = poll(&pfd, 1, POLL_TIMEOUT); 151 if (!rc) { 152 DEBUG_PRINT_ERROR("Poll timedout"); 153 break; 154 } else if (rc < 0) { 155 DEBUG_PRINT_ERROR("Error while polling: %d", rc); 156 break; 157 } 158 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { 159 struct vdec_msginfo vdec_msg; 160 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 161 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 162 v4l2_buf.length = omx->drv_ctx.num_planes; 163 v4l2_buf.m.planes = plane; 164 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 165 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; 166 vdec_msg.status_code=VDEC_S_SUCCESS; 167 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; 168 vdec_msg.msgdata.output_frame.len=plane[0].bytesused; 169 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; 170 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + 171 (uint64_t)v4l2_buf.timestamp.tv_usec; 172 if (vdec_msg.msgdata.output_frame.len) { 173 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; 174 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; 175 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; 176 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; 177 } 178 if (omx->async_message_process(input,&vdec_msg) < 0) { 179 DEBUG_PRINT_HIGH("async_message_thread Exited"); 180 break; 181 } 182 } 183 } 184 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { 185 struct vdec_msginfo vdec_msg; 186 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 187 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 188 v4l2_buf.length = 1; 189 v4l2_buf.m.planes = plane; 190 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 191 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; 192 vdec_msg.status_code=VDEC_S_SUCCESS; 193 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; 194 if (omx->async_message_process(input,&vdec_msg) < 0) { 195 DEBUG_PRINT_HIGH("async_message_thread Exited"); 196 break; 197 } 198 } 199 } 200 if (pfd.revents & POLLPRI) { 201 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); 202 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { 203 struct vdec_msginfo vdec_msg; 204 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; 205 vdec_msg.status_code=VDEC_S_SUCCESS; 206 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved"); 207 if (omx->async_message_process(input,&vdec_msg) < 0) { 208 DEBUG_PRINT_HIGH("async_message_thread Exited"); 209 break; 210 } 211 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) { 212 struct vdec_msginfo vdec_msg; 213 vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED; 214 vdec_msg.status_code=VDEC_S_SUCCESS; 215 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved"); 216 if (omx->async_message_process(input,&vdec_msg) < 0) { 217 DEBUG_PRINT_HIGH("async_message_thread Exited"); 218 break; 219 } 220 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 221 struct vdec_msginfo vdec_msg; 222 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; 223 vdec_msg.status_code=VDEC_S_SUCCESS; 224 DEBUG_PRINT_HIGH("VIDC Flush Done Recieved"); 225 if (omx->async_message_process(input,&vdec_msg) < 0) { 226 DEBUG_PRINT_HIGH("async_message_thread Exited"); 227 break; 228 } 229 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; 230 vdec_msg.status_code=VDEC_S_SUCCESS; 231 DEBUG_PRINT_HIGH("VIDC Flush Done Recieved"); 232 if (omx->async_message_process(input,&vdec_msg) < 0) { 233 DEBUG_PRINT_HIGH("async_message_thread Exited"); 234 break; 235 } 236 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { 237 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited"); 238 break; 239 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 240 struct vdec_msginfo vdec_msg; 241 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR; 242 vdec_msg.status_code=VDEC_S_SUCCESS; 243 DEBUG_PRINT_HIGH("SYS Error Recieved"); 244 if (omx->async_message_process(input,&vdec_msg) < 0) { 245 DEBUG_PRINT_HIGH("async_message_thread Exited"); 246 break; 247 } 248 } else { 249 DEBUG_PRINT_HIGH("VIDC Some Event recieved"); 250 continue; 251 } 252 } 253 } 254 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); 255 return NULL; 256} 257 258void* message_thread(void *input) 259{ 260 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 261 unsigned char id; 262 int n; 263 if (omx == NULL) { 264 DEBUG_PRINT_ERROR("message thread null pointer rxd"); 265 return NULL; 266 } 267 268 DEBUG_PRINT_HIGH("omx_vdec: message thread start"); 269 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); 270 while (1) { 271 272 n = read(omx->m_pipe_in, &id, 1); 273 274 if (0 == n) { 275 break; 276 } 277 278 if (1 == n) { 279 omx->process_event_cb(omx, id); 280 } 281 if ((n < 0) && (errno != EINTR)) { 282 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno); 283 break; 284 } 285 } 286 DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); 287 return NULL; 288} 289 290void post_message(omx_vdec *omx, unsigned char id) 291{ 292 int ret_value; 293 294 if (omx == NULL) { 295 DEBUG_PRINT_ERROR("message thread null pointer rxd"); 296 return; 297 } 298 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); 299 ret_value = write(omx->m_pipe_out, &id, 1); 300 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); 301} 302 303// omx_cmd_queue destructor 304omx_vdec::omx_cmd_queue::~omx_cmd_queue() 305{ 306 // Nothing to do 307} 308 309// omx cmd queue constructor 310omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 311{ 312 memset(m_q,0,sizeof(m_q)); 313} 314 315// omx cmd queue insert 316bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) 317{ 318 bool ret = true; 319 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) { 320 m_q[m_write].id = id; 321 m_q[m_write].param1 = p1; 322 m_q[m_write].param2 = p2; 323 m_write++; 324 m_size ++; 325 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) { 326 m_write = 0; 327 } 328 } else { 329 ret = false; 330 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__); 331 } 332 return ret; 333} 334 335// omx cmd queue pop 336bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) 337{ 338 bool ret = true; 339 if (m_size > 0) { 340 *id = m_q[m_read].id; 341 *p1 = m_q[m_read].param1; 342 *p2 = m_q[m_read].param2; 343 // Move the read pointer ahead 344 ++m_read; 345 --m_size; 346 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) { 347 m_read = 0; 348 } 349 } else { 350 ret = false; 351 } 352 return ret; 353} 354 355// Retrieve the first mesg type in the queue 356unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 357{ 358 return m_q[m_read].id; 359} 360 361#ifdef _ANDROID_ 362omx_vdec::ts_arr_list::ts_arr_list() 363{ 364 //initialize timestamps array 365 memset(m_ts_arr_list, 0, sizeof(m_ts_arr_list) ); 366} 367omx_vdec::ts_arr_list::~ts_arr_list() 368{ 369 //free m_ts_arr_list? 370} 371 372bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) 373{ 374 bool ret = true; 375 bool duplicate_ts = false; 376 int idx = 0; 377 378 //insert at the first available empty location 379 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 380 if (!m_ts_arr_list[idx].valid) { 381 //found invalid or empty entry, save timestamp 382 m_ts_arr_list[idx].valid = true; 383 m_ts_arr_list[idx].timestamp = ts; 384 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", 385 ts, idx); 386 break; 387 } 388 } 389 390 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) { 391 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); 392 ret = false; 393 } 394 return ret; 395} 396 397bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) 398{ 399 bool ret = true; 400 int min_idx = -1; 401 OMX_TICKS min_ts = 0; 402 int idx = 0; 403 404 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 405 406 if (m_ts_arr_list[idx].valid) { 407 //found valid entry, save index 408 if (min_idx < 0) { 409 //first valid entry 410 min_ts = m_ts_arr_list[idx].timestamp; 411 min_idx = idx; 412 } else if (m_ts_arr_list[idx].timestamp < min_ts) { 413 min_ts = m_ts_arr_list[idx].timestamp; 414 min_idx = idx; 415 } 416 } 417 418 } 419 420 if (min_idx < 0) { 421 //no valid entries found 422 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); 423 ts = 0; 424 ret = false; 425 } else { 426 ts = m_ts_arr_list[min_idx].timestamp; 427 m_ts_arr_list[min_idx].valid = false; 428 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", 429 ts, min_idx); 430 } 431 432 return ret; 433 434} 435 436 437bool omx_vdec::ts_arr_list::reset_ts_list() 438{ 439 bool ret = true; 440 int idx = 0; 441 442 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); 443 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) { 444 m_ts_arr_list[idx].valid = false; 445 } 446 return ret; 447} 448#endif 449 450// factory function executed by the core to create instances 451void *get_omx_component_factory_fn(void) 452{ 453 return (new omx_vdec); 454} 455 456#ifdef _ANDROID_ 457#ifdef USE_ION 458VideoHeap::VideoHeap(int devicefd, size_t size, void* base, 459 ion_user_handle_t handle, int ionMapfd) 460{ 461 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); 462} 463#else 464VideoHeap::VideoHeap(int fd, size_t size, void* base) 465{ 466 // dup file descriptor, map once, use pmem 467 init(dup(fd), base, size, 0 , MEM_DEVICE); 468} 469#endif 470#endif // _ANDROID_ 471/* ====================================================================== 472 FUNCTION 473 omx_vdec::omx_vdec 474 475 DESCRIPTION 476 Constructor 477 478 PARAMETERS 479 None 480 481 RETURN VALUE 482 None. 483 ========================================================================== */ 484omx_vdec::omx_vdec(): m_error_propogated(false), 485 m_state(OMX_StateInvalid), 486 m_app_data(NULL), 487 m_inp_mem_ptr(NULL), 488 m_out_mem_ptr(NULL), 489 m_inp_err_count(0), 490 input_flush_progress (false), 491 output_flush_progress (false), 492 input_use_buffer (false), 493 output_use_buffer (false), 494 ouput_egl_buffers(false), 495 m_use_output_pmem(OMX_FALSE), 496 m_out_mem_region_smi(OMX_FALSE), 497 m_out_pvt_entry_pmem(OMX_FALSE), 498 pending_input_buffers(0), 499 pending_output_buffers(0), 500 m_out_bm_count(0), 501 m_inp_bm_count(0), 502 m_inp_bPopulated(OMX_FALSE), 503 m_out_bPopulated(OMX_FALSE), 504 m_flags(0), 505#ifdef _ANDROID_ 506 m_heap_ptr(NULL), 507#endif 508 m_inp_bEnabled(OMX_TRUE), 509 m_out_bEnabled(OMX_TRUE), 510 m_in_alloc_cnt(0), 511 m_platform_list(NULL), 512 m_platform_entry(NULL), 513 m_pmem_info(NULL), 514 arbitrary_bytes (true), 515 psource_frame (NULL), 516 pdest_frame (NULL), 517 m_inp_heap_ptr (NULL), 518 m_phdr_pmem_ptr(NULL), 519 m_heap_inp_bm_count (0), 520 codec_type_parse ((codec_type)0), 521 first_frame_meta (true), 522 frame_count (0), 523 nal_count (0), 524 nal_length(0), 525 look_ahead_nal (false), 526 first_frame(0), 527 first_buffer(NULL), 528 first_frame_size (0), 529 m_device_file_ptr(NULL), 530 m_vc1_profile((vc1_profile_type)0), 531 h264_last_au_ts(LLONG_MAX), 532 h264_last_au_flags(0), 533 prev_ts(LLONG_MAX), 534 rst_prev_ts(true), 535 frm_int(0), 536 in_reconfig(false), 537 m_display_id(NULL), 538 h264_parser(NULL), 539 client_extradata(0), 540#ifdef _ANDROID_ 541 m_enable_android_native_buffers(OMX_FALSE), 542 m_use_android_native_buffers(OMX_FALSE), 543#endif 544 m_desc_buffer_ptr(NULL), 545 secure_mode(false) 546{ 547 /* Assumption is that , to begin with , we have all the frames with decoder */ 548 DEBUG_PRINT_HIGH("In OMX vdec Constructor"); 549#ifdef _ANDROID_ 550 char property_value[PROPERTY_VALUE_MAX] = {0}; 551 property_get("vidc.debug.level", property_value, "1"); 552 debug_level = atoi(property_value); 553 property_value[0] = '\0'; 554 555 property_get("vidc.dec.debug.perf", property_value, "0"); 556 perf_flag = atoi(property_value); 557 if (perf_flag) { 558 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); 559 dec_time.start(); 560 proc_frms = latency = 0; 561 } 562 property_value[0] = '\0'; 563 property_get("vidc.dec.debug.ts", property_value, "0"); 564 m_debug_timestamp = atoi(property_value); 565 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); 566 if (m_debug_timestamp) { 567 time_stamp_dts.set_timestamp_reorder_mode(true); 568 time_stamp_dts.enable_debug_print(true); 569 } 570 571 property_value[0] = '\0'; 572 property_get("vidc.dec.debug.concealedmb", property_value, "0"); 573 m_debug_concealedmb = atoi(property_value); 574 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); 575 576#endif 577 memset(&m_cmp,0,sizeof(m_cmp)); 578 memset(&m_cb,0,sizeof(m_cb)); 579 memset (&drv_ctx,0,sizeof(drv_ctx)); 580 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 581 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 582 memset(m_demux_offsets, 0, sizeof(m_demux_offsets) ); 583 m_demux_entries = 0; 584#ifdef _ANDROID_ICS_ 585 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 586#endif 587 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 588 drv_ctx.timestamp_adjust = false; 589 drv_ctx.video_driver_fd = -1; 590 m_vendor_config.pData = NULL; 591 pthread_mutex_init(&m_lock, NULL); 592 pthread_mutex_init(&c_lock, NULL); 593 sem_init(&m_cmd_lock,0,0); 594 streaming[CAPTURE_PORT] = 595 streaming[OUTPUT_PORT] = false; 596#ifdef _ANDROID_ 597 char extradata_value[PROPERTY_VALUE_MAX] = {0}; 598 property_get("vidc.dec.debug.extradata", extradata_value, "0"); 599 m_debug_extradata = atoi(extradata_value); 600 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); 601#endif 602 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; 603 client_buffers.set_vdec_client(this); 604} 605 606static const int event_type[] = { 607 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 608 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, 609 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, 610 V4L2_EVENT_MSM_VIDC_CLOSE_DONE, 611 V4L2_EVENT_MSM_VIDC_SYS_ERROR 612}; 613 614static OMX_ERRORTYPE subscribe_to_events(int fd) 615{ 616 OMX_ERRORTYPE eRet = OMX_ErrorNone; 617 struct v4l2_event_subscription sub; 618 int array_sz = sizeof(event_type)/sizeof(int); 619 int i,rc; 620 if (fd < 0) { 621 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 622 return OMX_ErrorBadParameter; 623 } 624 625 for (i = 0; i < array_sz; ++i) { 626 memset(&sub, 0, sizeof(sub)); 627 sub.type = event_type[i]; 628 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 629 if (rc) { 630 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 631 break; 632 } 633 } 634 if (i < array_sz) { 635 for (--i; i >=0 ; i--) { 636 memset(&sub, 0, sizeof(sub)); 637 sub.type = event_type[i]; 638 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 639 if (rc) 640 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 641 } 642 eRet = OMX_ErrorNotImplemented; 643 } 644 return eRet; 645} 646 647 648static OMX_ERRORTYPE unsubscribe_to_events(int fd) 649{ 650 OMX_ERRORTYPE eRet = OMX_ErrorNone; 651 struct v4l2_event_subscription sub; 652 int array_sz = sizeof(event_type)/sizeof(int); 653 int i,rc; 654 if (fd < 0) { 655 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 656 return OMX_ErrorBadParameter; 657 } 658 659 for (i = 0; i < array_sz; ++i) { 660 memset(&sub, 0, sizeof(sub)); 661 sub.type = event_type[i]; 662 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 663 if (rc) { 664 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 665 break; 666 } 667 } 668 return eRet; 669} 670 671/* ====================================================================== 672 FUNCTION 673 omx_vdec::~omx_vdec 674 675 DESCRIPTION 676 Destructor 677 678 PARAMETERS 679 None 680 681 RETURN VALUE 682 None. 683 ========================================================================== */ 684omx_vdec::~omx_vdec() 685{ 686 m_pmem_info = NULL; 687 struct v4l2_decoder_cmd dec; 688 DEBUG_PRINT_HIGH("In OMX vdec Destructor"); 689 if (m_pipe_in) close(m_pipe_in); 690 if (m_pipe_out) close(m_pipe_out); 691 m_pipe_in = -1; 692 m_pipe_out = -1; 693 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); 694 pthread_join(msg_thread_id,NULL); 695 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); 696 dec.cmd = V4L2_DEC_CMD_STOP; 697 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 698 DEBUG_PRINT_ERROR("STOP Command failed"); 699 } 700 pthread_join(async_thread_id,NULL); 701 unsubscribe_to_events(drv_ctx.video_driver_fd); 702 close(drv_ctx.video_driver_fd); 703 pthread_mutex_destroy(&m_lock); 704 pthread_mutex_destroy(&c_lock); 705 sem_destroy(&m_cmd_lock); 706 if (perf_flag) { 707 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); 708 dec_time.end(); 709 } 710 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); 711} 712 713int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) 714{ 715 struct v4l2_requestbuffers bufreq; 716 int rc = 0; 717 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 718 bufreq.memory = V4L2_MEMORY_USERPTR; 719 bufreq.count = 0; 720 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 721 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 722 } 723 return rc; 724} 725 726/* ====================================================================== 727 FUNCTION 728 omx_vdec::OMXCntrlProcessMsgCb 729 730 DESCRIPTION 731 IL Client callbacks are generated through this routine. The decoder 732 provides the thread context for this routine. 733 734 PARAMETERS 735 ctxt -- Context information related to the self. 736 id -- Event identifier. This could be any of the following: 737 1. Command completion event 738 2. Buffer done callback event 739 3. Frame done callback event 740 741 RETURN VALUE 742 None. 743 744 ========================================================================== */ 745void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 746{ 747 signed int p1; // Parameter - 1 748 signed int p2; // Parameter - 2 749 unsigned int ident; 750 unsigned int qsize=0; // qsize 751 omx_vdec *pThis = (omx_vdec *) ctxt; 752 753 if (!pThis) { 754 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out", 755 __func__); 756 return; 757 } 758 759 // Protect the shared queue data structure 760 do { 761 /*Read the message id's from the queue*/ 762 pthread_mutex_lock(&pThis->m_lock); 763 qsize = pThis->m_cmd_q.m_size; 764 if (qsize) { 765 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); 766 } 767 768 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 769 qsize = pThis->m_ftb_q.m_size; 770 if (qsize) { 771 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); 772 } 773 } 774 775 if (qsize == 0 && pThis->m_state != OMX_StatePause) { 776 qsize = pThis->m_etb_q.m_size; 777 if (qsize) { 778 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); 779 } 780 } 781 pthread_mutex_unlock(&pThis->m_lock); 782 783 /*process message if we have one*/ 784 if (qsize > 0) { 785 id = ident; 786 switch (id) { 787 case OMX_COMPONENT_GENERATE_EVENT: 788 if (pThis->m_cb.EventHandler) { 789 switch (p1) { 790 case OMX_CommandStateSet: 791 pThis->m_state = (OMX_STATETYPE) p2; 792 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", 793 pThis->m_state); 794 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 795 OMX_EventCmdComplete, p1, p2, NULL); 796 break; 797 798 case OMX_EventError: 799 if (p2 == OMX_StateInvalid) { 800 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid"); 801 pThis->m_state = (OMX_STATETYPE) p2; 802 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 803 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 804 } else if (p2 == OMX_ErrorHardware) { 805 pThis->omx_report_error(); 806 } else { 807 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 808 OMX_EventError, p2, (OMX_U32)NULL, NULL ); 809 } 810 break; 811 812 case OMX_CommandPortDisable: 813 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2); 814 if (BITMASK_PRESENT(&pThis->m_flags, 815 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 816 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 817 break; 818 } 819 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) { 820 OMX_ERRORTYPE eRet = OMX_ErrorNone; 821 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 822 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) 823 DEBUG_PRINT_HIGH("Failed to release output buffers"); 824 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); 825 pThis->in_reconfig = false; 826 if (eRet != OMX_ErrorNone) { 827 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); 828 pThis->omx_report_error(); 829 break; 830 } 831 } 832 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 833 OMX_EventCmdComplete, p1, p2, NULL ); 834 break; 835 case OMX_CommandPortEnable: 836 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2); 837 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 838 OMX_EventCmdComplete, p1, p2, NULL ); 839 break; 840 841 default: 842 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 843 OMX_EventCmdComplete, p1, p2, NULL ); 844 break; 845 846 } 847 } else { 848 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 849 } 850 break; 851 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 852 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 853 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 854 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure"); 855 pThis->omx_report_error (); 856 } 857 break; 858 case OMX_COMPONENT_GENERATE_ETB: 859 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 860 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 861 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); 862 pThis->omx_report_error (); 863 } 864 break; 865 866 case OMX_COMPONENT_GENERATE_FTB: 867 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 868 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { 869 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure"); 870 pThis->omx_report_error (); 871 } 872 break; 873 874 case OMX_COMPONENT_GENERATE_COMMAND: 875 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 876 (OMX_U32)p2,(OMX_PTR)NULL); 877 break; 878 879 case OMX_COMPONENT_GENERATE_EBD: 880 881 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) { 882 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure"); 883 pThis->omx_report_error (); 884 } else { 885 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) { 886 pThis->m_inp_err_count++; 887 pThis->time_stamp_dts.remove_time_stamp( 888 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, 889 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 890 ?true:false); 891 } else { 892 pThis->m_inp_err_count = 0; 893 } 894 if ( pThis->empty_buffer_done(&pThis->m_cmp, 895 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 896 DEBUG_PRINT_ERROR("empty_buffer_done failure"); 897 pThis->omx_report_error (); 898 } 899 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) { 900 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); 901 pThis->omx_report_error (); 902 } 903 } 904 break; 905 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: 906 { 907 int64_t *timestamp = (int64_t *)p1; 908 if (p1) { 909 pThis->time_stamp_dts.remove_time_stamp(*timestamp, 910 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 911 ?true:false); 912 free(timestamp); 913 } 914 } 915 break; 916 case OMX_COMPONENT_GENERATE_FBD: 917 if (p2 != VDEC_S_SUCCESS) { 918 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure"); 919 pThis->omx_report_error (); 920 } else if ( pThis->fill_buffer_done(&pThis->m_cmp, 921 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 922 DEBUG_PRINT_ERROR("fill_buffer_done failure"); 923 pThis->omx_report_error (); 924 } 925 break; 926 927 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 928 DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); 929 if (!pThis->input_flush_progress) { 930 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 931 } else { 932 pThis->execute_input_flush(); 933 if (pThis->m_cb.EventHandler) { 934 if (p2 != VDEC_S_SUCCESS) { 935 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 936 pThis->omx_report_error (); 937 } else { 938 /*Check if we need generate event for Flush done*/ 939 if (BITMASK_PRESENT(&pThis->m_flags, 940 OMX_COMPONENT_INPUT_FLUSH_PENDING)) { 941 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 942 DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); 943 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 944 OMX_EventCmdComplete,OMX_CommandFlush, 945 OMX_CORE_INPUT_PORT_INDEX,NULL ); 946 } 947 if (BITMASK_PRESENT(&pThis->m_flags, 948 OMX_COMPONENT_IDLE_PENDING)) { 949 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { 950 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port"); 951 pThis->omx_report_error (); 952 } else { 953 pThis->streaming[OUTPUT_PORT] = false; 954 } 955 if (!pThis->output_flush_progress) { 956 DEBUG_PRINT_LOW("Input flush done hence issue stop"); 957 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 958 OMX_COMPONENT_GENERATE_STOP_DONE); 959 } 960 } 961 } 962 } else { 963 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 964 } 965 } 966 break; 967 968 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 969 DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); 970 if (!pThis->output_flush_progress) { 971 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver"); 972 } else { 973 pThis->execute_output_flush(); 974 if (pThis->m_cb.EventHandler) { 975 if (p2 != VDEC_S_SUCCESS) { 976 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 977 pThis->omx_report_error (); 978 } else { 979 /*Check if we need generate event for Flush done*/ 980 if (BITMASK_PRESENT(&pThis->m_flags, 981 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) { 982 DEBUG_PRINT_LOW("Notify Output Flush done"); 983 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 984 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 985 OMX_EventCmdComplete,OMX_CommandFlush, 986 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 987 } 988 if (BITMASK_PRESENT(&pThis->m_flags, 989 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) { 990 DEBUG_PRINT_LOW("Internal flush complete"); 991 BITMASK_CLEAR (&pThis->m_flags, 992 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 993 if (BITMASK_PRESENT(&pThis->m_flags, 994 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) { 995 pThis->post_event(OMX_CommandPortDisable, 996 OMX_CORE_OUTPUT_PORT_INDEX, 997 OMX_COMPONENT_GENERATE_EVENT); 998 BITMASK_CLEAR (&pThis->m_flags, 999 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 1000 1001 } 1002 } 1003 1004 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) { 1005 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { 1006 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port"); 1007 pThis->omx_report_error (); 1008 break; 1009 } 1010 pThis->streaming[CAPTURE_PORT] = false; 1011 if (!pThis->input_flush_progress) { 1012 DEBUG_PRINT_LOW("Output flush done hence issue stop"); 1013 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ 1014 OMX_COMPONENT_GENERATE_STOP_DONE); 1015 } 1016 } 1017 } 1018 } else { 1019 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1020 } 1021 } 1022 break; 1023 1024 case OMX_COMPONENT_GENERATE_START_DONE: 1025 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); 1026 1027 if (pThis->m_cb.EventHandler) { 1028 if (p2 != VDEC_S_SUCCESS) { 1029 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure"); 1030 pThis->omx_report_error (); 1031 } else { 1032 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); 1033 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1034 DEBUG_PRINT_LOW("Move to executing"); 1035 // Send the callback now 1036 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1037 pThis->m_state = OMX_StateExecuting; 1038 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1039 OMX_EventCmdComplete,OMX_CommandStateSet, 1040 OMX_StateExecuting, NULL); 1041 } else if (BITMASK_PRESENT(&pThis->m_flags, 1042 OMX_COMPONENT_PAUSE_PENDING)) { 1043 if (/*ioctl (pThis->drv_ctx.video_driver_fd, 1044 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) { 1045 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed"); 1046 pThis->omx_report_error (); 1047 } 1048 } 1049 } 1050 } else { 1051 DEBUG_PRINT_LOW("Event Handler callback is NULL"); 1052 } 1053 break; 1054 1055 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 1056 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 1057 if (pThis->m_cb.EventHandler) { 1058 if (p2 != VDEC_S_SUCCESS) { 1059 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 1060 pThis->omx_report_error (); 1061 } else { 1062 pThis->complete_pending_buffer_done_cbs(); 1063 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) { 1064 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 1065 //Send the callback now 1066 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 1067 pThis->m_state = OMX_StatePause; 1068 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1069 OMX_EventCmdComplete,OMX_CommandStateSet, 1070 OMX_StatePause, NULL); 1071 } 1072 } 1073 } else { 1074 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1075 } 1076 1077 break; 1078 1079 case OMX_COMPONENT_GENERATE_RESUME_DONE: 1080 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 1081 if (pThis->m_cb.EventHandler) { 1082 if (p2 != VDEC_S_SUCCESS) { 1083 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 1084 pThis->omx_report_error (); 1085 } else { 1086 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { 1087 DEBUG_PRINT_LOW("Moving the decoder to execute state"); 1088 // Send the callback now 1089 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1090 pThis->m_state = OMX_StateExecuting; 1091 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1092 OMX_EventCmdComplete,OMX_CommandStateSet, 1093 OMX_StateExecuting,NULL); 1094 } 1095 } 1096 } else { 1097 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1098 } 1099 1100 break; 1101 1102 case OMX_COMPONENT_GENERATE_STOP_DONE: 1103 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 1104 if (pThis->m_cb.EventHandler) { 1105 if (p2 != VDEC_S_SUCCESS) { 1106 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 1107 pThis->omx_report_error (); 1108 } else { 1109 pThis->complete_pending_buffer_done_cbs(); 1110 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) { 1111 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); 1112 // Send the callback now 1113 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 1114 pThis->m_state = OMX_StateIdle; 1115 DEBUG_PRINT_LOW("Move to Idle State"); 1116 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 1117 OMX_EventCmdComplete,OMX_CommandStateSet, 1118 OMX_StateIdle,NULL); 1119 } 1120 } 1121 } else { 1122 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1123 } 1124 1125 break; 1126 1127 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 1128 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); 1129 1130 if (p2 == OMX_IndexParamPortDefinition) { 1131 pThis->in_reconfig = true; 1132 } 1133 if (pThis->m_cb.EventHandler) { 1134 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1135 OMX_EventPortSettingsChanged, p1, p2, NULL ); 1136 } else { 1137 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1138 } 1139 1140 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) { 1141 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; 1142 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; 1143 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 1144 format = OMX_InterlaceInterleaveFrameTopFieldFirst; 1145 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 1146 format = OMX_InterlaceInterleaveFrameBottomFieldFirst; 1147 else //unsupported interlace format; raise a error 1148 event = OMX_EventError; 1149 if (pThis->m_cb.EventHandler) { 1150 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1151 event, format, 0, NULL ); 1152 } else { 1153 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1154 } 1155 } 1156 break; 1157 1158 case OMX_COMPONENT_GENERATE_EOS_DONE: 1159 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); 1160 if (pThis->m_cb.EventHandler) { 1161 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, 1162 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); 1163 } else { 1164 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1165 } 1166 pThis->prev_ts = LLONG_MAX; 1167 pThis->rst_prev_ts = true; 1168 break; 1169 1170 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 1171 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 1172 pThis->omx_report_error (); 1173 break; 1174 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: 1175 { 1176 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); 1177 if (pThis->m_cb.EventHandler) { 1178 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1179 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); 1180 } else { 1181 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1182 } 1183 } 1184 default: 1185 break; 1186 } 1187 } 1188 pthread_mutex_lock(&pThis->m_lock); 1189 qsize = pThis->m_cmd_q.m_size; 1190 if (pThis->m_state != OMX_StatePause) 1191 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); 1192 pthread_mutex_unlock(&pThis->m_lock); 1193 } while (qsize>0); 1194 1195} 1196 1197void omx_vdec::update_resolution(int width, int height) 1198{ 1199 drv_ctx.video_resolution.frame_height = height; 1200 drv_ctx.video_resolution.frame_width = width; 1201 drv_ctx.video_resolution.scan_lines = height; 1202 drv_ctx.video_resolution.stride = width; 1203 rectangle.nLeft = 0; 1204 rectangle.nTop = 0; 1205 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 1206 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 1207} 1208 1209/* ====================================================================== 1210 FUNCTION 1211 omx_vdec::ComponentInit 1212 1213 DESCRIPTION 1214 Initialize the component. 1215 1216 PARAMETERS 1217 ctxt -- Context information related to the self. 1218 id -- Event identifier. This could be any of the following: 1219 1. Command completion event 1220 2. Buffer done callback event 1221 3. Frame done callback event 1222 1223 RETURN VALUE 1224 None. 1225 1226 ========================================================================== */ 1227OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 1228{ 1229 1230 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1231 struct v4l2_fmtdesc fdesc; 1232 struct v4l2_format fmt; 1233 struct v4l2_requestbuffers bufreq; 1234 struct v4l2_control control; 1235 unsigned int alignment = 0,buffer_size = 0; 1236 int fds[2]; 1237 int r,ret=0; 1238 bool codec_ambiguous = false; 1239 OMX_STRING device_name = (OMX_STRING)DEVICE_NAME; 1240 DEBUG_PRINT_LOW("Opening device %s", device_name); 1241 drv_ctx.video_driver_fd = open(device_name, O_RDWR); 1242 1243 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open device %s returned fd %d, errno %d", 1244 device_name, drv_ctx.video_driver_fd, errno); 1245 1246 if (drv_ctx.video_driver_fd == 0) { 1247 drv_ctx.video_driver_fd = open(device_name, O_RDWR); 1248 } 1249 1250 if (drv_ctx.video_driver_fd < 0) { 1251 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno); 1252 return OMX_ErrorInsufficientResources; 1253 } 1254 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; 1255 drv_ctx.frame_rate.fps_denominator = 1; 1256 1257 ret = pthread_create(&async_thread_id,0,async_message_thread,this); 1258 if (ret < 0) { 1259 close(drv_ctx.video_driver_fd); 1260 DEBUG_PRINT_ERROR("Failed to create async_message_thread"); 1261 return OMX_ErrorInsufficientResources; 1262 } 1263 1264#ifdef INPUT_BUFFER_LOG 1265 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); 1266#endif 1267#ifdef OUTPUT_BUFFER_LOG 1268 outputBufferFile1 = fopen (outputfilename, "ab"); 1269#endif 1270#ifdef OUTPUT_EXTRADATA_LOG 1271 outputExtradataFile = fopen (ouputextradatafilename, "ab"); 1272#endif 1273 1274 // Copy the role information which provides the decoder kind 1275 strlcpy(drv_ctx.kind,role,128); 1276 1277 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ 1278 OMX_MAX_STRINGNAME_SIZE)) { 1279 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ 1280 OMX_MAX_STRINGNAME_SIZE); 1281 drv_ctx.timestamp_adjust = true; 1282 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; 1283 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 1284 output_capability=V4L2_PIX_FMT_MPEG4; 1285 /*Initialize Start Code for MPEG4*/ 1286 codec_type_parse = CODEC_TYPE_MPEG4; 1287 m_frame_parser.init_start_codes (codec_type_parse); 1288#ifdef INPUT_BUFFER_LOG 1289 strcat(inputfilename, "m4v"); 1290#endif 1291 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ 1292 OMX_MAX_STRINGNAME_SIZE)) { 1293 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ 1294 OMX_MAX_STRINGNAME_SIZE); 1295 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; 1296 output_capability = V4L2_PIX_FMT_MPEG2; 1297 eCompressionFormat = OMX_VIDEO_CodingMPEG2; 1298 /*Initialize Start Code for MPEG2*/ 1299 codec_type_parse = CODEC_TYPE_MPEG2; 1300 m_frame_parser.init_start_codes (codec_type_parse); 1301#ifdef INPUT_BUFFER_LOG 1302 strcat(inputfilename, "mpg"); 1303#endif 1304 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ 1305 OMX_MAX_STRINGNAME_SIZE)) { 1306 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 1307 DEBUG_PRINT_LOW("H263 Decoder selected"); 1308 drv_ctx.decoder_format = VDEC_CODECTYPE_H263; 1309 eCompressionFormat = OMX_VIDEO_CodingH263; 1310 output_capability = V4L2_PIX_FMT_H263; 1311 codec_type_parse = CODEC_TYPE_H263; 1312 m_frame_parser.init_start_codes (codec_type_parse); 1313#ifdef INPUT_BUFFER_LOG 1314 strcat(inputfilename, "263"); 1315#endif 1316 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ 1317 OMX_MAX_STRINGNAME_SIZE)) { 1318 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1319 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); 1320 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; 1321 output_capability = V4L2_PIX_FMT_DIVX_311; 1322 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1323 codec_type_parse = CODEC_TYPE_DIVX; 1324 m_frame_parser.init_start_codes (codec_type_parse); 1325 1326 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 1327 OMX_MAX_STRINGNAME_SIZE)) { 1328 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1329 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); 1330 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; 1331 output_capability = V4L2_PIX_FMT_DIVX; 1332 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1333 codec_type_parse = CODEC_TYPE_DIVX; 1334 codec_ambiguous = true; 1335 m_frame_parser.init_start_codes (codec_type_parse); 1336 1337 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ 1338 OMX_MAX_STRINGNAME_SIZE)) { 1339 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1340 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); 1341 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; 1342 output_capability = V4L2_PIX_FMT_DIVX; 1343 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1344 codec_type_parse = CODEC_TYPE_DIVX; 1345 codec_ambiguous = true; 1346 m_frame_parser.init_start_codes (codec_type_parse); 1347 1348 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ 1349 OMX_MAX_STRINGNAME_SIZE)) { 1350 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 1351 drv_ctx.decoder_format = VDEC_CODECTYPE_H264; 1352 output_capability=V4L2_PIX_FMT_H264; 1353 eCompressionFormat = OMX_VIDEO_CodingAVC; 1354 codec_type_parse = CODEC_TYPE_H264; 1355 m_frame_parser.init_start_codes (codec_type_parse); 1356 m_frame_parser.init_nal_length(nal_length); 1357#ifdef INPUT_BUFFER_LOG 1358 strcat(inputfilename, "264"); 1359#endif 1360 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ 1361 OMX_MAX_STRINGNAME_SIZE)) { 1362 strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 1363 drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; 1364 output_capability=V4L2_PIX_FMT_HEVC; 1365 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; 1366 codec_type_parse = CODEC_TYPE_HEVC; 1367 m_frame_parser.init_start_codes (codec_type_parse); 1368 m_frame_parser.init_nal_length(nal_length); 1369#ifdef INPUT_BUFFER_LOG 1370 strcat(inputfilename, "265"); 1371#endif 1372 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ 1373 OMX_MAX_STRINGNAME_SIZE)) { 1374 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 1375 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; 1376 eCompressionFormat = OMX_VIDEO_CodingWMV; 1377 codec_type_parse = CODEC_TYPE_VC1; 1378 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; 1379 m_frame_parser.init_start_codes (codec_type_parse); 1380#ifdef INPUT_BUFFER_LOG 1381 strcat(inputfilename, "vc1"); 1382#endif 1383 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ 1384 OMX_MAX_STRINGNAME_SIZE)) { 1385 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 1386 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; 1387 eCompressionFormat = OMX_VIDEO_CodingWMV; 1388 codec_type_parse = CODEC_TYPE_VC1; 1389 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; 1390 m_frame_parser.init_start_codes (codec_type_parse); 1391#ifdef INPUT_BUFFER_LOG 1392 strcat(inputfilename, "vc1"); 1393#endif 1394 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",\ 1395 OMX_MAX_STRINGNAME_SIZE)) { 1396 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 1397 output_capability=V4L2_PIX_FMT_VP8; 1398 eCompressionFormat = OMX_VIDEO_CodingVP8; 1399 codec_type_parse = CODEC_TYPE_VP8; 1400 arbitrary_bytes = false; 1401 } else { 1402 DEBUG_PRINT_ERROR("ERROR:Unknown Component"); 1403 eRet = OMX_ErrorInvalidComponentName; 1404 } 1405#ifdef INPUT_BUFFER_LOG 1406 inputBufferFile1 = fopen (inputfilename, "ab"); 1407#endif 1408 if (eRet == OMX_ErrorNone) { 1409 1410 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 1411 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) 1412 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 1413 if (!client_buffers.set_color_format(dest_color_format)) { 1414 DEBUG_PRINT_ERROR("Setting color format failed"); 1415 eRet = OMX_ErrorInsufficientResources; 1416 } 1417 1418 capture_capability= V4L2_PIX_FMT_NV12; 1419 ret = subscribe_to_events(drv_ctx.video_driver_fd); 1420 if (ret) { 1421 DEBUG_PRINT_ERROR("Subscribe Event Failed"); 1422 return OMX_ErrorInsufficientResources; 1423 } 1424 1425 struct v4l2_capability cap; 1426 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); 1427 if (ret) { 1428 DEBUG_PRINT_ERROR("Failed to query capabilities"); 1429 /*TODO: How to handle this case */ 1430 } else { 1431 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s," 1432 " version = %d, capabilities = %x", cap.driver, cap.card, 1433 cap.bus_info, cap.version, cap.capabilities); 1434 } 1435 ret=0; 1436 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1437 fdesc.index=0; 1438 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 1439 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 1440 fdesc.pixelformat, fdesc.flags); 1441 fdesc.index++; 1442 } 1443 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1444 fdesc.index=0; 1445 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 1446 1447 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 1448 fdesc.pixelformat, fdesc.flags); 1449 fdesc.index++; 1450 } 1451 update_resolution(320, 240); 1452 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1453 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 1454 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 1455 fmt.fmt.pix_mp.pixelformat = output_capability; 1456 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1457 if (ret) { 1458 /*TODO: How to handle this case */ 1459 DEBUG_PRINT_ERROR("Failed to set format on output port"); 1460 } 1461 DEBUG_PRINT_HIGH("Set Format was successful"); 1462 if (codec_ambiguous) { 1463 if (output_capability == V4L2_PIX_FMT_DIVX) { 1464 struct v4l2_control divx_ctrl; 1465 1466 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { 1467 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; 1468 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { 1469 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; 1470 } else { 1471 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; 1472 } 1473 1474 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; 1475 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); 1476 if (ret) { 1477 DEBUG_PRINT_ERROR("Failed to set divx version"); 1478 } 1479 } else { 1480 DEBUG_PRINT_ERROR("Codec should not be ambiguous"); 1481 } 1482 } 1483 1484 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1485 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 1486 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 1487 fmt.fmt.pix_mp.pixelformat = capture_capability; 1488 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 1489 if (ret) { 1490 /*TODO: How to handle this case */ 1491 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 1492 } 1493 DEBUG_PRINT_HIGH("Set Format was successful"); 1494 if (secure_mode) { 1495 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 1496 control.value = 1; 1497 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret); 1498 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 1499 if (ret) { 1500 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret); 1501 close(drv_ctx.video_driver_fd); 1502 return OMX_ErrorInsufficientResources; 1503 } 1504 } 1505 1506 /*Get the Buffer requirements for input and output ports*/ 1507 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; 1508 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 1509 if (secure_mode) { 1510 drv_ctx.op_buf.alignment=SZ_1M; 1511 drv_ctx.ip_buf.alignment=SZ_1M; 1512 } else { 1513 drv_ctx.op_buf.alignment=SZ_4K; 1514 drv_ctx.ip_buf.alignment=SZ_4K; 1515 } 1516 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 1517 drv_ctx.extradata = 0; 1518 drv_ctx.picture_order = VDEC_ORDER_DISPLAY; 1519 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 1520 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 1521 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 1522 drv_ctx.idr_only_decoding = 0; 1523 1524 m_state = OMX_StateLoaded; 1525#ifdef DEFAULT_EXTRADATA 1526 if (eRet == OMX_ErrorNone && !secure_mode) 1527 enable_extradata(DEFAULT_EXTRADATA, true, true); 1528#endif 1529 eRet=get_buffer_req(&drv_ctx.ip_buf); 1530 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size); 1531 get_buffer_req(&drv_ctx.op_buf); 1532 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || 1533 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC) { 1534 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; 1535 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); 1536 h264_scratch.nFilledLen = 0; 1537 h264_scratch.nOffset = 0; 1538 1539 if (h264_scratch.pBuffer == NULL) { 1540 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed "); 1541 return OMX_ErrorInsufficientResources; 1542 } 1543 } 1544 1545 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) { 1546 if (m_frame_parser.mutils == NULL) { 1547 m_frame_parser.mutils = new H264_Utils(); 1548 1549 if (m_frame_parser.mutils == NULL) { 1550 DEBUG_PRINT_ERROR("parser utils Allocation failed "); 1551 eRet = OMX_ErrorInsufficientResources; 1552 } else { 1553 m_frame_parser.mutils->initialize_frame_checking_environment(); 1554 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); 1555 } 1556 } 1557 1558 h264_parser = new h264_stream_parser(); 1559 if (!h264_parser) { 1560 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); 1561 eRet = OMX_ErrorInsufficientResources; 1562 } 1563 } 1564 1565 if (pipe(fds)) { 1566 DEBUG_PRINT_ERROR("pipe creation failed"); 1567 eRet = OMX_ErrorInsufficientResources; 1568 } else { 1569 int temp1[2]; 1570 if (fds[0] == 0 || fds[1] == 0) { 1571 if (pipe (temp1)) { 1572 DEBUG_PRINT_ERROR("pipe creation failed"); 1573 return OMX_ErrorInsufficientResources; 1574 } 1575 //close (fds[0]); 1576 //close (fds[1]); 1577 fds[0] = temp1 [0]; 1578 fds[1] = temp1 [1]; 1579 } 1580 m_pipe_in = fds[0]; 1581 m_pipe_out = fds[1]; 1582 r = pthread_create(&msg_thread_id,0,message_thread,this); 1583 1584 if (r < 0) { 1585 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed"); 1586 eRet = OMX_ErrorInsufficientResources; 1587 } 1588 } 1589 } 1590 1591 if (eRet != OMX_ErrorNone) { 1592 DEBUG_PRINT_ERROR("Component Init Failed"); 1593 DEBUG_PRINT_HIGH("Calling VDEC_IOCTL_STOP_NEXT_MSG"); 1594 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 1595 NULL); 1596 DEBUG_PRINT_HIGH("Calling close() on Video Driver"); 1597 close (drv_ctx.video_driver_fd); 1598 drv_ctx.video_driver_fd = -1; 1599 } else { 1600 DEBUG_PRINT_HIGH("omx_vdec::component_init() success"); 1601 } 1602 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); 1603 return eRet; 1604} 1605 1606/* ====================================================================== 1607 FUNCTION 1608 omx_vdec::GetComponentVersion 1609 1610 DESCRIPTION 1611 Returns the component version. 1612 1613 PARAMETERS 1614 TBD. 1615 1616 RETURN VALUE 1617 OMX_ErrorNone. 1618 1619 ========================================================================== */ 1620OMX_ERRORTYPE omx_vdec::get_component_version 1621( 1622 OMX_IN OMX_HANDLETYPE hComp, 1623 OMX_OUT OMX_STRING componentName, 1624 OMX_OUT OMX_VERSIONTYPE* componentVersion, 1625 OMX_OUT OMX_VERSIONTYPE* specVersion, 1626 OMX_OUT OMX_UUIDTYPE* componentUUID 1627 ) 1628{ 1629 if (m_state == OMX_StateInvalid) { 1630 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State"); 1631 return OMX_ErrorInvalidState; 1632 } 1633 /* TBD -- Return the proper version */ 1634 if (specVersion) { 1635 specVersion->nVersion = OMX_SPEC_VERSION; 1636 } 1637 return OMX_ErrorNone; 1638} 1639/* ====================================================================== 1640 FUNCTION 1641 omx_vdec::SendCommand 1642 1643 DESCRIPTION 1644 Returns zero if all the buffers released.. 1645 1646 PARAMETERS 1647 None. 1648 1649 RETURN VALUE 1650 true/false 1651 1652 ========================================================================== */ 1653OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 1654 OMX_IN OMX_COMMANDTYPE cmd, 1655 OMX_IN OMX_U32 param1, 1656 OMX_IN OMX_PTR cmdData 1657 ) 1658{ 1659 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client"); 1660 if (m_state == OMX_StateInvalid) { 1661 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State"); 1662 return OMX_ErrorInvalidState; 1663 } 1664 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX 1665 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) { 1666 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush " 1667 "to invalid port: %lu", param1); 1668 return OMX_ErrorBadPortIndex; 1669 } 1670 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 1671 sem_wait(&m_cmd_lock); 1672 DEBUG_PRINT_LOW("send_command: Command Processed"); 1673 return OMX_ErrorNone; 1674} 1675 1676/* ====================================================================== 1677 FUNCTION 1678 omx_vdec::SendCommand 1679 1680 DESCRIPTION 1681 Returns zero if all the buffers released.. 1682 1683 PARAMETERS 1684 None. 1685 1686 RETURN VALUE 1687 true/false 1688 1689 ========================================================================== */ 1690OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 1691 OMX_IN OMX_COMMANDTYPE cmd, 1692 OMX_IN OMX_U32 param1, 1693 OMX_IN OMX_PTR cmdData 1694 ) 1695{ 1696 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1697 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 1698 int bFlag = 1,sem_posted = 0,ret=0; 1699 1700 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd); 1701 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d", 1702 m_state, eState); 1703 1704 if (cmd == OMX_CommandStateSet) { 1705 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); 1706 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); 1707 /***************************/ 1708 /* Current State is Loaded */ 1709 /***************************/ 1710 if (m_state == OMX_StateLoaded) { 1711 if (eState == OMX_StateIdle) { 1712 //if all buffers are allocated or all ports disabled 1713 if (allocate_done() || 1714 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) { 1715 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); 1716 } else { 1717 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); 1718 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 1719 // Skip the event notification 1720 bFlag = 0; 1721 } 1722 } 1723 /* Requesting transition from Loaded to Loaded */ 1724 else if (eState == OMX_StateLoaded) { 1725 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded"); 1726 post_event(OMX_EventError,OMX_ErrorSameState,\ 1727 OMX_COMPONENT_GENERATE_EVENT); 1728 eRet = OMX_ErrorSameState; 1729 } 1730 /* Requesting transition from Loaded to WaitForResources */ 1731 else if (eState == OMX_StateWaitForResources) { 1732 /* Since error is None , we will post an event 1733 at the end of this function definition */ 1734 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); 1735 } 1736 /* Requesting transition from Loaded to Executing */ 1737 else if (eState == OMX_StateExecuting) { 1738 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing"); 1739 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1740 OMX_COMPONENT_GENERATE_EVENT); 1741 eRet = OMX_ErrorIncorrectStateTransition; 1742 } 1743 /* Requesting transition from Loaded to Pause */ 1744 else if (eState == OMX_StatePause) { 1745 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause"); 1746 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1747 OMX_COMPONENT_GENERATE_EVENT); 1748 eRet = OMX_ErrorIncorrectStateTransition; 1749 } 1750 /* Requesting transition from Loaded to Invalid */ 1751 else if (eState == OMX_StateInvalid) { 1752 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid"); 1753 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1754 eRet = OMX_ErrorInvalidState; 1755 } else { 1756 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\ 1757 eState); 1758 eRet = OMX_ErrorBadParameter; 1759 } 1760 } 1761 1762 /***************************/ 1763 /* Current State is IDLE */ 1764 /***************************/ 1765 else if (m_state == OMX_StateIdle) { 1766 if (eState == OMX_StateLoaded) { 1767 if (release_done()) { 1768 /* 1769 Since error is None , we will post an event at the end 1770 of this function definition 1771 */ 1772 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded"); 1773 } else { 1774 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending"); 1775 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 1776 // Skip the event notification 1777 bFlag = 0; 1778 } 1779 } 1780 /* Requesting transition from Idle to Executing */ 1781 else if (eState == OMX_StateExecuting) { 1782 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 1783 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); 1784 bFlag = 1; 1785 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 1786 m_state=OMX_StateExecuting; 1787 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful"); 1788 } 1789 /* Requesting transition from Idle to Idle */ 1790 else if (eState == OMX_StateIdle) { 1791 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle"); 1792 post_event(OMX_EventError,OMX_ErrorSameState,\ 1793 OMX_COMPONENT_GENERATE_EVENT); 1794 eRet = OMX_ErrorSameState; 1795 } 1796 /* Requesting transition from Idle to WaitForResources */ 1797 else if (eState == OMX_StateWaitForResources) { 1798 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources"); 1799 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1800 OMX_COMPONENT_GENERATE_EVENT); 1801 eRet = OMX_ErrorIncorrectStateTransition; 1802 } 1803 /* Requesting transition from Idle to Pause */ 1804 else if (eState == OMX_StatePause) { 1805 /*To pause the Video core we need to start the driver*/ 1806 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 1807 NULL) < */0) { 1808 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED"); 1809 omx_report_error (); 1810 eRet = OMX_ErrorHardware; 1811 } else { 1812 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 1813 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause"); 1814 bFlag = 0; 1815 } 1816 } 1817 /* Requesting transition from Idle to Invalid */ 1818 else if (eState == OMX_StateInvalid) { 1819 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid"); 1820 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1821 eRet = OMX_ErrorInvalidState; 1822 } else { 1823 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState); 1824 eRet = OMX_ErrorBadParameter; 1825 } 1826 } 1827 1828 /******************************/ 1829 /* Current State is Executing */ 1830 /******************************/ 1831 else if (m_state == OMX_StateExecuting) { 1832 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting"); 1833 /* Requesting transition from Executing to Idle */ 1834 if (eState == OMX_StateIdle) { 1835 /* Since error is None , we will post an event 1836 at the end of this function definition 1837 */ 1838 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle"); 1839 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1840 if (!sem_posted) { 1841 sem_posted = 1; 1842 sem_post (&m_cmd_lock); 1843 execute_omx_flush(OMX_ALL); 1844 } 1845 bFlag = 0; 1846 } 1847 /* Requesting transition from Executing to Paused */ 1848 else if (eState == OMX_StatePause) { 1849 DEBUG_PRINT_LOW("PAUSE Command Issued"); 1850 m_state = OMX_StatePause; 1851 bFlag = 1; 1852 } 1853 /* Requesting transition from Executing to Loaded */ 1854 else if (eState == OMX_StateLoaded) { 1855 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded"); 1856 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1857 OMX_COMPONENT_GENERATE_EVENT); 1858 eRet = OMX_ErrorIncorrectStateTransition; 1859 } 1860 /* Requesting transition from Executing to WaitForResources */ 1861 else if (eState == OMX_StateWaitForResources) { 1862 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources"); 1863 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1864 OMX_COMPONENT_GENERATE_EVENT); 1865 eRet = OMX_ErrorIncorrectStateTransition; 1866 } 1867 /* Requesting transition from Executing to Executing */ 1868 else if (eState == OMX_StateExecuting) { 1869 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing"); 1870 post_event(OMX_EventError,OMX_ErrorSameState,\ 1871 OMX_COMPONENT_GENERATE_EVENT); 1872 eRet = OMX_ErrorSameState; 1873 } 1874 /* Requesting transition from Executing to Invalid */ 1875 else if (eState == OMX_StateInvalid) { 1876 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid"); 1877 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1878 eRet = OMX_ErrorInvalidState; 1879 } else { 1880 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState); 1881 eRet = OMX_ErrorBadParameter; 1882 } 1883 } 1884 /***************************/ 1885 /* Current State is Pause */ 1886 /***************************/ 1887 else if (m_state == OMX_StatePause) { 1888 /* Requesting transition from Pause to Executing */ 1889 if (eState == OMX_StateExecuting) { 1890 DEBUG_PRINT_LOW("Pause --> Executing"); 1891 m_state = OMX_StateExecuting; 1892 bFlag = 1; 1893 } 1894 /* Requesting transition from Pause to Idle */ 1895 else if (eState == OMX_StateIdle) { 1896 /* Since error is None , we will post an event 1897 at the end of this function definition */ 1898 DEBUG_PRINT_LOW("Pause --> Idle"); 1899 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1900 if (!sem_posted) { 1901 sem_posted = 1; 1902 sem_post (&m_cmd_lock); 1903 execute_omx_flush(OMX_ALL); 1904 } 1905 bFlag = 0; 1906 } 1907 /* Requesting transition from Pause to loaded */ 1908 else if (eState == OMX_StateLoaded) { 1909 DEBUG_PRINT_ERROR("Pause --> loaded"); 1910 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1911 OMX_COMPONENT_GENERATE_EVENT); 1912 eRet = OMX_ErrorIncorrectStateTransition; 1913 } 1914 /* Requesting transition from Pause to WaitForResources */ 1915 else if (eState == OMX_StateWaitForResources) { 1916 DEBUG_PRINT_ERROR("Pause --> WaitForResources"); 1917 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1918 OMX_COMPONENT_GENERATE_EVENT); 1919 eRet = OMX_ErrorIncorrectStateTransition; 1920 } 1921 /* Requesting transition from Pause to Pause */ 1922 else if (eState == OMX_StatePause) { 1923 DEBUG_PRINT_ERROR("Pause --> Pause"); 1924 post_event(OMX_EventError,OMX_ErrorSameState,\ 1925 OMX_COMPONENT_GENERATE_EVENT); 1926 eRet = OMX_ErrorSameState; 1927 } 1928 /* Requesting transition from Pause to Invalid */ 1929 else if (eState == OMX_StateInvalid) { 1930 DEBUG_PRINT_ERROR("Pause --> Invalid"); 1931 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1932 eRet = OMX_ErrorInvalidState; 1933 } else { 1934 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState); 1935 eRet = OMX_ErrorBadParameter; 1936 } 1937 } 1938 /***************************/ 1939 /* Current State is WaitForResources */ 1940 /***************************/ 1941 else if (m_state == OMX_StateWaitForResources) { 1942 /* Requesting transition from WaitForResources to Loaded */ 1943 if (eState == OMX_StateLoaded) { 1944 /* Since error is None , we will post an event 1945 at the end of this function definition */ 1946 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded"); 1947 } 1948 /* Requesting transition from WaitForResources to WaitForResources */ 1949 else if (eState == OMX_StateWaitForResources) { 1950 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources"); 1951 post_event(OMX_EventError,OMX_ErrorSameState, 1952 OMX_COMPONENT_GENERATE_EVENT); 1953 eRet = OMX_ErrorSameState; 1954 } 1955 /* Requesting transition from WaitForResources to Executing */ 1956 else if (eState == OMX_StateExecuting) { 1957 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing"); 1958 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1959 OMX_COMPONENT_GENERATE_EVENT); 1960 eRet = OMX_ErrorIncorrectStateTransition; 1961 } 1962 /* Requesting transition from WaitForResources to Pause */ 1963 else if (eState == OMX_StatePause) { 1964 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause"); 1965 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1966 OMX_COMPONENT_GENERATE_EVENT); 1967 eRet = OMX_ErrorIncorrectStateTransition; 1968 } 1969 /* Requesting transition from WaitForResources to Invalid */ 1970 else if (eState == OMX_StateInvalid) { 1971 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid"); 1972 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1973 eRet = OMX_ErrorInvalidState; 1974 } 1975 /* Requesting transition from WaitForResources to Loaded - 1976 is NOT tested by Khronos TS */ 1977 1978 } else { 1979 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState); 1980 eRet = OMX_ErrorBadParameter; 1981 } 1982 } 1983 /********************************/ 1984 /* Current State is Invalid */ 1985 /*******************************/ 1986 else if (m_state == OMX_StateInvalid) { 1987 /* State Transition from Inavlid to any state */ 1988 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources 1989 || OMX_StateIdle || OMX_StateExecuting 1990 || OMX_StatePause || OMX_StateInvalid)) { 1991 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded"); 1992 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 1993 OMX_COMPONENT_GENERATE_EVENT); 1994 eRet = OMX_ErrorInvalidState; 1995 } 1996 } else if (cmd == OMX_CommandFlush) { 1997 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued" 1998 "with param1: %lu", param1); 1999 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 2000 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 2001 } 2002 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) { 2003 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 2004 } 2005 if (!sem_posted) { 2006 sem_posted = 1; 2007 DEBUG_PRINT_LOW("Set the Semaphore"); 2008 sem_post (&m_cmd_lock); 2009 execute_omx_flush(param1); 2010 } 2011 bFlag = 0; 2012 } else if ( cmd == OMX_CommandPortEnable) { 2013 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued" 2014 "with param1: %lu", param1); 2015 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 2016 m_inp_bEnabled = OMX_TRUE; 2017 2018 if ( (m_state == OMX_StateLoaded && 2019 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2020 || allocate_input_done()) { 2021 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 2022 OMX_COMPONENT_GENERATE_EVENT); 2023 } else { 2024 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 2025 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 2026 // Skip the event notification 2027 bFlag = 0; 2028 } 2029 } 2030 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 2031 DEBUG_PRINT_LOW("Enable output Port command recieved"); 2032 m_out_bEnabled = OMX_TRUE; 2033 2034 if ( (m_state == OMX_StateLoaded && 2035 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2036 || (allocate_output_done())) { 2037 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 2038 OMX_COMPONENT_GENERATE_EVENT); 2039 2040 } else { 2041 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending"); 2042 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2043 // Skip the event notification 2044 bFlag = 0; 2045 } 2046 } 2047 } else if (cmd == OMX_CommandPortDisable) { 2048 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued" 2049 "with param1: %lu", param1); 2050 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { 2051 m_inp_bEnabled = OMX_FALSE; 2052 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 2053 && release_input_done()) { 2054 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 2055 OMX_COMPONENT_GENERATE_EVENT); 2056 } else { 2057 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 2058 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 2059 if (!sem_posted) { 2060 sem_posted = 1; 2061 sem_post (&m_cmd_lock); 2062 } 2063 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 2064 } 2065 2066 // Skip the event notification 2067 bFlag = 0; 2068 } 2069 } 2070 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) { 2071 m_out_bEnabled = OMX_FALSE; 2072 DEBUG_PRINT_LOW("Disable output Port command recieved"); 2073 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 2074 && release_output_done()) { 2075 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 2076 OMX_COMPONENT_GENERATE_EVENT); 2077 } else { 2078 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 2079 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { 2080 if (!sem_posted) { 2081 sem_posted = 1; 2082 sem_post (&m_cmd_lock); 2083 } 2084 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 2085 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 2086 } 2087 // Skip the event notification 2088 bFlag = 0; 2089 2090 } 2091 } 2092 } else { 2093 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd); 2094 eRet = OMX_ErrorNotImplemented; 2095 } 2096 if (eRet == OMX_ErrorNone && bFlag) { 2097 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 2098 } 2099 if (!sem_posted) { 2100 sem_post(&m_cmd_lock); 2101 } 2102 2103 return eRet; 2104} 2105 2106/* ====================================================================== 2107 FUNCTION 2108 omx_vdec::ExecuteOmxFlush 2109 2110 DESCRIPTION 2111 Executes the OMX flush. 2112 2113 PARAMETERS 2114 flushtype - input flush(1)/output flush(0)/ both. 2115 2116 RETURN VALUE 2117 true/false 2118 2119 ========================================================================== */ 2120bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 2121{ 2122 bool bRet = false; 2123 struct v4l2_plane plane; 2124 struct v4l2_buffer v4l2_buf; 2125 struct v4l2_decoder_cmd dec; 2126 DEBUG_PRINT_LOW("in %s", __func__); 2127 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); 2128 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; 2129 switch (flushType) { 2130 case OMX_CORE_INPUT_PORT_INDEX: 2131 input_flush_progress = true; 2132 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT; 2133 break; 2134 case OMX_CORE_OUTPUT_PORT_INDEX: 2135 output_flush_progress = true; 2136 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 2137 break; 2138 default: 2139 input_flush_progress = true; 2140 output_flush_progress = true; 2141 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | 2142 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; 2143 } 2144 2145 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) { 2146 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType); 2147 bRet = false; 2148 } 2149 2150 return bRet; 2151} 2152/*========================================================================= 2153FUNCTION : execute_output_flush 2154 2155DESCRIPTION 2156Executes the OMX flush at OUTPUT PORT. 2157 2158PARAMETERS 2159None. 2160 2161RETURN VALUE 2162true/false 2163==========================================================================*/ 2164bool omx_vdec::execute_output_flush() 2165{ 2166 unsigned p1 = 0; // Parameter - 1 2167 unsigned p2 = 0; // Parameter - 2 2168 unsigned ident = 0; 2169 bool bRet = true; 2170 2171 /*Generate FBD for all Buffers in the FTBq*/ 2172 pthread_mutex_lock(&m_lock); 2173 DEBUG_PRINT_LOW("Initiate Output Flush"); 2174 while (m_ftb_q.m_size) { 2175 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d", 2176 m_ftb_q.m_size,pending_output_buffers); 2177 m_ftb_q.pop_entry(&p1,&p2,&ident); 2178 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2); 2179 if (ident == m_fill_output_msg ) { 2180 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 2181 } else if (ident == OMX_COMPONENT_GENERATE_FBD) { 2182 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 2183 } 2184 } 2185 pthread_mutex_unlock(&m_lock); 2186 output_flush_progress = false; 2187 2188 if (arbitrary_bytes) { 2189 prev_ts = LLONG_MAX; 2190 rst_prev_ts = true; 2191 } 2192 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); 2193 return bRet; 2194} 2195/*========================================================================= 2196FUNCTION : execute_input_flush 2197 2198DESCRIPTION 2199Executes the OMX flush at INPUT PORT. 2200 2201PARAMETERS 2202None. 2203 2204RETURN VALUE 2205true/false 2206==========================================================================*/ 2207bool omx_vdec::execute_input_flush() 2208{ 2209 unsigned i =0; 2210 unsigned p1 = 0; // Parameter - 1 2211 unsigned p2 = 0; // Parameter - 2 2212 unsigned ident = 0; 2213 bool bRet = true; 2214 2215 /*Generate EBD for all Buffers in the ETBq*/ 2216 DEBUG_PRINT_LOW("Initiate Input Flush"); 2217 2218 pthread_mutex_lock(&m_lock); 2219 DEBUG_PRINT_LOW("Check if the Queue is empty"); 2220 while (m_etb_q.m_size) { 2221 m_etb_q.pop_entry(&p1,&p2,&ident); 2222 2223 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 2224 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 2225 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 2226 } else if (ident == OMX_COMPONENT_GENERATE_ETB) { 2227 pending_input_buffers++; 2228 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 2229 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 2230 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 2231 } else if (ident == OMX_COMPONENT_GENERATE_EBD) { 2232 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p", 2233 (OMX_BUFFERHEADERTYPE *)p1); 2234 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 2235 } 2236 } 2237 time_stamp_dts.flush_timestamp(); 2238 /*Check if Heap Buffers are to be flushed*/ 2239 if (arbitrary_bytes && !(codec_config_flag)) { 2240 DEBUG_PRINT_LOW("Reset all the variables before flusing"); 2241 h264_scratch.nFilledLen = 0; 2242 nal_count = 0; 2243 look_ahead_nal = false; 2244 frame_count = 0; 2245 h264_last_au_ts = LLONG_MAX; 2246 h264_last_au_flags = 0; 2247 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 2248 m_demux_entries = 0; 2249 DEBUG_PRINT_LOW("Initialize parser"); 2250 if (m_frame_parser.mutils) { 2251 m_frame_parser.mutils->initialize_frame_checking_environment(); 2252 } 2253 2254 while (m_input_pending_q.m_size) { 2255 m_input_pending_q.pop_entry(&p1,&p2,&ident); 2256 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 2257 } 2258 2259 if (psource_frame) { 2260 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 2261 psource_frame = NULL; 2262 } 2263 2264 if (pdest_frame) { 2265 pdest_frame->nFilledLen = 0; 2266 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL, 2267 (unsigned int)NULL); 2268 pdest_frame = NULL; 2269 } 2270 m_frame_parser.flush(); 2271 } else if (codec_config_flag) { 2272 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " 2273 "is not sent to the driver yet"); 2274 } 2275 pthread_mutex_unlock(&m_lock); 2276 input_flush_progress = false; 2277 if (!arbitrary_bytes) { 2278 prev_ts = LLONG_MAX; 2279 rst_prev_ts = true; 2280 } 2281#ifdef _ANDROID_ 2282 if (m_debug_timestamp) { 2283 m_timestamp_list.reset_ts_list(); 2284 } 2285#endif 2286 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); 2287 return bRet; 2288} 2289 2290 2291/* ====================================================================== 2292 FUNCTION 2293 omx_vdec::SendCommandEvent 2294 2295 DESCRIPTION 2296 Send the event to decoder pipe. This is needed to generate the callbacks 2297 in decoder thread context. 2298 2299 PARAMETERS 2300 None. 2301 2302 RETURN VALUE 2303 true/false 2304 2305 ========================================================================== */ 2306bool omx_vdec::post_event(unsigned int p1, 2307 unsigned int p2, 2308 unsigned int id) 2309{ 2310 bool bRet = false; 2311 2312 2313 pthread_mutex_lock(&m_lock); 2314 2315 if (id == m_fill_output_msg || 2316 id == OMX_COMPONENT_GENERATE_FBD) { 2317 m_ftb_q.insert_entry(p1,p2,id); 2318 } else if (id == OMX_COMPONENT_GENERATE_ETB || 2319 id == OMX_COMPONENT_GENERATE_EBD || 2320 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { 2321 m_etb_q.insert_entry(p1,p2,id); 2322 } else { 2323 m_cmd_q.insert_entry(p1,p2,id); 2324 } 2325 2326 bRet = true; 2327 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); 2328 post_message(this, id); 2329 2330 pthread_mutex_unlock(&m_lock); 2331 2332 return bRet; 2333} 2334 2335OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 2336{ 2337 OMX_ERRORTYPE eRet = OMX_ErrorNoMore; 2338 if (!profileLevelType) 2339 return OMX_ErrorBadParameter; 2340 2341 if (profileLevelType->nPortIndex == 0) { 2342 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 2343 if (profileLevelType->nProfileIndex == 0) { 2344 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 2345 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2346 2347 } else if (profileLevelType->nProfileIndex == 1) { 2348 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 2349 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2350 } else if (profileLevelType->nProfileIndex == 2) { 2351 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 2352 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2353 } else { 2354 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", 2355 profileLevelType->nProfileIndex); 2356 eRet = OMX_ErrorNoMore; 2357 } 2358 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) { 2359 // TODO 2360 { 2361 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", 2362 profileLevelType->nProfileIndex); 2363 eRet = OMX_ErrorNoMore; 2364 } 2365 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) { 2366 if (profileLevelType->nProfileIndex == 0) { 2367 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 2368 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 2369 } else { 2370 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex); 2371 eRet = OMX_ErrorNoMore; 2372 } 2373 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 2374 if (profileLevelType->nProfileIndex == 0) { 2375 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2376 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2377 } else if (profileLevelType->nProfileIndex == 1) { 2378 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 2379 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2380 } else { 2381 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex); 2382 eRet = OMX_ErrorNoMore; 2383 } 2384 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 2385 eRet = OMX_ErrorNoMore; 2386 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 2387 if (profileLevelType->nProfileIndex == 0) { 2388 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; 2389 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 2390 } else if (profileLevelType->nProfileIndex == 1) { 2391 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; 2392 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 2393 } else { 2394 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex); 2395 eRet = OMX_ErrorNoMore; 2396 } 2397 } 2398 } else { 2399 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex); 2400 eRet = OMX_ErrorBadPortIndex; 2401 } 2402 return eRet; 2403} 2404 2405/* ====================================================================== 2406 FUNCTION 2407 omx_vdec::GetParameter 2408 2409 DESCRIPTION 2410 OMX Get Parameter method implementation 2411 2412 PARAMETERS 2413 <TBD>. 2414 2415 RETURN VALUE 2416 Error None if successful. 2417 2418 ========================================================================== */ 2419OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 2420 OMX_IN OMX_INDEXTYPE paramIndex, 2421 OMX_INOUT OMX_PTR paramData) 2422{ 2423 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2424 2425 DEBUG_PRINT_LOW("get_parameter:"); 2426 if (m_state == OMX_StateInvalid) { 2427 DEBUG_PRINT_ERROR("Get Param in Invalid State"); 2428 return OMX_ErrorInvalidState; 2429 } 2430 if (paramData == NULL) { 2431 DEBUG_PRINT_LOW("Get Param in Invalid paramData"); 2432 return OMX_ErrorBadParameter; 2433 } 2434 switch ((unsigned long)paramIndex) { 2435 case OMX_IndexParamPortDefinition: 2436 { 2437 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = 2438 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 2439 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition"); 2440 eRet = update_portdef(portDefn); 2441 if (eRet == OMX_ErrorNone) 2442 m_port_def = *portDefn; 2443 break; 2444 } 2445 case OMX_IndexParamVideoInit: 2446 { 2447 OMX_PORT_PARAM_TYPE *portParamType = 2448 (OMX_PORT_PARAM_TYPE *) paramData; 2449 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); 2450 2451 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2452 portParamType->nSize = sizeof(portParamType); 2453 portParamType->nPorts = 2; 2454 portParamType->nStartPortNumber = 0; 2455 break; 2456 } 2457 case OMX_IndexParamVideoPortFormat: 2458 { 2459 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 2460 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 2461 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); 2462 2463 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 2464 portFmt->nSize = sizeof(portFmt); 2465 2466 if (0 == portFmt->nPortIndex) { 2467 if (0 == portFmt->nIndex) { 2468 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 2469 portFmt->eCompressionFormat = eCompressionFormat; 2470 } else { 2471 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2472 " NoMore compression formats"); 2473 eRet = OMX_ErrorNoMore; 2474 } 2475 } else if (1 == portFmt->nPortIndex) { 2476 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 2477 2478 if (0 == portFmt->nIndex) 2479 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) 2480 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 2481 else if (1 == portFmt->nIndex) 2482 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; 2483 else { 2484 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2485 " NoMore Color formats"); 2486 eRet = OMX_ErrorNoMore; 2487 } 2488 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat); 2489 } else { 2490 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d", 2491 (int)portFmt->nPortIndex); 2492 eRet = OMX_ErrorBadPortIndex; 2493 } 2494 break; 2495 } 2496 /*Component should support this port definition*/ 2497 case OMX_IndexParamAudioInit: 2498 { 2499 OMX_PORT_PARAM_TYPE *audioPortParamType = 2500 (OMX_PORT_PARAM_TYPE *) paramData; 2501 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); 2502 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2503 audioPortParamType->nSize = sizeof(audioPortParamType); 2504 audioPortParamType->nPorts = 0; 2505 audioPortParamType->nStartPortNumber = 0; 2506 break; 2507 } 2508 /*Component should support this port definition*/ 2509 case OMX_IndexParamImageInit: 2510 { 2511 OMX_PORT_PARAM_TYPE *imagePortParamType = 2512 (OMX_PORT_PARAM_TYPE *) paramData; 2513 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); 2514 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2515 imagePortParamType->nSize = sizeof(imagePortParamType); 2516 imagePortParamType->nPorts = 0; 2517 imagePortParamType->nStartPortNumber = 0; 2518 break; 2519 2520 } 2521 /*Component should support this port definition*/ 2522 case OMX_IndexParamOtherInit: 2523 { 2524 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x", 2525 paramIndex); 2526 eRet =OMX_ErrorUnsupportedIndex; 2527 break; 2528 } 2529 case OMX_IndexParamStandardComponentRole: 2530 { 2531 OMX_PARAM_COMPONENTROLETYPE *comp_role; 2532 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 2533 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 2534 comp_role->nSize = sizeof(*comp_role); 2535 2536 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d", 2537 paramIndex); 2538 strlcpy((char*)comp_role->cRole,(const char*)m_cRole, 2539 OMX_MAX_STRINGNAME_SIZE); 2540 break; 2541 } 2542 /* Added for parameter test */ 2543 case OMX_IndexParamPriorityMgmt: 2544 { 2545 2546 OMX_PRIORITYMGMTTYPE *priorityMgmType = 2547 (OMX_PRIORITYMGMTTYPE *) paramData; 2548 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); 2549 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 2550 priorityMgmType->nSize = sizeof(priorityMgmType); 2551 2552 break; 2553 } 2554 /* Added for parameter test */ 2555 case OMX_IndexParamCompBufferSupplier: 2556 { 2557 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 2558 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 2559 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); 2560 2561 bufferSupplierType->nSize = sizeof(bufferSupplierType); 2562 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 2563 if (0 == bufferSupplierType->nPortIndex) 2564 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2565 else if (1 == bufferSupplierType->nPortIndex) 2566 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2567 else 2568 eRet = OMX_ErrorBadPortIndex; 2569 2570 2571 break; 2572 } 2573 case OMX_IndexParamVideoAvc: 2574 { 2575 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x", 2576 paramIndex); 2577 break; 2578 } 2579 case OMX_IndexParamVideoH263: 2580 { 2581 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x", 2582 paramIndex); 2583 break; 2584 } 2585 case OMX_IndexParamVideoMpeg4: 2586 { 2587 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x", 2588 paramIndex); 2589 break; 2590 } 2591 case OMX_IndexParamVideoMpeg2: 2592 { 2593 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x", 2594 paramIndex); 2595 break; 2596 } 2597 case OMX_IndexParamVideoProfileLevelQuerySupported: 2598 { 2599 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex); 2600 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = 2601 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 2602 eRet = get_supported_profile_level_for_1080p(profileLevelType); 2603 break; 2604 } 2605#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 2606 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: 2607 { 2608 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); 2609 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; 2610 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 2611 2612 if (secure_mode) { 2613 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | 2614 GRALLOC_USAGE_PRIVATE_UNCACHED); 2615 } else { 2616#ifdef _HEVC_USE_ADSP_HEAP_ 2617 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); 2618#else 2619 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED; 2620#endif 2621 DEBUG_PRINT_HIGH("nativeBuffersUsage->nUsage %x", (unsigned int)nativeBuffersUsage->nUsage); 2622 } 2623 } else { 2624 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); 2625 eRet = OMX_ErrorBadParameter; 2626 } 2627 } 2628 break; 2629#endif 2630 2631 default: 2632 { 2633 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex); 2634 eRet =OMX_ErrorUnsupportedIndex; 2635 } 2636 2637 } 2638 2639 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", 2640 drv_ctx.video_resolution.frame_width, 2641 drv_ctx.video_resolution.frame_height, 2642 drv_ctx.video_resolution.stride, 2643 drv_ctx.video_resolution.scan_lines); 2644 2645 return eRet; 2646} 2647 2648#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 2649OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) 2650{ 2651 DEBUG_PRINT_LOW("Inside use_android_native_buffer"); 2652 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2653 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; 2654 2655 if ((params == NULL) || 2656 (params->nativeBuffer == NULL) || 2657 (params->nativeBuffer->handle == NULL) || 2658 !m_enable_android_native_buffers) 2659 return OMX_ErrorBadParameter; 2660 m_use_android_native_buffers = OMX_TRUE; 2661 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 2662 private_handle_t *handle = (private_handle_t *)nBuf->handle; 2663 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port 2664 OMX_U8 *buffer = NULL; 2665 if (!secure_mode) { 2666 buffer = (OMX_U8*)mmap(0, handle->size, 2667 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 2668 if (buffer == MAP_FAILED) { 2669 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 2670 return OMX_ErrorInsufficientResources; 2671 } 2672 } 2673 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); 2674 } else { 2675 eRet = OMX_ErrorBadParameter; 2676 } 2677 return eRet; 2678} 2679#endif 2680/* ====================================================================== 2681 FUNCTION 2682 omx_vdec::Setparameter 2683 2684 DESCRIPTION 2685 OMX Set Parameter method implementation. 2686 2687 PARAMETERS 2688 <TBD>. 2689 2690 RETURN VALUE 2691 OMX Error None if successful. 2692 2693 ========================================================================== */ 2694OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 2695 OMX_IN OMX_INDEXTYPE paramIndex, 2696 OMX_IN OMX_PTR paramData) 2697{ 2698 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2699 int ret=0; 2700 struct v4l2_format fmt; 2701 if (m_state == OMX_StateInvalid) { 2702 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 2703 return OMX_ErrorInvalidState; 2704 } 2705 if (paramData == NULL) { 2706 DEBUG_PRINT_ERROR("Get Param in Invalid paramData"); 2707 return OMX_ErrorBadParameter; 2708 } 2709 if ((m_state != OMX_StateLoaded) && 2710 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && 2711 (m_out_bEnabled == OMX_TRUE) && 2712 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && 2713 (m_inp_bEnabled == OMX_TRUE)) { 2714 DEBUG_PRINT_ERROR("Set Param in Invalid State"); 2715 return OMX_ErrorIncorrectStateOperation; 2716 } 2717 switch ((unsigned long)paramIndex) { 2718 case OMX_IndexParamPortDefinition: 2719 { 2720 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 2721 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 2722 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has 2723 //been called. 2724 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", 2725 (int)portDefn->format.video.nFrameHeight, 2726 (int)portDefn->format.video.nFrameWidth); 2727 if (OMX_DirOutput == portDefn->eDir) { 2728 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); 2729 m_display_id = portDefn->format.video.pNativeWindow; 2730 unsigned int buffer_size; 2731 if (!client_buffers.get_buffer_req(buffer_size)) { 2732 DEBUG_PRINT_ERROR("Error in getting buffer requirements"); 2733 eRet = OMX_ErrorBadParameter; 2734 } else { 2735 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && 2736 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) { 2737 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; 2738 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; 2739 eRet = set_buffer_req(&drv_ctx.op_buf); 2740 if (eRet == OMX_ErrorNone) 2741 m_port_def = *portDefn; 2742 } else { 2743 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)", 2744 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, 2745 portDefn->nBufferCountActual, portDefn->nBufferSize); 2746 eRet = OMX_ErrorBadParameter; 2747 } 2748 } 2749 } else if (OMX_DirInput == portDefn->eDir) { 2750 if ((portDefn->format.video.xFramerate >> 16) > 0 && 2751 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) { 2752 // Frame rate only should be set if this is a "known value" or to 2753 // activate ts prediction logic (arbitrary mode only) sending input 2754 // timestamps with max value (LLONG_MAX). 2755 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu", 2756 portDefn->format.video.xFramerate >> 16); 2757 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, 2758 drv_ctx.frame_rate.fps_denominator); 2759 if (!drv_ctx.frame_rate.fps_numerator) { 2760 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 2761 drv_ctx.frame_rate.fps_numerator = 30; 2762 } 2763 if (drv_ctx.frame_rate.fps_denominator) 2764 drv_ctx.frame_rate.fps_numerator = (int) 2765 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 2766 drv_ctx.frame_rate.fps_denominator = 1; 2767 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 2768 drv_ctx.frame_rate.fps_numerator; 2769 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", 2770 frm_int, drv_ctx.frame_rate.fps_numerator / 2771 (float)drv_ctx.frame_rate.fps_denominator); 2772 } 2773 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); 2774 if (drv_ctx.video_resolution.frame_height != 2775 portDefn->format.video.nFrameHeight || 2776 drv_ctx.video_resolution.frame_width != 2777 portDefn->format.video.nFrameWidth) { 2778 DEBUG_PRINT_LOW("SetParam IP: WxH(%d x %d)", 2779 portDefn->format.video.nFrameWidth, 2780 portDefn->format.video.nFrameHeight); 2781 if (portDefn->format.video.nFrameHeight != 0x0 && 2782 portDefn->format.video.nFrameWidth != 0x0) { 2783 update_resolution(portDefn->format.video.nFrameWidth, 2784 portDefn->format.video.nFrameHeight); 2785 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2786 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2787 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2788 fmt.fmt.pix_mp.pixelformat = output_capability; 2789 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); 2790 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2791 if (ret) { 2792 DEBUG_PRINT_ERROR("Set Resolution failed"); 2793 eRet = OMX_ErrorUnsupportedSetting; 2794 } else 2795 eRet = get_buffer_req(&drv_ctx.op_buf); 2796 } 2797 } else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount 2798 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) { 2799 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; 2800 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; 2801 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & 2802 (~(buffer_prop->alignment - 1)); 2803 eRet = set_buffer_req(buffer_prop); 2804 } else { 2805 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)", 2806 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, 2807 portDefn->nBufferCountActual, portDefn->nBufferSize); 2808 eRet = OMX_ErrorBadParameter; 2809 } 2810 } else if (portDefn->eDir == OMX_DirMax) { 2811 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 2812 (int)portDefn->nPortIndex); 2813 eRet = OMX_ErrorBadPortIndex; 2814 } 2815 } 2816 break; 2817 case OMX_IndexParamVideoPortFormat: 2818 { 2819 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 2820 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 2821 int ret=0; 2822 struct v4l2_format fmt; 2823 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d", 2824 portFmt->eColorFormat); 2825 2826 if (1 == portFmt->nPortIndex) { 2827 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2828 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 2829 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 2830 fmt.fmt.pix_mp.pixelformat = capture_capability; 2831 enum vdec_output_fromat op_format; 2832 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) 2833 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) || 2834 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)) 2835 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; 2836 else if (portFmt->eColorFormat == 2837 (OMX_COLOR_FORMATTYPE) 2838 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) 2839 op_format = VDEC_YUV_FORMAT_TILE_4x2; 2840 else 2841 eRet = OMX_ErrorBadParameter; 2842 2843 if (eRet == OMX_ErrorNone) { 2844 drv_ctx.output_format = op_format; 2845 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 2846 if (ret) { 2847 DEBUG_PRINT_ERROR("Set output format failed"); 2848 eRet = OMX_ErrorUnsupportedSetting; 2849 /*TODO: How to handle this case */ 2850 } else { 2851 eRet = get_buffer_req(&drv_ctx.op_buf); 2852 } 2853 } 2854 if (eRet == OMX_ErrorNone) { 2855 if (!client_buffers.set_color_format(portFmt->eColorFormat)) { 2856 DEBUG_PRINT_ERROR("Set color format failed"); 2857 eRet = OMX_ErrorBadParameter; 2858 } 2859 } 2860 } 2861 } 2862 break; 2863 2864 case OMX_QcomIndexPortDefn: 2865 { 2866 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 2867 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 2868 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d", 2869 portFmt->nFramePackingFormat); 2870 2871 /* Input port */ 2872 if (portFmt->nPortIndex == 0) { 2873 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) { 2874 if (secure_mode) { 2875 arbitrary_bytes = false; 2876 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); 2877 eRet = OMX_ErrorUnsupportedSetting; 2878 } else { 2879 arbitrary_bytes = true; 2880 } 2881 } else if (portFmt->nFramePackingFormat == 2882 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) { 2883 arbitrary_bytes = false; 2884 } else { 2885 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu", 2886 portFmt->nFramePackingFormat); 2887 eRet = OMX_ErrorUnsupportedSetting; 2888 } 2889 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 2890 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); 2891 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && 2892 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && 2893 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) { 2894 m_out_mem_region_smi = OMX_TRUE; 2895 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 2896 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set"); 2897 m_use_output_pmem = OMX_TRUE; 2898 } 2899 } 2900 } 2901 } 2902 break; 2903 2904 case OMX_IndexParamStandardComponentRole: 2905 { 2906 OMX_PARAM_COMPONENTROLETYPE *comp_role; 2907 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 2908 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", 2909 comp_role->cRole); 2910 2911 if ((m_state == OMX_StateLoaded)&& 2912 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 2913 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 2914 } else { 2915 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 2916 return OMX_ErrorIncorrectStateOperation; 2917 } 2918 2919 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 2920 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 2921 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 2922 } else { 2923 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2924 eRet =OMX_ErrorUnsupportedSetting; 2925 } 2926 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) { 2927 if (!strncmp((char*)comp_role->cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) { 2928 strlcpy((char*)m_cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 2929 } else { 2930 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2931 eRet =OMX_ErrorUnsupportedSetting; 2932 } 2933 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 2934 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 2935 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 2936 } else { 2937 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2938 eRet = OMX_ErrorUnsupportedSetting; 2939 } 2940 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 2941 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 2942 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 2943 } else { 2944 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2945 eRet =OMX_ErrorUnsupportedSetting; 2946 } 2947 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 2948 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 2949 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 2950 } else { 2951 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2952 eRet = OMX_ErrorUnsupportedSetting; 2953 } 2954 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 2955 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) 2956 ) { 2957 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) { 2958 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 2959 } else { 2960 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2961 eRet =OMX_ErrorUnsupportedSetting; 2962 } 2963 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 2964 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 2965 ) { 2966 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) { 2967 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2968 } else { 2969 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2970 eRet =OMX_ErrorUnsupportedSetting; 2971 } 2972 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 2973 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || 2974 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) { 2975 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 2976 } else { 2977 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole); 2978 eRet = OMX_ErrorUnsupportedSetting; 2979 } 2980 } else { 2981 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind); 2982 eRet = OMX_ErrorInvalidComponentName; 2983 } 2984 break; 2985 } 2986 2987 case OMX_IndexParamPriorityMgmt: 2988 { 2989 if (m_state != OMX_StateLoaded) { 2990 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State"); 2991 return OMX_ErrorIncorrectStateOperation; 2992 } 2993 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 2994 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d", 2995 priorityMgmtype->nGroupID); 2996 2997 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d", 2998 priorityMgmtype->nGroupPriority); 2999 3000 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 3001 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 3002 3003 break; 3004 } 3005 3006 case OMX_IndexParamCompBufferSupplier: 3007 { 3008 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 3009 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d", 3010 bufferSupplierType->eBufferSupplier); 3011 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 3012 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 3013 3014 else 3015 3016 eRet = OMX_ErrorBadPortIndex; 3017 3018 break; 3019 3020 } 3021 case OMX_IndexParamVideoAvc: 3022 { 3023 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d", 3024 paramIndex); 3025 break; 3026 } 3027 case OMX_IndexParamVideoH263: 3028 { 3029 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d", 3030 paramIndex); 3031 break; 3032 } 3033 case OMX_IndexParamVideoMpeg4: 3034 { 3035 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d", 3036 paramIndex); 3037 break; 3038 } 3039 case OMX_IndexParamVideoMpeg2: 3040 { 3041 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d", 3042 paramIndex); 3043 break; 3044 } 3045 case OMX_QcomIndexParamVideoDecoderPictureOrder: 3046 { 3047 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = 3048 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; 3049 struct v4l2_control control; 3050 int pic_order,rc=0; 3051 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d", 3052 pictureOrder->eOutputPictureOrder); 3053 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { 3054 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; 3055 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) { 3056 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 3057 time_stamp_dts.set_timestamp_reorder_mode(false); 3058 } else 3059 eRet = OMX_ErrorBadParameter; 3060 if (eRet == OMX_ErrorNone) { 3061 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 3062 control.value = pic_order; 3063 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 3064 if (rc) { 3065 DEBUG_PRINT_ERROR("Set picture order failed"); 3066 eRet = OMX_ErrorUnsupportedSetting; 3067 } 3068 } 3069 break; 3070 } 3071 case OMX_QcomIndexParamConcealMBMapExtraData: 3072 if (!secure_mode) 3073 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, 3074 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3075 else { 3076 DEBUG_PRINT_ERROR("secure mode setting not supported"); 3077 eRet = OMX_ErrorUnsupportedSetting; 3078 } 3079 break; 3080 case OMX_QcomIndexParamFrameInfoExtraData: 3081 { 3082 if (!secure_mode) 3083 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, 3084 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3085 else { 3086 DEBUG_PRINT_ERROR("secure mode setting not supported"); 3087 eRet = OMX_ErrorUnsupportedSetting; 3088 } 3089 break; 3090 } 3091 case OMX_QcomIndexParamInterlaceExtraData: 3092 if (!secure_mode) 3093 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, 3094 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3095 else { 3096 DEBUG_PRINT_ERROR("secure mode setting not supported"); 3097 eRet = OMX_ErrorUnsupportedSetting; 3098 } 3099 break; 3100 case OMX_QcomIndexParamH264TimeInfo: 3101 if (!secure_mode) 3102 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, 3103 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3104 else { 3105 DEBUG_PRINT_ERROR("secure mode setting not supported"); 3106 eRet = OMX_ErrorUnsupportedSetting; 3107 } 3108 break; 3109 case OMX_QcomIndexParamVideoDivx: 3110 { 3111 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; 3112 } 3113 break; 3114 case OMX_QcomIndexPlatformPvt: 3115 { 3116 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); 3117 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; 3118 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 3119 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); 3120 eRet = OMX_ErrorUnsupportedSetting; 3121 } else { 3122 m_out_pvt_entry_pmem = OMX_TRUE; 3123 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) { 3124 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set"); 3125 m_use_output_pmem = OMX_TRUE; 3126 } 3127 } 3128 3129 } 3130 break; 3131 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: 3132 { 3133 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); 3134 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); 3135 struct v4l2_control control; 3136 int rc; 3137 drv_ctx.idr_only_decoding = 1; 3138 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; 3139 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; 3140 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 3141 if (rc) { 3142 DEBUG_PRINT_ERROR("Set picture order failed"); 3143 eRet = OMX_ErrorUnsupportedSetting; 3144 } else { 3145 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; 3146 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; 3147 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); 3148 if (rc) { 3149 DEBUG_PRINT_ERROR("Sync frame setting failed"); 3150 eRet = OMX_ErrorUnsupportedSetting; 3151 } 3152 } 3153 } 3154 break; 3155 3156 case OMX_QcomIndexParamIndexExtraDataType: 3157 { 3158 if (!secure_mode) { 3159 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; 3160 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && 3161 (extradataIndexType->bEnabled == OMX_TRUE) && 3162 (extradataIndexType->nPortIndex == 1)) { 3163 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); 3164 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); 3165 3166 } 3167 } 3168 } 3169 break; 3170 case OMX_QcomIndexParamEnableSmoothStreaming: 3171 { 3172 struct v4l2_control control; 3173 struct v4l2_format fmt; 3174 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; 3175 control.value = 1; 3176 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); 3177 if (rc < 0) { 3178 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 3179 eRet = OMX_ErrorHardware; 3180 } 3181 } 3182 break; 3183#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3184 /* Need to allow following two set_parameters even in Idle 3185 * state. This is ANDROID architecture which is not in sync 3186 * with openmax standard. */ 3187 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: 3188 { 3189 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; 3190 if (enableNativeBuffers) { 3191 m_enable_android_native_buffers = enableNativeBuffers->enable; 3192 } 3193 } 3194 break; 3195 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: 3196 { 3197 eRet = use_android_native_buffer(hComp, paramData); 3198 } 3199 break; 3200#endif 3201 case OMX_QcomIndexParamEnableTimeStampReorder: 3202 { 3203 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; 3204 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { 3205 if (reorder->bEnable == OMX_TRUE) { 3206 frm_int =0; 3207 time_stamp_dts.set_timestamp_reorder_mode(true); 3208 } else 3209 time_stamp_dts.set_timestamp_reorder_mode(false); 3210 } else { 3211 time_stamp_dts.set_timestamp_reorder_mode(false); 3212 if (reorder->bEnable == OMX_TRUE) { 3213 eRet = OMX_ErrorUnsupportedSetting; 3214 } 3215 } 3216 } 3217 break; 3218 default: 3219 { 3220 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex); 3221 eRet = OMX_ErrorUnsupportedIndex; 3222 } 3223 } 3224 return eRet; 3225} 3226 3227/* ====================================================================== 3228 FUNCTION 3229 omx_vdec::GetConfig 3230 3231 DESCRIPTION 3232 OMX Get Config Method implementation. 3233 3234 PARAMETERS 3235 <TBD>. 3236 3237 RETURN VALUE 3238 OMX Error None if successful. 3239 3240 ========================================================================== */ 3241OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 3242 OMX_IN OMX_INDEXTYPE configIndex, 3243 OMX_INOUT OMX_PTR configData) 3244{ 3245 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3246 3247 if (m_state == OMX_StateInvalid) { 3248 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 3249 return OMX_ErrorInvalidState; 3250 } 3251 3252 switch ((unsigned long)configIndex) { 3253 case OMX_QcomIndexConfigInterlaced: 3254 { 3255 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 3256 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 3257 if (configFmt->nPortIndex == 1) { 3258 if (configFmt->nIndex == 0) { 3259 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 3260 } else if (configFmt->nIndex == 1) { 3261 configFmt->eInterlaceType = 3262 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 3263 } else if (configFmt->nIndex == 2) { 3264 configFmt->eInterlaceType = 3265 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 3266 } else { 3267 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 3268 " NoMore Interlaced formats"); 3269 eRet = OMX_ErrorNoMore; 3270 } 3271 3272 } else { 3273 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port", 3274 (int)configFmt->nPortIndex); 3275 eRet = OMX_ErrorBadPortIndex; 3276 } 3277 break; 3278 } 3279 case OMX_QcomIndexQueryNumberOfVideoDecInstance: 3280 { 3281 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 3282 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 3283 decoderinstances->nNumOfInstances = 16; 3284 /*TODO: How to handle this case */ 3285 break; 3286 } 3287 case OMX_QcomIndexConfigVideoFramePackingArrangement: 3288 { 3289 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) { 3290 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = 3291 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; 3292 h264_parser->get_frame_pack_data(configFmt); 3293 } else { 3294 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); 3295 } 3296 break; 3297 } 3298 case OMX_IndexConfigCommonOutputCrop: 3299 { 3300 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; 3301 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); 3302 break; 3303 } 3304 default: 3305 { 3306 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex); 3307 eRet = OMX_ErrorBadParameter; 3308 } 3309 3310 } 3311 3312 return eRet; 3313} 3314 3315/* ====================================================================== 3316 FUNCTION 3317 omx_vdec::SetConfig 3318 3319 DESCRIPTION 3320 OMX Set Config method implementation 3321 3322 PARAMETERS 3323 <TBD>. 3324 3325 RETURN VALUE 3326 OMX Error None if successful. 3327 ========================================================================== */ 3328OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 3329 OMX_IN OMX_INDEXTYPE configIndex, 3330 OMX_IN OMX_PTR configData) 3331{ 3332 if (m_state == OMX_StateInvalid) { 3333 DEBUG_PRINT_ERROR("Get Config in Invalid State"); 3334 return OMX_ErrorInvalidState; 3335 } 3336 3337 OMX_ERRORTYPE ret = OMX_ErrorNone; 3338 OMX_VIDEO_CONFIG_NALSIZE *pNal; 3339 3340 DEBUG_PRINT_LOW("Set Config Called"); 3341 3342 if (m_state == OMX_StateExecuting) { 3343 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state"); 3344 return ret; 3345 } 3346 3347 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) { 3348 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; 3349 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called"); 3350 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) { 3351 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC"); 3352 OMX_U32 extra_size; 3353 // Parsing done here for the AVC atom is definitely not generic 3354 // Currently this piece of code is working, but certainly 3355 // not tested with all .mp4 files. 3356 // Incase of failure, we might need to revisit this 3357 // for a generic piece of code. 3358 3359 // Retrieve size of NAL length field 3360 // byte #4 contains the size of NAL lenght field 3361 nal_length = (config->pData[4] & 0x03) + 1; 3362 3363 extra_size = 0; 3364 if (nal_length > 2) { 3365 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ 3366 extra_size = (nal_length - 2) * 2; 3367 } 3368 3369 // SPS starts from byte #6 3370 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); 3371 OMX_U8 *pDestBuf; 3372 m_vendor_config.nPortIndex = config->nPortIndex; 3373 3374 // minus 6 --> SPS starts from byte #6 3375 // minus 1 --> picture param set byte to be ignored from avcatom 3376 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; 3377 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); 3378 OMX_U32 len; 3379 OMX_U8 index = 0; 3380 // case where SPS+PPS is sent as part of set_config 3381 pDestBuf = m_vendor_config.pData; 3382 3383 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]", 3384 m_vendor_config.nPortIndex, 3385 m_vendor_config.nDataSize, 3386 m_vendor_config.pData); 3387 while (index < 2) { 3388 uint8 *psize; 3389 len = *pSrcBuf; 3390 len = len << 8; 3391 len |= *(pSrcBuf + 1); 3392 psize = (uint8 *) & len; 3393 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); 3394 for (unsigned int i = 0; i < nal_length; i++) { 3395 pDestBuf[i] = psize[nal_length - 1 - i]; 3396 } 3397 //memcpy(pDestBuf,pSrcBuf,(len+2)); 3398 pDestBuf += len + nal_length; 3399 pSrcBuf += len + 2; 3400 index++; 3401 pSrcBuf++; // skip picture param set 3402 len = 0; 3403 } 3404 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || 3405 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) { 3406 m_vendor_config.nPortIndex = config->nPortIndex; 3407 m_vendor_config.nDataSize = config->nDataSize; 3408 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); 3409 memcpy(m_vendor_config.pData, config->pData,config->nDataSize); 3410 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) { 3411 if (m_vendor_config.pData) { 3412 free(m_vendor_config.pData); 3413 m_vendor_config.pData = NULL; 3414 m_vendor_config.nDataSize = 0; 3415 } 3416 3417 if (((*((OMX_U32 *) config->pData)) & 3418 VC1_SP_MP_START_CODE_MASK) == 3419 VC1_SP_MP_START_CODE) { 3420 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile"); 3421 m_vendor_config.nPortIndex = config->nPortIndex; 3422 m_vendor_config.nDataSize = config->nDataSize; 3423 m_vendor_config.pData = 3424 (OMX_U8 *) malloc(config->nDataSize); 3425 memcpy(m_vendor_config.pData, config->pData, 3426 config->nDataSize); 3427 m_vc1_profile = VC1_SP_MP_RCV; 3428 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) { 3429 DEBUG_PRINT_LOW("set_config - VC1 Advance profile"); 3430 m_vendor_config.nPortIndex = config->nPortIndex; 3431 m_vendor_config.nDataSize = config->nDataSize; 3432 m_vendor_config.pData = 3433 (OMX_U8 *) malloc((config->nDataSize)); 3434 memcpy(m_vendor_config.pData, config->pData, 3435 config->nDataSize); 3436 m_vc1_profile = VC1_AP; 3437 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) { 3438 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only"); 3439 m_vendor_config.nPortIndex = config->nPortIndex; 3440 m_vendor_config.nDataSize = config->nDataSize; 3441 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); 3442 memcpy(m_vendor_config.pData,config->pData,config->nDataSize); 3443 m_vc1_profile = VC1_SP_MP_RCV; 3444 } else { 3445 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile"); 3446 } 3447 } 3448 return ret; 3449 } else if (configIndex == OMX_IndexConfigVideoNalSize) { 3450 3451 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 3452 nal_length = pNal->nNaluBytes; 3453 m_frame_parser.init_nal_length(nal_length); 3454 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d",nal_length); 3455 return ret; 3456 } 3457 3458 return OMX_ErrorNotImplemented; 3459} 3460 3461/* ====================================================================== 3462 FUNCTION 3463 omx_vdec::GetExtensionIndex 3464 3465 DESCRIPTION 3466 OMX GetExtensionIndex method implementaion. <TBD> 3467 3468 PARAMETERS 3469 <TBD>. 3470 3471 RETURN VALUE 3472 OMX Error None if everything successful. 3473 3474 ========================================================================== */ 3475OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 3476 OMX_IN OMX_STRING paramName, 3477 OMX_OUT OMX_INDEXTYPE* indexType) 3478{ 3479 if (m_state == OMX_StateInvalid) { 3480 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State"); 3481 return OMX_ErrorInvalidState; 3482 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { 3483 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; 3484 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) { 3485 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; 3486 } 3487#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3488 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { 3489 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; 3490 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { 3491 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; 3492 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { 3493 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName); 3494 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; 3495 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { 3496 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; 3497 } 3498#endif 3499 else { 3500 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName); 3501 return OMX_ErrorNotImplemented; 3502 } 3503 return OMX_ErrorNone; 3504} 3505 3506/* ====================================================================== 3507 FUNCTION 3508 omx_vdec::GetState 3509 3510 DESCRIPTION 3511 Returns the state information back to the caller.<TBD> 3512 3513 PARAMETERS 3514 <TBD>. 3515 3516 RETURN VALUE 3517 Error None if everything is successful. 3518 ========================================================================== */ 3519OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 3520 OMX_OUT OMX_STATETYPE* state) 3521{ 3522 *state = m_state; 3523 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); 3524 return OMX_ErrorNone; 3525} 3526 3527/* ====================================================================== 3528 FUNCTION 3529 omx_vdec::ComponentTunnelRequest 3530 3531 DESCRIPTION 3532 OMX Component Tunnel Request method implementation. <TBD> 3533 3534 PARAMETERS 3535 None. 3536 3537 RETURN VALUE 3538 OMX Error None if everything successful. 3539 3540 ========================================================================== */ 3541OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 3542 OMX_IN OMX_U32 port, 3543 OMX_IN OMX_HANDLETYPE peerComponent, 3544 OMX_IN OMX_U32 peerPort, 3545 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 3546{ 3547 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented"); 3548 return OMX_ErrorNotImplemented; 3549} 3550 3551/* ====================================================================== 3552 FUNCTION 3553 omx_vdec::UseOutputBuffer 3554 3555 DESCRIPTION 3556 Helper function for Use buffer in the input pin 3557 3558 PARAMETERS 3559 None. 3560 3561 RETURN VALUE 3562 true/false 3563 3564 ========================================================================== */ 3565OMX_ERRORTYPE omx_vdec::allocate_extradata() 3566{ 3567#ifdef USE_ION 3568 if (drv_ctx.extradata_info.buffer_size) { 3569 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { 3570 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 3571 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 3572 free_ion_memory(&drv_ctx.extradata_info.ion); 3573 } 3574 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); 3575 DEBUG_PRINT_HIGH("allocate extradata memory size %d", drv_ctx.extradata_info.size); 3576 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( 3577 drv_ctx.extradata_info.size, 4096, 3578 &drv_ctx.extradata_info.ion.ion_alloc_data, 3579 &drv_ctx.extradata_info.ion.fd_ion_data, 0); 3580 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { 3581 DEBUG_PRINT_ERROR("Failed to alloc extradata memory"); 3582 return OMX_ErrorInsufficientResources; 3583 } 3584 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, 3585 drv_ctx.extradata_info.size, 3586 PROT_READ|PROT_WRITE, MAP_SHARED, 3587 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); 3588 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { 3589 DEBUG_PRINT_ERROR("Failed to map extradata memory"); 3590 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 3591 free_ion_memory(&drv_ctx.extradata_info.ion); 3592 return OMX_ErrorInsufficientResources; 3593 } 3594 memset(drv_ctx.extradata_info.uaddr, 0, drv_ctx.extradata_info.size); 3595 } 3596#endif 3597 return OMX_ErrorNone; 3598} 3599 3600void omx_vdec::free_extradata() 3601{ 3602#ifdef USE_ION 3603 if (drv_ctx.extradata_info.uaddr) { 3604 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); 3605 close(drv_ctx.extradata_info.ion.fd_ion_data.fd); 3606 free_ion_memory(&drv_ctx.extradata_info.ion); 3607 } 3608 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); 3609#endif 3610} 3611 3612OMX_ERRORTYPE omx_vdec::use_output_buffer( 3613 OMX_IN OMX_HANDLETYPE hComp, 3614 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3615 OMX_IN OMX_U32 port, 3616 OMX_IN OMX_PTR appData, 3617 OMX_IN OMX_U32 bytes, 3618 OMX_IN OMX_U8* buffer) 3619{ 3620 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3621 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 3622 unsigned i= 0; // Temporary counter 3623 struct vdec_setbuffer_cmd setbuffers; 3624 OMX_PTR privateAppData = NULL; 3625 private_handle_t *handle = NULL; 3626 OMX_U8 *buff = buffer; 3627 struct v4l2_buffer buf; 3628 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 3629 int extra_idx = 0; 3630 3631 if (!m_out_mem_ptr) { 3632 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); 3633 eRet = allocate_output_headers(); 3634 if (eRet == OMX_ErrorNone) 3635 eRet = allocate_extradata(); 3636 } 3637 3638 if (eRet == OMX_ErrorNone) { 3639 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 3640 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 3641 break; 3642 } 3643 } 3644 } 3645 3646 if (i >= drv_ctx.op_buf.actualcount) { 3647 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount); 3648 eRet = OMX_ErrorInsufficientResources; 3649 } 3650 3651 if (eRet == OMX_ErrorNone) { 3652#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 3653 if (m_enable_android_native_buffers) { 3654 if (m_use_android_native_buffers) { 3655 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; 3656 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 3657 handle = (private_handle_t *)nBuf->handle; 3658 privateAppData = params->pAppPrivate; 3659 } else { 3660 handle = (private_handle_t *)buff; 3661 privateAppData = appData; 3662 } 3663 3664 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 3665 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 3666 " expected %u, got %lu", 3667 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); 3668 return OMX_ErrorBadParameter; 3669 } 3670 3671 drv_ctx.op_buf.buffer_size = (OMX_U32)handle->size; 3672 if (!m_use_android_native_buffers) { 3673 if (!secure_mode) { 3674 buff = (OMX_U8*)mmap(0, handle->size, 3675 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 3676 if (buff == MAP_FAILED) { 3677 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 3678 return OMX_ErrorInsufficientResources; 3679 } 3680 } 3681 } 3682#if defined(_ANDROID_ICS_) 3683 native_buffer[i].nativehandle = handle; 3684 native_buffer[i].privatehandle = handle; 3685#endif 3686 if (!handle) { 3687 DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); 3688 return OMX_ErrorBadParameter; 3689 } 3690 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; 3691 drv_ctx.ptr_outputbuffer[i].offset = 0; 3692 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 3693 drv_ctx.ptr_outputbuffer[i].mmaped_size = 3694 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 3695 } else 3696#endif 3697 3698 if (!ouput_egl_buffers && !m_use_output_pmem) { 3699#ifdef USE_ION 3700 DEBUG_PRINT_HIGH("allocate output buffer memory size %d", drv_ctx.op_buf.buffer_size); 3701 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 3702 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 3703 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 3704 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); 3705 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 3706 DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd); 3707 return OMX_ErrorInsufficientResources; 3708 } 3709 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 3710 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 3711#else 3712 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 3713 open (MEM_DEVICE,O_RDWR); 3714 3715 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 3716 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 3717 return OMX_ErrorInsufficientResources; 3718 } 3719 3720 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ 3721 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) { 3722 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 3723 open (MEM_DEVICE,O_RDWR); 3724 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 3725 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd); 3726 return OMX_ErrorInsufficientResources; 3727 } 3728 } 3729 3730 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, 3731 drv_ctx.op_buf.buffer_size, 3732 drv_ctx.op_buf.alignment)) { 3733 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 3734 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 3735 return OMX_ErrorInsufficientResources; 3736 } 3737#endif 3738 if (!secure_mode) { 3739 drv_ctx.ptr_outputbuffer[i].bufferaddr = 3740 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, 3741 PROT_READ|PROT_WRITE, MAP_SHARED, 3742 drv_ctx.ptr_outputbuffer[i].pmem_fd,0); 3743 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { 3744 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 3745#ifdef USE_ION 3746 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 3747#endif 3748 DEBUG_PRINT_ERROR("Unable to mmap output buffer"); 3749 return OMX_ErrorInsufficientResources; 3750 } 3751 } 3752 drv_ctx.ptr_outputbuffer[i].offset = 0; 3753 privateAppData = appData; 3754 } else { 3755 3756 DEBUG_PRINT_HIGH("Use_op_buf: out_pmem=%d",m_use_output_pmem); 3757 if (!appData || !bytes ) { 3758 if (!secure_mode && !buffer) { 3759 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case"); 3760 return OMX_ErrorBadParameter; 3761 } 3762 } 3763 3764 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; 3765 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; 3766 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; 3767 if (!pmem_list->entryList || !pmem_list->entryList->entry || 3768 !pmem_list->nEntries || 3769 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 3770 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer"); 3771 return OMX_ErrorBadParameter; 3772 } 3773 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 3774 pmem_list->entryList->entry; 3775 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", 3776 pmem_info->pmem_fd); 3777 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; 3778 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; 3779 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 3780 drv_ctx.ptr_outputbuffer[i].mmaped_size = 3781 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 3782 privateAppData = appData; 3783 } 3784 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 3785 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; 3786 3787 *bufferHdr = (m_out_mem_ptr + i ); 3788 if (secure_mode) 3789 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 3790 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 3791 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], 3792 sizeof (vdec_bufferpayload)); 3793 3794 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, 3795 drv_ctx.ptr_outputbuffer[i].bufferaddr, 3796 drv_ctx.ptr_outputbuffer[i].pmem_fd ); 3797 3798 buf.index = i; 3799 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3800 buf.memory = V4L2_MEMORY_USERPTR; 3801 plane[0].length = drv_ctx.op_buf.buffer_size; 3802 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 3803 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 3804 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; 3805 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 3806 plane[0].data_offset = 0; 3807 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 3808 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 3809 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 3810 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 3811#ifdef USE_ION 3812 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 3813#endif 3814 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 3815 plane[extra_idx].data_offset = 0; 3816 } else if (extra_idx >= VIDEO_MAX_PLANES) { 3817 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 3818 return OMX_ErrorBadParameter; 3819 } 3820 buf.m.planes = plane; 3821 buf.length = drv_ctx.num_planes; 3822 3823 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); 3824 3825 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { 3826 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 3827 /*TODO: How to handle this case */ 3828 return OMX_ErrorInsufficientResources; 3829 } 3830 3831 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { 3832 enum v4l2_buf_type buf_type; 3833 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3834 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { 3835 return OMX_ErrorInsufficientResources; 3836 } else { 3837 streaming[CAPTURE_PORT] = true; 3838 DEBUG_PRINT_LOW("STREAMON Successful"); 3839 } 3840 } 3841 3842 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 3843 if (m_enable_android_native_buffers) { 3844 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); 3845 (*bufferHdr)->pBuffer = (OMX_U8 *)handle; 3846 } else { 3847 (*bufferHdr)->pBuffer = buff; 3848 } 3849 (*bufferHdr)->pAppPrivate = privateAppData; 3850 BITMASK_SET(&m_out_bm_count,i); 3851 } 3852 return eRet; 3853} 3854 3855/* ====================================================================== 3856 FUNCTION 3857 omx_vdec::use_input_heap_buffers 3858 3859 DESCRIPTION 3860 OMX Use Buffer Heap allocation method implementation. 3861 3862 PARAMETERS 3863 <TBD>. 3864 3865 RETURN VALUE 3866 OMX Error None , if everything successful. 3867 3868 ========================================================================== */ 3869OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( 3870 OMX_IN OMX_HANDLETYPE hComp, 3871 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3872 OMX_IN OMX_U32 port, 3873 OMX_IN OMX_PTR appData, 3874 OMX_IN OMX_U32 bytes, 3875 OMX_IN OMX_U8* buffer) 3876{ 3877 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); 3878 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3879 if (!m_inp_heap_ptr) 3880 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) 3881 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 3882 drv_ctx.ip_buf.actualcount); 3883 if (!m_phdr_pmem_ptr) 3884 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) 3885 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 3886 drv_ctx.ip_buf.actualcount); 3887 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) { 3888 DEBUG_PRINT_ERROR("Insufficent memory"); 3889 eRet = OMX_ErrorInsufficientResources; 3890 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) { 3891 input_use_buffer = true; 3892 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); 3893 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; 3894 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; 3895 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; 3896 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; 3897 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; 3898 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; 3899 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); 3900 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); 3901 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], 3902 (unsigned)NULL, (unsigned)NULL)) { 3903 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 3904 return OMX_ErrorInsufficientResources; 3905 } 3906 m_in_alloc_cnt++; 3907 } else { 3908 DEBUG_PRINT_ERROR("All i/p buffers have been set!"); 3909 eRet = OMX_ErrorInsufficientResources; 3910 } 3911 return eRet; 3912} 3913 3914/* ====================================================================== 3915 FUNCTION 3916 omx_vdec::UseBuffer 3917 3918 DESCRIPTION 3919 OMX Use Buffer method implementation. 3920 3921 PARAMETERS 3922 <TBD>. 3923 3924 RETURN VALUE 3925 OMX Error None , if everything successful. 3926 3927 ========================================================================== */ 3928OMX_ERRORTYPE omx_vdec::use_buffer( 3929 OMX_IN OMX_HANDLETYPE hComp, 3930 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3931 OMX_IN OMX_U32 port, 3932 OMX_IN OMX_PTR appData, 3933 OMX_IN OMX_U32 bytes, 3934 OMX_IN OMX_U8* buffer) 3935{ 3936 OMX_ERRORTYPE error = OMX_ErrorNone; 3937 struct vdec_setbuffer_cmd setbuffers; 3938 3939 if (bufferHdr == NULL || bytes == 0) { 3940 if (!secure_mode && buffer == NULL) { 3941 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer); 3942 return OMX_ErrorBadParameter; 3943 } 3944 } 3945 if (m_state == OMX_StateInvalid) { 3946 DEBUG_PRINT_ERROR("Use Buffer in Invalid State"); 3947 return OMX_ErrorInvalidState; 3948 } 3949 if (port == OMX_CORE_INPUT_PORT_INDEX) 3950 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); 3951 else if (port == OMX_CORE_OUTPUT_PORT_INDEX) 3952 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested 3953 else { 3954 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 3955 error = OMX_ErrorBadPortIndex; 3956 } 3957 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); 3958 if (error == OMX_ErrorNone) { 3959 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 3960 // Send the callback now 3961 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 3962 post_event(OMX_CommandStateSet,OMX_StateIdle, 3963 OMX_COMPONENT_GENERATE_EVENT); 3964 } 3965 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && 3966 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 3967 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 3968 post_event(OMX_CommandPortEnable, 3969 OMX_CORE_INPUT_PORT_INDEX, 3970 OMX_COMPONENT_GENERATE_EVENT); 3971 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && 3972 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 3973 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3974 post_event(OMX_CommandPortEnable, 3975 OMX_CORE_OUTPUT_PORT_INDEX, 3976 OMX_COMPONENT_GENERATE_EVENT); 3977 } 3978 } 3979 return error; 3980} 3981 3982OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, 3983 OMX_BUFFERHEADERTYPE *pmem_bufferHdr) 3984{ 3985 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) { 3986 if (m_inp_heap_ptr[bufferindex].pBuffer) 3987 free(m_inp_heap_ptr[bufferindex].pBuffer); 3988 m_inp_heap_ptr[bufferindex].pBuffer = NULL; 3989 } 3990 if (pmem_bufferHdr) 3991 free_input_buffer(pmem_bufferHdr); 3992 return OMX_ErrorNone; 3993} 3994 3995OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 3996{ 3997 unsigned int index = 0; 3998 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { 3999 return OMX_ErrorBadParameter; 4000 } 4001 4002 index = bufferHdr - m_inp_mem_ptr; 4003 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 4004 4005 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) { 4006 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); 4007 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) { 4008 struct vdec_setbuffer_cmd setbuffers; 4009 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 4010 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], 4011 sizeof (vdec_bufferpayload)); 4012 DEBUG_PRINT_LOW("unmap the input buffer fd=%d", 4013 drv_ctx.ptr_inputbuffer[index].pmem_fd); 4014 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %d", 4015 drv_ctx.ptr_inputbuffer[index].mmaped_size, 4016 drv_ctx.ptr_inputbuffer[index].bufferaddr); 4017 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, 4018 drv_ctx.ptr_inputbuffer[index].mmaped_size); 4019 close (drv_ctx.ptr_inputbuffer[index].pmem_fd); 4020 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; 4021 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) { 4022 free(m_desc_buffer_ptr[index].buf_addr); 4023 m_desc_buffer_ptr[index].buf_addr = NULL; 4024 m_desc_buffer_ptr[index].desc_data_size = 0; 4025 } 4026#ifdef USE_ION 4027 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); 4028#endif 4029 } 4030 } 4031 4032 return OMX_ErrorNone; 4033} 4034 4035OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 4036{ 4037 unsigned int index = 0; 4038 4039 if (bufferHdr == NULL || m_out_mem_ptr == NULL) { 4040 return OMX_ErrorBadParameter; 4041 } 4042 4043 index = bufferHdr - m_out_mem_ptr; 4044 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); 4045 4046 if (index < drv_ctx.op_buf.actualcount 4047 && drv_ctx.ptr_outputbuffer) { 4048 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %x", index, 4049 drv_ctx.ptr_outputbuffer[index].bufferaddr); 4050 4051 struct vdec_setbuffer_cmd setbuffers; 4052 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 4053 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], 4054 sizeof (vdec_bufferpayload)); 4055#ifdef _ANDROID_ 4056 if (m_enable_android_native_buffers) { 4057 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { 4058 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, 4059 drv_ctx.ptr_outputbuffer[index].mmaped_size); 4060 } 4061 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 4062 } else { 4063#endif 4064 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) { 4065 DEBUG_PRINT_LOW("unmap the output buffer fd = %d", 4066 drv_ctx.ptr_outputbuffer[0].pmem_fd); 4067 DEBUG_PRINT_LOW("unmap the ouput buffer size=%d address = %d", 4068 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, 4069 drv_ctx.ptr_outputbuffer[0].bufferaddr); 4070 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, 4071 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); 4072 close (drv_ctx.ptr_outputbuffer[0].pmem_fd); 4073 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; 4074#ifdef USE_ION 4075 free_ion_memory(&drv_ctx.op_buf_ion_info[0]); 4076#endif 4077 } 4078#ifdef _ANDROID_ 4079 } 4080#endif 4081 if (release_output_done()) { 4082 free_extradata(); 4083 } 4084 } 4085 4086 return OMX_ErrorNone; 4087 4088} 4089 4090OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 4091 OMX_BUFFERHEADERTYPE **bufferHdr, 4092 OMX_U32 port, 4093 OMX_PTR appData, 4094 OMX_U32 bytes) 4095{ 4096 OMX_BUFFERHEADERTYPE *input = NULL; 4097 unsigned char *buf_addr = NULL; 4098 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4099 unsigned i = 0; 4100 4101 /* Sanity Check*/ 4102 if (bufferHdr == NULL) { 4103 return OMX_ErrorBadParameter; 4104 } 4105 4106 if (m_inp_heap_ptr == NULL) { 4107 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 4108 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 4109 drv_ctx.ip_buf.actualcount); 4110 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 4111 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 4112 drv_ctx.ip_buf.actualcount); 4113 4114 if (m_inp_heap_ptr == NULL) { 4115 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed "); 4116 return OMX_ErrorInsufficientResources; 4117 } 4118 } 4119 4120 /*Find a Free index*/ 4121 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 4122 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) { 4123 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 4124 break; 4125 } 4126 } 4127 4128 if (i < drv_ctx.ip_buf.actualcount) { 4129 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); 4130 4131 if (buf_addr == NULL) { 4132 return OMX_ErrorInsufficientResources; 4133 } 4134 4135 *bufferHdr = (m_inp_heap_ptr + i); 4136 input = *bufferHdr; 4137 BITMASK_SET(&m_heap_inp_bm_count,i); 4138 4139 input->pBuffer = (OMX_U8 *)buf_addr; 4140 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4141 input->nVersion.nVersion = OMX_SPEC_VERSION; 4142 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 4143 input->pAppPrivate = appData; 4144 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 4145 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); 4146 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 4147 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); 4148 /*Add the Buffers to freeq*/ 4149 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i], 4150 (unsigned)NULL, (unsigned)NULL)) { 4151 DEBUG_PRINT_ERROR("ERROR:Free_q is full"); 4152 return OMX_ErrorInsufficientResources; 4153 } 4154 } else { 4155 return OMX_ErrorBadParameter; 4156 } 4157 4158 return eRet; 4159 4160} 4161 4162 4163/* ====================================================================== 4164 FUNCTION 4165 omx_vdec::AllocateInputBuffer 4166 4167 DESCRIPTION 4168 Helper function for allocate buffer in the input pin 4169 4170 PARAMETERS 4171 None. 4172 4173 RETURN VALUE 4174 true/false 4175 4176 ========================================================================== */ 4177OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 4178 OMX_IN OMX_HANDLETYPE hComp, 4179 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4180 OMX_IN OMX_U32 port, 4181 OMX_IN OMX_PTR appData, 4182 OMX_IN OMX_U32 bytes) 4183{ 4184 4185 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4186 struct vdec_setbuffer_cmd setbuffers; 4187 OMX_BUFFERHEADERTYPE *input = NULL; 4188 unsigned i = 0; 4189 unsigned char *buf_addr = NULL; 4190 int pmem_fd = -1; 4191 4192 if (bytes != drv_ctx.ip_buf.buffer_size) { 4193 DEBUG_PRINT_LOW("Requested Size is wrong %d epected is %d", 4194 bytes, drv_ctx.ip_buf.buffer_size); 4195 return OMX_ErrorBadParameter; 4196 } 4197 4198 if (!m_inp_mem_ptr) { 4199 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)", 4200 drv_ctx.ip_buf.actualcount, 4201 drv_ctx.ip_buf.buffer_size); 4202 4203 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 4204 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); 4205 4206 if (m_inp_mem_ptr == NULL) { 4207 return OMX_ErrorInsufficientResources; 4208 } 4209 4210 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 4211 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); 4212 4213 if (drv_ctx.ptr_inputbuffer == NULL) { 4214 return OMX_ErrorInsufficientResources; 4215 } 4216#ifdef USE_ION 4217 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ 4218 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); 4219 4220 if (drv_ctx.ip_buf_ion_info == NULL) { 4221 return OMX_ErrorInsufficientResources; 4222 } 4223#endif 4224 4225 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) { 4226 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; 4227#ifdef USE_ION 4228 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; 4229#endif 4230 } 4231 } 4232 4233 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) { 4234 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 4235 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); 4236 break; 4237 } 4238 } 4239 4240 if (i < drv_ctx.ip_buf.actualcount) { 4241 struct v4l2_buffer buf; 4242 struct v4l2_plane plane; 4243 int rc; 4244 4245#ifdef USE_ION 4246 DEBUG_PRINT_HIGH("Allocate input Buffer size %d", drv_ctx.ip_buf.buffer_size); 4247 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 4248 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, 4249 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, 4250 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); 4251 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { 4252 return OMX_ErrorInsufficientResources; 4253 } 4254 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; 4255#else 4256 pmem_fd = open (MEM_DEVICE,O_RDWR); 4257 4258 if (pmem_fd < 0) { 4259 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 4260 return OMX_ErrorInsufficientResources; 4261 } 4262 4263 if (pmem_fd == 0) { 4264 pmem_fd = open (MEM_DEVICE,O_RDWR); 4265 4266 if (pmem_fd < 0) { 4267 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer"); 4268 return OMX_ErrorInsufficientResources; 4269 } 4270 } 4271 4272 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, 4273 drv_ctx.ip_buf.alignment)) { 4274 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 4275 close(pmem_fd); 4276 return OMX_ErrorInsufficientResources; 4277 } 4278#endif 4279 if (!secure_mode) { 4280 buf_addr = (unsigned char *)mmap(NULL, 4281 drv_ctx.ip_buf.buffer_size, 4282 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); 4283 4284 if (buf_addr == MAP_FAILED) { 4285 close(pmem_fd); 4286#ifdef USE_ION 4287 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); 4288#endif 4289 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer"); 4290 return OMX_ErrorInsufficientResources; 4291 } 4292 } 4293 *bufferHdr = (m_inp_mem_ptr + i); 4294 if (secure_mode) 4295 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; 4296 else 4297 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; 4298 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; 4299 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; 4300 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; 4301 drv_ctx.ptr_inputbuffer [i].offset = 0; 4302 4303 4304 buf.index = i; 4305 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4306 buf.memory = V4L2_MEMORY_USERPTR; 4307 plane.bytesused = 0; 4308 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; 4309 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; 4310 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; 4311 plane.reserved[1] = 0; 4312 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; 4313 buf.m.planes = &plane; 4314 buf.length = 1; 4315 4316 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_inputbuffer[i]); 4317 4318 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 4319 4320 if (rc) { 4321 DEBUG_PRINT_ERROR("Failed to prepare bufs"); 4322 /*TODO: How to handle this case */ 4323 return OMX_ErrorInsufficientResources; 4324 } 4325 4326 input = *bufferHdr; 4327 BITMASK_SET(&m_inp_bm_count,i); 4328 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); 4329 if (secure_mode) 4330 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; 4331 else 4332 input->pBuffer = (OMX_U8 *)buf_addr; 4333 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4334 input->nVersion.nVersion = OMX_SPEC_VERSION; 4335 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 4336 input->pAppPrivate = appData; 4337 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 4338 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; 4339 4340 if (drv_ctx.disable_dmx) { 4341 eRet = allocate_desc_buffer(i); 4342 } 4343 } else { 4344 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found"); 4345 eRet = OMX_ErrorInsufficientResources; 4346 } 4347 return eRet; 4348} 4349 4350 4351/* ====================================================================== 4352 FUNCTION 4353 omx_vdec::AllocateOutputBuffer 4354 4355 DESCRIPTION 4356 Helper fn for AllocateBuffer in the output pin 4357 4358 PARAMETERS 4359 <TBD>. 4360 4361 RETURN VALUE 4362 OMX Error None if everything went well. 4363 4364 ========================================================================== */ 4365OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 4366 OMX_IN OMX_HANDLETYPE hComp, 4367 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4368 OMX_IN OMX_U32 port, 4369 OMX_IN OMX_PTR appData, 4370 OMX_IN OMX_U32 bytes) 4371{ 4372 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4373 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 4374 unsigned i= 0; // Temporary counter 4375 struct vdec_setbuffer_cmd setbuffers; 4376 int extra_idx = 0; 4377#ifdef USE_ION 4378 int ion_device_fd =-1; 4379 struct ion_allocation_data ion_alloc_data; 4380 struct ion_fd_data fd_ion_data; 4381#endif 4382 if (!m_out_mem_ptr) { 4383 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)", 4384 drv_ctx.op_buf.actualcount, 4385 drv_ctx.op_buf.buffer_size); 4386 int nBufHdrSize = 0; 4387 int nPlatformEntrySize = 0; 4388 int nPlatformListSize = 0; 4389 int nPMEMInfoSize = 0; 4390 int pmem_fd = -1; 4391 unsigned char *pmem_baseaddress = NULL; 4392 4393 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 4394 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 4395 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 4396 4397 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", 4398 drv_ctx.op_buf.actualcount); 4399 nBufHdrSize = drv_ctx.op_buf.actualcount * 4400 sizeof(OMX_BUFFERHEADERTYPE); 4401 4402 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 4403 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 4404 nPlatformListSize = drv_ctx.op_buf.actualcount * 4405 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 4406 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 4407 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 4408 4409 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, 4410 sizeof(OMX_BUFFERHEADERTYPE), 4411 nPMEMInfoSize, 4412 nPlatformListSize); 4413 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, 4414 drv_ctx.op_buf.actualcount); 4415#ifdef USE_ION 4416 DEBUG_PRINT_HIGH("allocate outputBuffer size %d",drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount); 4417 ion_device_fd = alloc_map_ion_memory( 4418 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, 4419 drv_ctx.op_buf.alignment, 4420 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0); 4421 if (ion_device_fd < 0) { 4422 return OMX_ErrorInsufficientResources; 4423 } 4424 pmem_fd = fd_ion_data.fd; 4425#else 4426 pmem_fd = open (MEM_DEVICE,O_RDWR); 4427 4428 if (pmem_fd < 0) { 4429 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d", 4430 drv_ctx.op_buf.buffer_size); 4431 return OMX_ErrorInsufficientResources; 4432 } 4433 4434 if (pmem_fd == 0) { 4435 pmem_fd = open (MEM_DEVICE,O_RDWR); 4436 4437 if (pmem_fd < 0) { 4438 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d", 4439 drv_ctx.op_buf.buffer_size); 4440 return OMX_ErrorInsufficientResources; 4441 } 4442 } 4443 4444 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * 4445 drv_ctx.op_buf.actualcount, 4446 drv_ctx.op_buf.alignment)) { 4447 DEBUG_PRINT_ERROR("align_pmem_buffers() failed"); 4448 close(pmem_fd); 4449 return OMX_ErrorInsufficientResources; 4450 } 4451#endif 4452 if (!secure_mode) { 4453 pmem_baseaddress = (unsigned char *)mmap(NULL, 4454 (drv_ctx.op_buf.buffer_size * 4455 drv_ctx.op_buf.actualcount), 4456 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); 4457 if (pmem_baseaddress == MAP_FAILED) { 4458 DEBUG_PRINT_ERROR("MMAP failed for Size %d", 4459 drv_ctx.op_buf.buffer_size); 4460 close(pmem_fd); 4461#ifdef USE_ION 4462 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 4463#endif 4464 return OMX_ErrorInsufficientResources; 4465 } 4466 } 4467 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 4468 // Alloc mem for platform specific info 4469 char *pPtr=NULL; 4470 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 4471 nPMEMInfoSize,1); 4472 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ 4473 calloc (sizeof(struct vdec_bufferpayload), 4474 drv_ctx.op_buf.actualcount); 4475 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 4476 calloc (sizeof (struct vdec_output_frameinfo), 4477 drv_ctx.op_buf.actualcount); 4478#ifdef USE_ION 4479 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ 4480 calloc (sizeof(struct vdec_ion), 4481 drv_ctx.op_buf.actualcount); 4482#endif 4483 4484 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 4485 && drv_ctx.ptr_respbuffer) { 4486 drv_ctx.ptr_outputbuffer[0].mmaped_size = 4487 (drv_ctx.op_buf.buffer_size * 4488 drv_ctx.op_buf.actualcount); 4489 bufHdr = m_out_mem_ptr; 4490 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 4491 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 4492 (((char *) m_platform_list) + nPlatformListSize); 4493 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 4494 (((char *) m_platform_entry) + nPlatformEntrySize); 4495 pPlatformList = m_platform_list; 4496 pPlatformEntry = m_platform_entry; 4497 pPMEMInfo = m_pmem_info; 4498 4499 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 4500 4501 // Settting the entire storage nicely 4502 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); 4503 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 4504 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 4505 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4506 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 4507 // Set the values when we determine the right HxW param 4508 bufHdr->nAllocLen = bytes; 4509 bufHdr->nFilledLen = 0; 4510 bufHdr->pAppPrivate = appData; 4511 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 4512 // Platform specific PMEM Information 4513 // Initialize the Platform Entry 4514 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); 4515 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 4516 pPlatformEntry->entry = pPMEMInfo; 4517 // Initialize the Platform List 4518 pPlatformList->nEntries = 1; 4519 pPlatformList->entryList = pPlatformEntry; 4520 // Keep pBuffer NULL till vdec is opened 4521 bufHdr->pBuffer = NULL; 4522 bufHdr->nOffset = 0; 4523 4524 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; 4525 pPMEMInfo->pmem_fd = 0; 4526 bufHdr->pPlatformPrivate = pPlatformList; 4527 4528 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; 4529 m_pmem_info[i].pmem_fd = pmem_fd; 4530#ifdef USE_ION 4531 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; 4532 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; 4533 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; 4534#endif 4535 4536 /*Create a mapping between buffers*/ 4537 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 4538 drv_ctx.ptr_respbuffer[i].client_data = (void *)\ 4539 &drv_ctx.ptr_outputbuffer[i]; 4540 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; 4541 drv_ctx.ptr_outputbuffer[i].bufferaddr = 4542 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); 4543 4544 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p", 4545 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, 4546 drv_ctx.ptr_outputbuffer[i].bufferaddr); 4547 // Move the buffer and buffer header pointers 4548 bufHdr++; 4549 pPMEMInfo++; 4550 pPlatformEntry++; 4551 pPlatformList++; 4552 } 4553 } else { 4554 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 4555 m_out_mem_ptr, pPtr); 4556 if (m_out_mem_ptr) { 4557 free(m_out_mem_ptr); 4558 m_out_mem_ptr = NULL; 4559 } 4560 if (pPtr) { 4561 free(pPtr); 4562 pPtr = NULL; 4563 } 4564 if (drv_ctx.ptr_outputbuffer) { 4565 free(drv_ctx.ptr_outputbuffer); 4566 drv_ctx.ptr_outputbuffer = NULL; 4567 } 4568 if (drv_ctx.ptr_respbuffer) { 4569 free(drv_ctx.ptr_respbuffer); 4570 drv_ctx.ptr_respbuffer = NULL; 4571 } 4572#ifdef USE_ION 4573 if (drv_ctx.op_buf_ion_info) { 4574 DEBUG_PRINT_LOW("Free o/p ion context"); 4575 free(drv_ctx.op_buf_ion_info); 4576 drv_ctx.op_buf_ion_info = NULL; 4577 } 4578#endif 4579 eRet = OMX_ErrorInsufficientResources; 4580 } 4581 if (eRet == OMX_ErrorNone) 4582 eRet = allocate_extradata(); 4583 } 4584 4585 for (i=0; i< drv_ctx.op_buf.actualcount; i++) { 4586 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 4587 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i); 4588 break; 4589 } 4590 } 4591 4592 if (eRet == OMX_ErrorNone) { 4593 if (i < drv_ctx.op_buf.actualcount) { 4594 struct v4l2_buffer buf; 4595 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 4596 int rc; 4597 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 4598 4599 drv_ctx.ptr_outputbuffer[i].buffer_len = 4600 drv_ctx.op_buf.buffer_size; 4601 4602 *bufferHdr = (m_out_mem_ptr + i ); 4603 if (secure_mode) { 4604 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 4605 } 4606 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; 4607 4608 buf.index = i; 4609 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4610 buf.memory = V4L2_MEMORY_USERPTR; 4611 plane[0].length = drv_ctx.op_buf.buffer_size; 4612 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - 4613 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; 4614#ifdef USE_ION 4615 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 4616#endif 4617 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; 4618 plane[0].data_offset = 0; 4619 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 4620 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 4621 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 4622 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); 4623#ifdef USE_ION 4624 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 4625#endif 4626 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; 4627 plane[extra_idx].data_offset = 0; 4628 } else if (extra_idx >= VIDEO_MAX_PLANES) { 4629 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx); 4630 return OMX_ErrorBadParameter; 4631 } 4632 buf.m.planes = plane; 4633 buf.length = drv_ctx.num_planes; 4634 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); 4635 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); 4636 if (rc) { 4637 /*TODO: How to handle this case */ 4638 return OMX_ErrorInsufficientResources; 4639 } 4640 4641 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { 4642 enum v4l2_buf_type buf_type; 4643 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 4644 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 4645 if (rc) { 4646 return OMX_ErrorInsufficientResources; 4647 } else { 4648 streaming[CAPTURE_PORT] = true; 4649 DEBUG_PRINT_LOW("STREAMON Successful"); 4650 } 4651 } 4652 4653 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; 4654 (*bufferHdr)->pAppPrivate = appData; 4655 BITMASK_SET(&m_out_bm_count,i); 4656 } else { 4657 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient"); 4658 eRet = OMX_ErrorInsufficientResources; 4659 } 4660 } 4661 4662 return eRet; 4663} 4664 4665 4666// AllocateBuffer -- API Call 4667/* ====================================================================== 4668 FUNCTION 4669 omx_vdec::AllocateBuffer 4670 4671 DESCRIPTION 4672 Returns zero if all the buffers released.. 4673 4674 PARAMETERS 4675 None. 4676 4677 RETURN VALUE 4678 true/false 4679 4680 ========================================================================== */ 4681OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 4682 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4683 OMX_IN OMX_U32 port, 4684 OMX_IN OMX_PTR appData, 4685 OMX_IN OMX_U32 bytes) 4686{ 4687 unsigned i = 0; 4688 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 4689 4690 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); 4691 if (m_state == OMX_StateInvalid) { 4692 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State"); 4693 return OMX_ErrorInvalidState; 4694 } 4695 4696 if (port == OMX_CORE_INPUT_PORT_INDEX) { 4697 if (arbitrary_bytes) { 4698 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 4699 } else { 4700 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 4701 } 4702 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 4703 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, 4704 appData,bytes); 4705 } else { 4706 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port); 4707 eRet = OMX_ErrorBadPortIndex; 4708 } 4709 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 4710 if (eRet == OMX_ErrorNone) { 4711 if (allocate_done()) { 4712 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 4713 // Send the callback now 4714 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 4715 post_event(OMX_CommandStateSet,OMX_StateIdle, 4716 OMX_COMPONENT_GENERATE_EVENT); 4717 } 4718 } 4719 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) { 4720 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 4721 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 4722 post_event(OMX_CommandPortEnable, 4723 OMX_CORE_INPUT_PORT_INDEX, 4724 OMX_COMPONENT_GENERATE_EVENT); 4725 } 4726 } 4727 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) { 4728 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 4729 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 4730 post_event(OMX_CommandPortEnable, 4731 OMX_CORE_OUTPUT_PORT_INDEX, 4732 OMX_COMPONENT_GENERATE_EVENT); 4733 } 4734 } 4735 } 4736 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); 4737 return eRet; 4738} 4739 4740// Free Buffer - API call 4741/* ====================================================================== 4742 FUNCTION 4743 omx_vdec::FreeBuffer 4744 4745 DESCRIPTION 4746 4747 PARAMETERS 4748 None. 4749 4750 RETURN VALUE 4751 true/false 4752 4753 ========================================================================== */ 4754OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 4755 OMX_IN OMX_U32 port, 4756 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4757{ 4758 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4759 unsigned int nPortIndex; 4760 DEBUG_PRINT_LOW("In for decoder free_buffer"); 4761 4762 if (m_state == OMX_StateIdle && 4763 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 4764 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); 4765 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 4766 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) { 4767 DEBUG_PRINT_LOW("Free Buffer while port %d disabled", port); 4768 } else if ((port == OMX_CORE_INPUT_PORT_INDEX && 4769 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || 4770 (port == OMX_CORE_OUTPUT_PORT_INDEX && 4771 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) { 4772 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending", port); 4773 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) { 4774 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled"); 4775 post_event(OMX_EventError, 4776 OMX_ErrorPortUnpopulated, 4777 OMX_COMPONENT_GENERATE_EVENT); 4778 4779 return OMX_ErrorIncorrectStateOperation; 4780 } else if (m_state != OMX_StateInvalid) { 4781 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers"); 4782 post_event(OMX_EventError, 4783 OMX_ErrorPortUnpopulated, 4784 OMX_COMPONENT_GENERATE_EVENT); 4785 } 4786 4787 if (port == OMX_CORE_INPUT_PORT_INDEX) { 4788 /*Check if arbitrary bytes*/ 4789 if (!arbitrary_bytes && !input_use_buffer) 4790 nPortIndex = buffer - m_inp_mem_ptr; 4791 else 4792 nPortIndex = buffer - m_inp_heap_ptr; 4793 4794 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); 4795 if (nPortIndex < drv_ctx.ip_buf.actualcount) { 4796 // Clear the bit associated with it. 4797 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 4798 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 4799 if (input_use_buffer == true) { 4800 4801 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); 4802 if (m_phdr_pmem_ptr) 4803 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 4804 } else { 4805 if (arbitrary_bytes) { 4806 if (m_phdr_pmem_ptr) 4807 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); 4808 else 4809 free_input_buffer(nPortIndex,NULL); 4810 } else 4811 free_input_buffer(buffer); 4812 } 4813 m_inp_bPopulated = OMX_FALSE; 4814 /*Free the Buffer Header*/ 4815 if (release_input_done()) { 4816 DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); 4817 free_input_buffer_header(); 4818 } 4819 } else { 4820 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid"); 4821 eRet = OMX_ErrorBadPortIndex; 4822 } 4823 4824 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 4825 && release_input_done()) { 4826 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 4827 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 4828 post_event(OMX_CommandPortDisable, 4829 OMX_CORE_INPUT_PORT_INDEX, 4830 OMX_COMPONENT_GENERATE_EVENT); 4831 } 4832 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 4833 // check if the buffer is valid 4834 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 4835 if (nPortIndex < drv_ctx.op_buf.actualcount) { 4836 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); 4837 // Clear the bit associated with it. 4838 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 4839 m_out_bPopulated = OMX_FALSE; 4840 client_buffers.free_output_buffer (buffer); 4841 4842 if (release_output_done()) { 4843 free_output_buffer_header(); 4844 } 4845 } else { 4846 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid"); 4847 eRet = OMX_ErrorBadPortIndex; 4848 } 4849 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 4850 && release_output_done()) { 4851 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); 4852 4853 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 4854 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 4855#ifdef _ANDROID_ICS_ 4856 if (m_enable_android_native_buffers) { 4857 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); 4858 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 4859 } 4860#endif 4861 4862 post_event(OMX_CommandPortDisable, 4863 OMX_CORE_OUTPUT_PORT_INDEX, 4864 OMX_COMPONENT_GENERATE_EVENT); 4865 } 4866 } else { 4867 eRet = OMX_ErrorBadPortIndex; 4868 } 4869 if ((eRet == OMX_ErrorNone) && 4870 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 4871 if (release_done()) { 4872 // Send the callback now 4873 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 4874 post_event(OMX_CommandStateSet, OMX_StateLoaded, 4875 OMX_COMPONENT_GENERATE_EVENT); 4876 } 4877 } 4878 return eRet; 4879} 4880 4881 4882/* ====================================================================== 4883 FUNCTION 4884 omx_vdec::EmptyThisBuffer 4885 4886 DESCRIPTION 4887 This routine is used to push the encoded video frames to 4888 the video decoder. 4889 4890 PARAMETERS 4891 None. 4892 4893 RETURN VALUE 4894 OMX Error None if everything went successful. 4895 4896 ========================================================================== */ 4897OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 4898 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4899{ 4900 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 4901 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; 4902 4903 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 4904 codec_config_flag = true; 4905 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); 4906 } 4907 if (m_state == OMX_StateInvalid) { 4908 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State"); 4909 return OMX_ErrorInvalidState; 4910 } 4911 4912 if (buffer == NULL) { 4913 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL"); 4914 return OMX_ErrorBadParameter; 4915 } 4916 4917 if (!m_inp_bEnabled) { 4918 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled."); 4919 return OMX_ErrorIncorrectStateOperation; 4920 } 4921 4922 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) { 4923 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex); 4924 return OMX_ErrorBadPortIndex; 4925 } 4926 4927 if (perf_flag) { 4928 if (!latency) { 4929 dec_time.stop(); 4930 latency = dec_time.processing_time_us(); 4931 dec_time.start(); 4932 } 4933 } 4934 4935 if (arbitrary_bytes) { 4936 nBufferIndex = buffer - m_inp_heap_ptr; 4937 } else { 4938 if (input_use_buffer == true) { 4939 nBufferIndex = buffer - m_inp_heap_ptr; 4940 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; 4941 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; 4942 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; 4943 buffer = &m_inp_mem_ptr[nBufferIndex]; 4944 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", 4945 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); 4946 } else { 4947 nBufferIndex = buffer - m_inp_mem_ptr; 4948 } 4949 } 4950 4951 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) { 4952 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid"); 4953 return OMX_ErrorBadParameter; 4954 } 4955 4956 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", 4957 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); 4958 if (arbitrary_bytes) { 4959 post_event ((unsigned)hComp,(unsigned)buffer, 4960 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 4961 } else { 4962 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) 4963 set_frame_rate(buffer->nTimeStamp); 4964 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); 4965 } 4966 return OMX_ErrorNone; 4967} 4968 4969/* ====================================================================== 4970 FUNCTION 4971 omx_vdec::empty_this_buffer_proxy 4972 4973 DESCRIPTION 4974 This routine is used to push the encoded video frames to 4975 the video decoder. 4976 4977 PARAMETERS 4978 None. 4979 4980 RETURN VALUE 4981 OMX Error None if everything went successful. 4982 4983 ========================================================================== */ 4984OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 4985 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4986{ 4987 int push_cnt = 0,i=0; 4988 unsigned nPortIndex = 0; 4989 OMX_ERRORTYPE ret = OMX_ErrorNone; 4990 struct vdec_input_frameinfo frameinfo; 4991 struct vdec_bufferpayload *temp_buffer; 4992 struct vdec_seqheader seq_header; 4993 bool port_setting_changed = true; 4994 bool not_coded_vop = false; 4995 4996 /*Should we generate a Aync error event*/ 4997 if (buffer == NULL || buffer->pInputPortPrivate == NULL) { 4998 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid"); 4999 return OMX_ErrorBadParameter; 5000 } 5001 5002 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 5003 5004 if (nPortIndex > drv_ctx.ip_buf.actualcount) { 5005 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 5006 nPortIndex); 5007 return OMX_ErrorBadParameter; 5008 } 5009 5010 pending_input_buffers++; 5011 5012 /* return zero length and not an EOS buffer */ 5013 if (!arbitrary_bytes && (buffer->nFilledLen == 0) && 5014 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) { 5015 DEBUG_PRINT_HIGH("return zero legth buffer"); 5016 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5017 OMX_COMPONENT_GENERATE_EBD); 5018 return OMX_ErrorNone; 5019 } 5020 5021 5022 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) { 5023 mp4StreamType psBits; 5024 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); 5025 psBits.numBytes = buffer->nFilledLen; 5026 mp4_headerparser.parseHeader(&psBits); 5027 not_coded_vop = mp4_headerparser.is_notcodec_vop( 5028 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 5029 if (not_coded_vop) { 5030 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u", 5031 buffer->nFilledLen,frame_count); 5032 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 5033 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero"); 5034 not_coded_vop = false; 5035 buffer->nFilledLen = 0; 5036 } 5037 } 5038 } 5039 5040 if (input_flush_progress == true 5041 5042 || not_coded_vop 5043 5044 ) { 5045 DEBUG_PRINT_LOW("Flush in progress return buffer "); 5046 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5047 OMX_COMPONENT_GENERATE_EBD); 5048 return OMX_ErrorNone; 5049 } 5050 5051 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 5052 5053 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) { 5054 return OMX_ErrorBadParameter; 5055 } 5056 5057 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 5058 /*for use buffer we need to memcpy the data*/ 5059 temp_buffer->buffer_len = buffer->nFilledLen; 5060 5061 if (input_use_buffer) { 5062 if (buffer->nFilledLen <= temp_buffer->buffer_len) { 5063 if (arbitrary_bytes) { 5064 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 5065 } else { 5066 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), 5067 buffer->nFilledLen); 5068 } 5069 } else { 5070 return OMX_ErrorBadParameter; 5071 } 5072 5073 } 5074 5075 frameinfo.bufferaddr = temp_buffer->bufferaddr; 5076 frameinfo.client_data = (void *) buffer; 5077 frameinfo.datalen = temp_buffer->buffer_len; 5078 frameinfo.flags = 0; 5079 frameinfo.offset = buffer->nOffset; 5080 frameinfo.pmem_fd = temp_buffer->pmem_fd; 5081 frameinfo.pmem_offset = temp_buffer->offset; 5082 frameinfo.timestamp = buffer->nTimeStamp; 5083 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) { 5084 DEBUG_PRINT_LOW("ETB: dmx enabled"); 5085 if (m_demux_entries == 0) { 5086 extract_demux_addr_offsets(buffer); 5087 } 5088 5089 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); 5090 handle_demux_data(buffer); 5091 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; 5092 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; 5093 } else { 5094 frameinfo.desc_addr = NULL; 5095 frameinfo.desc_size = 0; 5096 } 5097 if (!arbitrary_bytes) { 5098 frameinfo.flags |= buffer->nFlags; 5099 } 5100 5101#ifdef _ANDROID_ 5102 if (m_debug_timestamp) { 5103 if (arbitrary_bytes) { 5104 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 5105 m_timestamp_list.insert_ts(buffer->nTimeStamp); 5106 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 5107 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 5108 m_timestamp_list.insert_ts(buffer->nTimeStamp); 5109 } 5110 } 5111#endif 5112 5113#ifdef INPUT_BUFFER_LOG 5114 if (inputBufferFile1) { 5115 fwrite((const char *)temp_buffer->bufferaddr, 5116 temp_buffer->buffer_len,1,inputBufferFile1); 5117 } 5118#endif 5119 5120 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { 5121 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 5122 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 5123 } 5124 5125 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 5126 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); 5127 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 5128 h264_scratch.nFilledLen = 0; 5129 nal_count = 0; 5130 look_ahead_nal = false; 5131 frame_count = 0; 5132 if (m_frame_parser.mutils) 5133 m_frame_parser.mutils->initialize_frame_checking_environment(); 5134 m_frame_parser.flush(); 5135 h264_last_au_ts = LLONG_MAX; 5136 h264_last_au_flags = 0; 5137 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 5138 m_demux_entries = 0; 5139 } 5140 struct v4l2_buffer buf; 5141 struct v4l2_plane plane; 5142 memset( (void *)&buf, 0, sizeof(buf)); 5143 memset( (void *)&plane, 0, sizeof(plane)); 5144 int rc; 5145 unsigned long print_count; 5146 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 5147 buf.flags = V4L2_QCOM_BUF_FLAG_EOS; 5148 DEBUG_PRINT_HIGH("INPUT EOS reached") ; 5149 } 5150 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5151 buf.index = nPortIndex; 5152 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5153 buf.memory = V4L2_MEMORY_USERPTR; 5154 plane.bytesused = temp_buffer->buffer_len; 5155 plane.length = drv_ctx.ip_buf.buffer_size; 5156 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - 5157 (unsigned long)temp_buffer->offset; 5158 plane.reserved[0] = temp_buffer->pmem_fd; 5159 plane.reserved[1] = temp_buffer->offset; 5160 plane.data_offset = 0; 5161 buf.m.planes = &plane; 5162 buf.length = 1; 5163 if (frameinfo.timestamp >= LLONG_MAX) { 5164 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; 5165 } 5166 //assumption is that timestamp is in milliseconds 5167 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; 5168 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); 5169 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; 5170 5171 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 5172 if (rc) { 5173 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver"); 5174 return OMX_ErrorHardware; 5175 } 5176 codec_config_flag = false; 5177 DEBUG_PRINT_LOW("%s: codec_config cleared", __FUNCTION__); 5178 5179 if (!streaming[OUTPUT_PORT]) { 5180 enum v4l2_buf_type buf_type; 5181 int ret,r; 5182 5183 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5184 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 5185 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); 5186 if (!ret) { 5187 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful"); 5188 streaming[OUTPUT_PORT] = true; 5189 } else { 5190 /*TODO: How to handle this case */ 5191 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT"); 5192 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); 5193 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5194 OMX_COMPONENT_GENERATE_EBD); 5195 return OMX_ErrorBadParameter; 5196 } 5197 } 5198 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", 5199 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); 5200 time_stamp_dts.insert_timestamp(buffer); 5201 5202 return ret; 5203} 5204 5205/* ====================================================================== 5206 FUNCTION 5207 omx_vdec::FillThisBuffer 5208 5209 DESCRIPTION 5210 IL client uses this method to release the frame buffer 5211 after displaying them. 5212 5213 PARAMETERS 5214 None. 5215 5216 RETURN VALUE 5217 true/false 5218 5219 ========================================================================== */ 5220OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 5221 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 5222{ 5223 unsigned nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 5224 5225 if (m_state == OMX_StateInvalid) { 5226 DEBUG_PRINT_ERROR("FTB in Invalid State"); 5227 return OMX_ErrorInvalidState; 5228 } 5229 5230 if (!m_out_bEnabled) { 5231 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); 5232 return OMX_ErrorIncorrectStateOperation; 5233 } 5234 5235 if (buffer == NULL || 5236 (nPortIndex >= drv_ctx.op_buf.actualcount)) { 5237 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 5238 nPortIndex, drv_ctx.op_buf.actualcount); 5239 return OMX_ErrorBadParameter; 5240 } 5241 5242 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) { 5243 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex); 5244 return OMX_ErrorBadPortIndex; 5245 } 5246 5247 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 5248 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg); 5249 return OMX_ErrorNone; 5250} 5251/* ====================================================================== 5252 FUNCTION 5253 omx_vdec::fill_this_buffer_proxy 5254 5255 DESCRIPTION 5256 IL client uses this method to release the frame buffer 5257 after displaying them. 5258 5259 PARAMETERS 5260 None. 5261 5262 RETURN VALUE 5263 true/false 5264 5265 ========================================================================== */ 5266OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 5267 OMX_IN OMX_HANDLETYPE hComp, 5268 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 5269{ 5270 OMX_ERRORTYPE nRet = OMX_ErrorNone; 5271 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 5272 unsigned nPortIndex = 0; 5273 struct vdec_fillbuffer_cmd fillbuffer; 5274 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 5275 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 5276 5277 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); 5278 5279 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) { 5280 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u", 5281 nPortIndex, drv_ctx.op_buf.actualcount); 5282 return OMX_ErrorBadParameter; 5283 } 5284 5285 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 5286 bufferAdd, bufferAdd->pBuffer); 5287 /*Return back the output buffer to client*/ 5288 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) { 5289 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); 5290 buffer->nFilledLen = 0; 5291 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5292 return OMX_ErrorNone; 5293 } 5294 pending_output_buffers++; 5295 buffer = client_buffers.get_dr_buf_hdr(bufferAdd); 5296 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 5297 if (ptr_respbuffer) { 5298 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 5299 } 5300 5301 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) { 5302 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); 5303 buffer->nFilledLen = 0; 5304 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5305 pending_output_buffers--; 5306 return OMX_ErrorBadParameter; 5307 } 5308 5309 int rc = 0; 5310 struct v4l2_buffer buf; 5311 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 5312 memset( (void *)&buf, 0, sizeof(buf)); 5313 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); 5314 int extra_idx = 0; 5315 5316 buf.index = nPortIndex; 5317 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5318 buf.memory = V4L2_MEMORY_USERPTR; 5319 plane[0].bytesused = buffer->nFilledLen; 5320 plane[0].length = drv_ctx.op_buf.buffer_size; 5321 plane[0].m.userptr = 5322 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - 5323 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; 5324 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; 5325 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; 5326 plane[0].data_offset = 0; 5327 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 5328 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 5329 plane[extra_idx].bytesused = 0; 5330 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; 5331 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); 5332#ifdef USE_ION 5333 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; 5334#endif 5335 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; 5336 plane[extra_idx].data_offset = 0; 5337 } else if (extra_idx >= VIDEO_MAX_PLANES) { 5338 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx); 5339 return OMX_ErrorBadParameter; 5340 } 5341 buf.m.planes = plane; 5342 buf.length = drv_ctx.num_planes; 5343 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); 5344 if (rc) { 5345 /*TODO: How to handle this case */ 5346 DEBUG_PRINT_ERROR("Failed to qbuf to driver"); 5347 } 5348return OMX_ErrorNone; 5349} 5350 5351/* ====================================================================== 5352 FUNCTION 5353 omx_vdec::SetCallbacks 5354 5355 DESCRIPTION 5356 Set the callbacks. 5357 5358 PARAMETERS 5359 None. 5360 5361 RETURN VALUE 5362 OMX Error None if everything successful. 5363 5364 ========================================================================== */ 5365OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 5366 OMX_IN OMX_CALLBACKTYPE* callbacks, 5367 OMX_IN OMX_PTR appData) 5368{ 5369 5370 m_cb = *callbacks; 5371 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 5372 m_cb.EventHandler,m_cb.FillBufferDone); 5373 m_app_data = appData; 5374 return OMX_ErrorNotImplemented; 5375} 5376 5377/* ====================================================================== 5378 FUNCTION 5379 omx_vdec::ComponentDeInit 5380 5381 DESCRIPTION 5382 Destroys the component and release memory allocated to the heap. 5383 5384 PARAMETERS 5385 <TBD>. 5386 5387 RETURN VALUE 5388 OMX Error None if everything successful. 5389 5390 ========================================================================== */ 5391OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 5392{ 5393 5394 unsigned i = 0; 5395 if (OMX_StateLoaded != m_state) { 5396 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\ 5397 m_state); 5398 DEBUG_PRINT_ERROR("Playback Ended - FAILED"); 5399 } else { 5400 DEBUG_PRINT_HIGH("Playback Ended - PASSED"); 5401 } 5402 5403 /*Check if the output buffers have to be cleaned up*/ 5404 if (m_out_mem_ptr) { 5405 DEBUG_PRINT_LOW("Freeing the Output Memory"); 5406 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) { 5407 free_output_buffer (&m_out_mem_ptr[i]); 5408 } 5409#ifdef _ANDROID_ICS_ 5410 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); 5411#endif 5412 } 5413 5414 /*Check if the input buffers have to be cleaned up*/ 5415 if (m_inp_mem_ptr || m_inp_heap_ptr) { 5416 DEBUG_PRINT_LOW("Freeing the Input Memory"); 5417 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) { 5418 if (m_inp_mem_ptr) 5419 free_input_buffer (i,&m_inp_mem_ptr[i]); 5420 else 5421 free_input_buffer (i,NULL); 5422 } 5423 } 5424 free_input_buffer_header(); 5425 free_output_buffer_header(); 5426 if (h264_scratch.pBuffer) { 5427 free(h264_scratch.pBuffer); 5428 h264_scratch.pBuffer = NULL; 5429 } 5430 5431 if (h264_parser) { 5432 delete h264_parser; 5433 h264_parser = NULL; 5434 } 5435 5436 if (m_platform_list) { 5437 free(m_platform_list); 5438 m_platform_list = NULL; 5439 } 5440 if (m_vendor_config.pData) { 5441 free(m_vendor_config.pData); 5442 m_vendor_config.pData = NULL; 5443 } 5444 5445 // Reset counters in mesg queues 5446 m_ftb_q.m_size=0; 5447 m_cmd_q.m_size=0; 5448 m_etb_q.m_size=0; 5449 m_ftb_q.m_read = m_ftb_q.m_write =0; 5450 m_cmd_q.m_read = m_cmd_q.m_write =0; 5451 m_etb_q.m_read = m_etb_q.m_write =0; 5452#ifdef _ANDROID_ 5453 if (m_debug_timestamp) { 5454 m_timestamp_list.reset_ts_list(); 5455 } 5456#endif 5457 5458 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG"); 5459 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 5460 // NULL); 5461 DEBUG_PRINT_HIGH("Close the driver instance"); 5462 5463#ifdef INPUT_BUFFER_LOG 5464 fclose (inputBufferFile1); 5465#endif 5466#ifdef OUTPUT_BUFFER_LOG 5467 if (outputBufferFile1) 5468 fclose (outputBufferFile1); 5469#endif 5470#ifdef OUTPUT_EXTRADATA_LOG 5471 fclose (outputExtradataFile); 5472#endif 5473 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete"); 5474 return OMX_ErrorNone; 5475} 5476 5477/* ====================================================================== 5478 FUNCTION 5479 omx_vdec::UseEGLImage 5480 5481 DESCRIPTION 5482 OMX Use EGL Image method implementation <TBD>. 5483 5484 PARAMETERS 5485 <TBD>. 5486 5487 RETURN VALUE 5488 Not Implemented error. 5489 5490 ========================================================================== */ 5491OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 5492 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5493 OMX_IN OMX_U32 port, 5494 OMX_IN OMX_PTR appData, 5495 OMX_IN void* eglImage) 5496{ 5497 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; 5498 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; 5499 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; 5500 5501#ifdef USE_EGL_IMAGE_GPU 5502 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; 5503 EGLint fd = -1, offset = 0,pmemPtr = 0; 5504#else 5505 int fd = -1, offset = 0; 5506#endif 5507 DEBUG_PRINT_HIGH("use EGL image support for decoder"); 5508 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { 5509 DEBUG_PRINT_ERROR(""); 5510 } 5511#ifdef USE_EGL_IMAGE_GPU 5512 if (m_display_id == NULL) { 5513 DEBUG_PRINT_ERROR("Display ID is not set by IL client"); 5514 return OMX_ErrorInsufficientResources; 5515 } 5516 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) 5517 eglGetProcAddress("eglQueryImageKHR"); 5518 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); 5519 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); 5520 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); 5521#else //with OMX test app 5522 struct temp_egl { 5523 int pmem_fd; 5524 int offset; 5525 }; 5526 struct temp_egl *temp_egl_id = NULL; 5527 void * pmemPtr = (void *) eglImage; 5528 temp_egl_id = (struct temp_egl *)eglImage; 5529 if (temp_egl_id != NULL) { 5530 fd = temp_egl_id->pmem_fd; 5531 offset = temp_egl_id->offset; 5532 } 5533#endif 5534 if (fd < 0) { 5535 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd); 5536 return OMX_ErrorInsufficientResources; 5537 } 5538 pmem_info.pmem_fd = (OMX_U32) fd; 5539 pmem_info.offset = (OMX_U32) offset; 5540 pmem_entry.entry = (void *) &pmem_info; 5541 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 5542 pmem_list.entryList = &pmem_entry; 5543 pmem_list.nEntries = 1; 5544 ouput_egl_buffers = true; 5545 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, 5546 (void *)&pmem_list, drv_ctx.op_buf.buffer_size, 5547 (OMX_U8 *)pmemPtr)) { 5548 DEBUG_PRINT_ERROR("use buffer call failed for egl image"); 5549 return OMX_ErrorInsufficientResources; 5550 } 5551 return OMX_ErrorNone; 5552} 5553 5554/* ====================================================================== 5555 FUNCTION 5556 omx_vdec::ComponentRoleEnum 5557 5558 DESCRIPTION 5559 OMX Component Role Enum method implementation. 5560 5561 PARAMETERS 5562 <TBD>. 5563 5564 RETURN VALUE 5565 OMX Error None if everything is successful. 5566 ========================================================================== */ 5567OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 5568 OMX_OUT OMX_U8* role, 5569 OMX_IN OMX_U32 index) 5570{ 5571 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5572 5573 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 5574 if ((0 == index) && role) { 5575 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 5576 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5577 } else { 5578 eRet = OMX_ErrorNoMore; 5579 } 5580 } 5581 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) { 5582 if ((0 == index) && role) { 5583 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 5584 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5585 } else { 5586 eRet = OMX_ErrorNoMore; 5587 } 5588 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 5589 if ((0 == index) && role) { 5590 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 5591 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5592 } else { 5593 DEBUG_PRINT_LOW("No more roles"); 5594 eRet = OMX_ErrorNoMore; 5595 } 5596 } 5597 5598 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 5599 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) ) { 5600 if ((0 == index) && role) { 5601 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 5602 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5603 } else { 5604 DEBUG_PRINT_LOW("No more roles"); 5605 eRet = OMX_ErrorNoMore; 5606 } 5607 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 5608 if ((0 == index) && role) { 5609 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 5610 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5611 } else { 5612 DEBUG_PRINT_LOW("No more roles"); 5613 eRet = OMX_ErrorNoMore; 5614 } 5615 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) { 5616 if ((0 == index) && role) { 5617 strlcpy((char *)role, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); 5618 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5619 } else { 5620 DEBUG_PRINT_LOW("No more roles"); 5621 eRet = OMX_ErrorNoMore; 5622 } 5623 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 5624 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 5625 ) { 5626 if ((0 == index) && role) { 5627 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 5628 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5629 } else { 5630 DEBUG_PRINT_LOW("No more roles"); 5631 eRet = OMX_ErrorNoMore; 5632 } 5633 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 5634 if ((0 == index) && role) { 5635 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); 5636 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 5637 } else { 5638 DEBUG_PRINT_LOW("No more roles"); 5639 eRet = OMX_ErrorNoMore; 5640 } 5641 } else { 5642 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component"); 5643 eRet = OMX_ErrorInvalidComponentName; 5644 } 5645 return eRet; 5646} 5647 5648 5649 5650 5651/* ====================================================================== 5652 FUNCTION 5653 omx_vdec::AllocateDone 5654 5655 DESCRIPTION 5656 Checks if entire buffer pool is allocated by IL Client or not. 5657 Need this to move to IDLE state. 5658 5659 PARAMETERS 5660 None. 5661 5662 RETURN VALUE 5663 true/false. 5664 5665 ========================================================================== */ 5666bool omx_vdec::allocate_done(void) 5667{ 5668 bool bRet = false; 5669 bool bRet_In = false; 5670 bool bRet_Out = false; 5671 5672 bRet_In = allocate_input_done(); 5673 bRet_Out = allocate_output_done(); 5674 5675 if (bRet_In && bRet_Out) { 5676 bRet = true; 5677 } 5678 5679 return bRet; 5680} 5681/* ====================================================================== 5682 FUNCTION 5683 omx_vdec::AllocateInputDone 5684 5685 DESCRIPTION 5686 Checks if I/P buffer pool is allocated by IL Client or not. 5687 5688 PARAMETERS 5689 None. 5690 5691 RETURN VALUE 5692 true/false. 5693 5694 ========================================================================== */ 5695bool omx_vdec::allocate_input_done(void) 5696{ 5697 bool bRet = false; 5698 unsigned i=0; 5699 5700 if (m_inp_mem_ptr == NULL) { 5701 return bRet; 5702 } 5703 if (m_inp_mem_ptr ) { 5704 for (; i<drv_ctx.ip_buf.actualcount; i++) { 5705 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 5706 break; 5707 } 5708 } 5709 } 5710 if (i == drv_ctx.ip_buf.actualcount) { 5711 bRet = true; 5712 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers"); 5713 } 5714 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) { 5715 m_inp_bPopulated = OMX_TRUE; 5716 } 5717 return bRet; 5718} 5719/* ====================================================================== 5720 FUNCTION 5721 omx_vdec::AllocateOutputDone 5722 5723 DESCRIPTION 5724 Checks if entire O/P buffer pool is allocated by IL Client or not. 5725 5726 PARAMETERS 5727 None. 5728 5729 RETURN VALUE 5730 true/false. 5731 5732 ========================================================================== */ 5733bool omx_vdec::allocate_output_done(void) 5734{ 5735 bool bRet = false; 5736 unsigned j=0; 5737 5738 if (m_out_mem_ptr == NULL) { 5739 return bRet; 5740 } 5741 5742 if (m_out_mem_ptr) { 5743 for (; j < drv_ctx.op_buf.actualcount; j++) { 5744 if (BITMASK_ABSENT(&m_out_bm_count,j)) { 5745 break; 5746 } 5747 } 5748 } 5749 5750 if (j == drv_ctx.op_buf.actualcount) { 5751 bRet = true; 5752 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers"); 5753 if (m_out_bEnabled) 5754 m_out_bPopulated = OMX_TRUE; 5755 } 5756 5757 return bRet; 5758} 5759 5760/* ====================================================================== 5761 FUNCTION 5762 omx_vdec::ReleaseDone 5763 5764 DESCRIPTION 5765 Checks if IL client has released all the buffers. 5766 5767 PARAMETERS 5768 None. 5769 5770 RETURN VALUE 5771 true/false 5772 5773 ========================================================================== */ 5774bool omx_vdec::release_done(void) 5775{ 5776 bool bRet = false; 5777 5778 if (release_input_done()) { 5779 if (release_output_done()) { 5780 bRet = true; 5781 } 5782 } 5783 return bRet; 5784} 5785 5786 5787/* ====================================================================== 5788 FUNCTION 5789 omx_vdec::ReleaseOutputDone 5790 5791 DESCRIPTION 5792 Checks if IL client has released all the buffers. 5793 5794 PARAMETERS 5795 None. 5796 5797 RETURN VALUE 5798 true/false 5799 5800 ========================================================================== */ 5801bool omx_vdec::release_output_done(void) 5802{ 5803 bool bRet = false; 5804 unsigned i=0,j=0; 5805 5806 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr); 5807 if (m_out_mem_ptr) { 5808 for (; j < drv_ctx.op_buf.actualcount ; j++) { 5809 if (BITMASK_PRESENT(&m_out_bm_count,j)) { 5810 break; 5811 } 5812 } 5813 if (j == drv_ctx.op_buf.actualcount) { 5814 m_out_bm_count = 0; 5815 bRet = true; 5816 } 5817 } else { 5818 m_out_bm_count = 0; 5819 bRet = true; 5820 } 5821 return bRet; 5822} 5823/* ====================================================================== 5824 FUNCTION 5825 omx_vdec::ReleaseInputDone 5826 5827 DESCRIPTION 5828 Checks if IL client has released all the buffers. 5829 5830 PARAMETERS 5831 None. 5832 5833 RETURN VALUE 5834 true/false 5835 5836 ========================================================================== */ 5837bool omx_vdec::release_input_done(void) 5838{ 5839 bool bRet = false; 5840 unsigned i=0,j=0; 5841 5842 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 5843 if (m_inp_mem_ptr) { 5844 for (; j<drv_ctx.ip_buf.actualcount; j++) { 5845 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) { 5846 break; 5847 } 5848 } 5849 if (j==drv_ctx.ip_buf.actualcount) { 5850 bRet = true; 5851 } 5852 } else { 5853 bRet = true; 5854 } 5855 return bRet; 5856} 5857 5858OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 5859 OMX_BUFFERHEADERTYPE * buffer) 5860{ 5861 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 5862 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) { 5863 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer); 5864 return OMX_ErrorBadParameter; 5865 } else if (output_flush_progress) { 5866 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); 5867 buffer->nFilledLen = 0; 5868 buffer->nTimeStamp = 0; 5869 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 5870 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 5871 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; 5872 } 5873 5874 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 5875 buffer, buffer->pBuffer); 5876 pending_output_buffers --; 5877 5878 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 5879 DEBUG_PRINT_HIGH("Output EOS has been reached"); 5880 if (!output_flush_progress) 5881 post_event((unsigned)NULL, (unsigned)NULL, 5882 OMX_COMPONENT_GENERATE_EOS_DONE); 5883 5884 if (psource_frame) { 5885 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); 5886 psource_frame = NULL; 5887 } 5888 if (pdest_frame) { 5889 pdest_frame->nFilledLen = 0; 5890 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL, 5891 (unsigned)NULL); 5892 pdest_frame = NULL; 5893 } 5894 } 5895 5896 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer); 5897#ifdef OUTPUT_BUFFER_LOG 5898 if (outputBufferFile1 && buffer->nFilledLen) { 5899 int buf_index = buffer - m_out_mem_ptr; 5900 int stride = drv_ctx.video_resolution.stride; 5901 int scanlines = drv_ctx.video_resolution.scan_lines; 5902 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; 5903 int i; 5904 int bytes_written = 0; 5905 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { 5906 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); 5907 temp += stride; 5908 } 5909 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; 5910 int stride_c = stride; 5911 for (i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { 5912 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); 5913 temp += stride_c; 5914 } 5915 } 5916#endif 5917 5918 /* For use buffer we need to copy the data */ 5919 if (!output_flush_progress) { 5920 time_stamp_dts.get_next_timestamp(buffer, 5921 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 5922 ?true:false); 5923 if (m_debug_timestamp) { 5924 { 5925 OMX_TICKS expected_ts = 0; 5926 m_timestamp_list.pop_min_ts(expected_ts); 5927 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", 5928 buffer->nTimeStamp, expected_ts); 5929 5930 if (buffer->nTimeStamp != expected_ts) { 5931 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check"); 5932 } 5933 } 5934 } 5935 } 5936 if (m_cb.FillBufferDone) { 5937 if (buffer->nFilledLen > 0) { 5938 handle_extradata(buffer); 5939 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 5940 // Keep min timestamp interval to handle corrupted bit stream scenario 5941 set_frame_rate(buffer->nTimeStamp); 5942 else if (arbitrary_bytes) 5943 adjust_timestamp(buffer->nTimeStamp); 5944 if (perf_flag) { 5945 if (!proc_frms) { 5946 dec_time.stop(); 5947 latency = dec_time.processing_time_us() - latency; 5948 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); 5949 dec_time.start(); 5950 fps_metrics.start(); 5951 } 5952 proc_frms++; 5953 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 5954 OMX_U64 proc_time = 0; 5955 fps_metrics.stop(); 5956 proc_time = fps_metrics.processing_time_us(); 5957 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", 5958 proc_frms, (float)proc_time / 1e6, 5959 (float)(1e6 * proc_frms) / proc_time); 5960 proc_frms = 0; 5961 } 5962 } 5963 5964#ifdef OUTPUT_EXTRADATA_LOG 5965 if (outputExtradataFile) { 5966 5967 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 5968 p_extra = (OMX_OTHER_EXTRADATATYPE *) 5969 ((unsigned)(buffer->pBuffer + buffer->nOffset + 5970 buffer->nFilledLen + 3)&(~3)); 5971 while (p_extra && 5972 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) { 5973 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); 5974 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); 5975 if (p_extra->eType == OMX_ExtraDataNone) { 5976 break; 5977 } 5978 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 5979 } 5980 } 5981#endif 5982 } 5983 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { 5984 prev_ts = LLONG_MAX; 5985 rst_prev_ts = true; 5986 } 5987 5988 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 5989 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 5990 buffer->pPlatformPrivate)->entryList->entry; 5991 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); 5992 OMX_BUFFERHEADERTYPE *il_buffer; 5993 il_buffer = client_buffers.get_il_buf_hdr(buffer); 5994 if (il_buffer) 5995 m_cb.FillBufferDone (hComp,m_app_data,il_buffer); 5996 else { 5997 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); 5998 return OMX_ErrorBadParameter; 5999 } 6000 DEBUG_PRINT_LOW("After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); 6001 } else { 6002 return OMX_ErrorBadParameter; 6003 } 6004 6005 return OMX_ErrorNone; 6006} 6007 6008OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 6009 OMX_BUFFERHEADERTYPE* buffer) 6010{ 6011 6012 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) { 6013 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer); 6014 return OMX_ErrorBadParameter; 6015 } 6016 6017 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 6018 buffer, buffer->pBuffer); 6019 pending_input_buffers--; 6020 6021 if (arbitrary_bytes) { 6022 if (pdest_frame == NULL && input_flush_progress == false) { 6023 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); 6024 pdest_frame = buffer; 6025 buffer->nFilledLen = 0; 6026 buffer->nTimeStamp = LLONG_MAX; 6027 push_input_buffer (hComp); 6028 } else { 6029 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); 6030 buffer->nFilledLen = 0; 6031 if (!m_input_free_q.insert_entry((unsigned)buffer, 6032 (unsigned)NULL, (unsigned)NULL)) { 6033 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error"); 6034 } 6035 } 6036 } else if (m_cb.EmptyBufferDone) { 6037 buffer->nFilledLen = 0; 6038 if (input_use_buffer == true) { 6039 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; 6040 } 6041 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 6042 } 6043 return OMX_ErrorNone; 6044} 6045 6046int omx_vdec::async_message_process (void *context, void* message) 6047{ 6048 omx_vdec* omx = NULL; 6049 struct vdec_msginfo *vdec_msg = NULL; 6050 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 6051 struct v4l2_buffer *v4l2_buf_ptr = NULL; 6052 struct vdec_output_frameinfo *output_respbuf = NULL; 6053 int rc=1; 6054 if (context == NULL || message == NULL) { 6055 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check"); 6056 return -1; 6057 } 6058 vdec_msg = (struct vdec_msginfo *)message; 6059 6060 omx = reinterpret_cast<omx_vdec*>(context); 6061 6062 switch (vdec_msg->msgcode) { 6063 6064 case VDEC_MSG_EVT_HW_ERROR: 6065 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6066 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 6067 break; 6068 6069 case VDEC_MSG_RESP_START_DONE: 6070 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6071 OMX_COMPONENT_GENERATE_START_DONE); 6072 break; 6073 6074 case VDEC_MSG_RESP_STOP_DONE: 6075 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6076 OMX_COMPONENT_GENERATE_STOP_DONE); 6077 break; 6078 6079 case VDEC_MSG_RESP_RESUME_DONE: 6080 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6081 OMX_COMPONENT_GENERATE_RESUME_DONE); 6082 break; 6083 6084 case VDEC_MSG_RESP_PAUSE_DONE: 6085 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6086 OMX_COMPONENT_GENERATE_PAUSE_DONE); 6087 break; 6088 6089 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 6090 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6091 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 6092 break; 6093 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 6094 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6095 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 6096 break; 6097 case VDEC_MSG_RESP_INPUT_FLUSHED: 6098 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 6099 6100 /* omxhdr = (OMX_BUFFERHEADERTYPE* ) 6101 vdec_msg->msgdata.input_frame_clientdata; */ 6102 6103 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; 6104 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index; 6105 if (omxhdr == NULL || 6106 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) { 6107 omxhdr = NULL; 6108 vdec_msg->status_code = VDEC_S_EFATAL; 6109 } 6110 6111 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, 6112 OMX_COMPONENT_GENERATE_EBD); 6113 break; 6114 case VDEC_MSG_EVT_INFO_FIELD_DROPPED: 6115 int64_t *timestamp; 6116 timestamp = (int64_t *) malloc(sizeof(int64_t)); 6117 if (timestamp) { 6118 *timestamp = vdec_msg->msgdata.output_frame.time_stamp; 6119 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, 6120 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); 6121 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", 6122 vdec_msg->msgdata.output_frame.time_stamp); 6123 } 6124 break; 6125 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 6126 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 6127 6128 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; 6129 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index; 6130 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", 6131 omxhdr, vdec_msg->msgdata.output_frame.time_stamp, 6132 vdec_msg->msgdata.output_frame.pic_type); 6133 6134 if (omxhdr && omxhdr->pOutputPortPrivate && 6135 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && 6136 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 6137 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) { 6138 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) { 6139 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 6140 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 6141 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 6142 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags; 6143 6144 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) { 6145 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; 6146 //rc = -1; 6147 } 6148 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) { 6149 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 6150 } 6151 vdec_msg->msgdata.output_frame.bufferaddr = 6152 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; 6153 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != 6154 vdec_msg->msgdata.output_frame.framesize.left) 6155 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) 6156 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) 6157 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { 6158 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; 6159 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; 6160 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; 6161 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; 6162 DEBUG_PRINT_HIGH("Crop information has changed"); 6163 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, 6164 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 6165 } 6166 output_respbuf = (struct vdec_output_frameinfo *)\ 6167 omxhdr->pOutputPortPrivate; 6168 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 6169 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 6170 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) { 6171 output_respbuf->pic_type = PICTURE_TYPE_I; 6172 } 6173 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) { 6174 output_respbuf->pic_type = PICTURE_TYPE_P; 6175 } 6176 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { 6177 output_respbuf->pic_type = PICTURE_TYPE_B; 6178 } 6179 6180 if (omx->output_use_buffer) 6181 memcpy ( omxhdr->pBuffer, (void *) 6182 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + 6183 (unsigned long)vdec_msg->msgdata.output_frame.offset), 6184 vdec_msg->msgdata.output_frame.len); 6185 } else 6186 omxhdr->nFilledLen = 0; 6187 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, 6188 OMX_COMPONENT_GENERATE_FBD); 6189 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) 6190 omx->post_event ((unsigned int)NULL, vdec_msg->status_code, 6191 OMX_COMPONENT_GENERATE_EOS_DONE); 6192 else 6193 omx->post_event ((unsigned int)NULL, vdec_msg->status_code, 6194 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 6195 break; 6196 case VDEC_MSG_EVT_CONFIG_CHANGED: 6197 DEBUG_PRINT_HIGH("Port settings changed"); 6198 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, 6199 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 6200 break; 6201 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: 6202 { 6203 DEBUG_PRINT_HIGH("Port settings changed info"); 6204 // get_buffer_req and populate port defn structure 6205 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6206 struct v4l2_format fmt; 6207 int ret; 6208 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 6209 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 6210 omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); 6211 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline; 6212 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0]; 6213 omx->m_port_def.nPortIndex = 1; 6214 eRet = omx->update_portdef(&(omx->m_port_def)); 6215 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ 6216 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG); 6217 break; 6218 } 6219 default: 6220 break; 6221 } 6222 return rc; 6223} 6224 6225OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 6226 OMX_HANDLETYPE hComp, 6227 OMX_BUFFERHEADERTYPE *buffer 6228 ) 6229{ 6230 unsigned address,p2,id; 6231 DEBUG_PRINT_LOW("Empty this arbitrary"); 6232 6233 if (buffer == NULL) { 6234 return OMX_ErrorBadParameter; 6235 } 6236 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 6237 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", 6238 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); 6239 6240 /* return zero length and not an EOS buffer */ 6241 /* return buffer if input flush in progress */ 6242 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && 6243 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) { 6244 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); 6245 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 6246 return OMX_ErrorNone; 6247 } 6248 6249 if (psource_frame == NULL) { 6250 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); 6251 psource_frame = buffer; 6252 DEBUG_PRINT_LOW("Try to Push One Input Buffer "); 6253 push_input_buffer (hComp); 6254 } else { 6255 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); 6256 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL, 6257 (unsigned)NULL)) { 6258 return OMX_ErrorBadParameter; 6259 } 6260 } 6261 6262 6263 return OMX_ErrorNone; 6264} 6265 6266OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 6267{ 6268 unsigned address,p2,id; 6269 OMX_ERRORTYPE ret = OMX_ErrorNone; 6270 6271 if (pdest_frame == NULL || psource_frame == NULL) { 6272 /*Check if we have a destination buffer*/ 6273 if (pdest_frame == NULL) { 6274 DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); 6275 if (m_input_free_q.m_size) { 6276 m_input_free_q.pop_entry(&address,&p2,&id); 6277 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 6278 pdest_frame->nFilledLen = 0; 6279 pdest_frame->nTimeStamp = LLONG_MAX; 6280 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); 6281 } 6282 } 6283 6284 /*Check if we have a destination buffer*/ 6285 if (psource_frame == NULL) { 6286 DEBUG_PRINT_LOW("Get a source buffer from the queue"); 6287 if (m_input_pending_q.m_size) { 6288 m_input_pending_q.pop_entry(&address,&p2,&id); 6289 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 6290 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, 6291 psource_frame->nTimeStamp); 6292 DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", 6293 psource_frame->nFlags,psource_frame->nFilledLen); 6294 6295 } 6296 } 6297 6298 } 6299 6300 while ((pdest_frame != NULL) && (psource_frame != NULL)) { 6301 switch (codec_type_parse) { 6302 case CODEC_TYPE_MPEG4: 6303 case CODEC_TYPE_H263: 6304 case CODEC_TYPE_MPEG2: 6305 ret = push_input_sc_codec(hComp); 6306 break; 6307 case CODEC_TYPE_H264: 6308 ret = push_input_h264(hComp); 6309 break; 6310 case CODEC_TYPE_HEVC: 6311 ret = push_input_hevc(hComp); 6312 break; 6313 case CODEC_TYPE_VC1: 6314 ret = push_input_vc1(hComp); 6315 break; 6316 default: 6317 break; 6318 } 6319 if (ret != OMX_ErrorNone) { 6320 DEBUG_PRINT_ERROR("Pushing input Buffer Failed"); 6321 omx_report_error (); 6322 break; 6323 } 6324 } 6325 6326 return ret; 6327} 6328 6329OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 6330{ 6331 OMX_U32 partial_frame = 1; 6332 OMX_BOOL generate_ebd = OMX_TRUE; 6333 unsigned address,p2,id; 6334 6335 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %d", 6336 psource_frame,psource_frame->nTimeStamp); 6337 if (m_frame_parser.parse_sc_frame(psource_frame, 6338 pdest_frame,&partial_frame) == -1) { 6339 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 6340 return OMX_ErrorBadParameter; 6341 } 6342 6343 if (partial_frame == 0) { 6344 DEBUG_PRINT_LOW("Frame size %d source %p frame count %d", 6345 pdest_frame->nFilledLen,psource_frame,frame_count); 6346 6347 6348 DEBUG_PRINT_LOW("TimeStamp updated %d",pdest_frame->nTimeStamp); 6349 /*First Parsed buffer will have only header Hence skip*/ 6350 if (frame_count == 0) { 6351 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); 6352 6353 if (codec_type_parse == CODEC_TYPE_MPEG4 || 6354 codec_type_parse == CODEC_TYPE_DIVX) { 6355 mp4StreamType psBits; 6356 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; 6357 psBits.numBytes = pdest_frame->nFilledLen; 6358 mp4_headerparser.parseHeader(&psBits); 6359 } 6360 6361 frame_count++; 6362 } else { 6363 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 6364 if (pdest_frame->nFilledLen) { 6365 /*Push the frame to the Decoder*/ 6366 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6367 return OMX_ErrorBadParameter; 6368 } 6369 frame_count++; 6370 pdest_frame = NULL; 6371 6372 if (m_input_free_q.m_size) { 6373 m_input_free_q.pop_entry(&address,&p2,&id); 6374 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 6375 pdest_frame->nFilledLen = 0; 6376 } 6377 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) { 6378 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL"); 6379 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL, 6380 (unsigned)NULL); 6381 pdest_frame = NULL; 6382 } 6383 } 6384 } else { 6385 DEBUG_PRINT_LOW("Not a Complete Frame %d",pdest_frame->nFilledLen); 6386 /*Check if Destination Buffer is full*/ 6387 if (pdest_frame->nAllocLen == 6388 pdest_frame->nFilledLen + pdest_frame->nOffset) { 6389 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled"); 6390 return OMX_ErrorStreamCorrupt; 6391 } 6392 } 6393 6394 if (psource_frame->nFilledLen == 0) { 6395 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 6396 if (pdest_frame) { 6397 pdest_frame->nFlags |= psource_frame->nFlags; 6398 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", 6399 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 6400 DEBUG_PRINT_LOW("Found a frame size = %d number = %d", 6401 pdest_frame->nFilledLen,frame_count++); 6402 /*Push the frame to the Decoder*/ 6403 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6404 return OMX_ErrorBadParameter; 6405 } 6406 frame_count++; 6407 pdest_frame = NULL; 6408 } else { 6409 DEBUG_PRINT_LOW("Last frame in else dest addr") ; 6410 generate_ebd = OMX_FALSE; 6411 } 6412 } 6413 if (generate_ebd) { 6414 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); 6415 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 6416 psource_frame = NULL; 6417 6418 if (m_input_pending_q.m_size) { 6419 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 6420 m_input_pending_q.pop_entry(&address,&p2,&id); 6421 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 6422 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, 6423 psource_frame->nTimeStamp); 6424 DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", 6425 psource_frame->nFlags,psource_frame->nFilledLen); 6426 } 6427 } 6428 } 6429 return OMX_ErrorNone; 6430} 6431 6432OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 6433{ 6434 OMX_U32 partial_frame = 1; 6435 unsigned address,p2,id; 6436 OMX_BOOL isNewFrame = OMX_FALSE; 6437 OMX_BOOL generate_ebd = OMX_TRUE; 6438 6439 if (h264_scratch.pBuffer == NULL) { 6440 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated"); 6441 return OMX_ErrorBadParameter; 6442 } 6443 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %d " 6444 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); 6445 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); 6446 if (h264_scratch.nFilledLen && look_ahead_nal) { 6447 look_ahead_nal = false; 6448 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 6449 h264_scratch.nFilledLen) { 6450 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 6451 h264_scratch.pBuffer,h264_scratch.nFilledLen); 6452 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 6453 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); 6454 h264_scratch.nFilledLen = 0; 6455 } else { 6456 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264"); 6457 return OMX_ErrorBadParameter; 6458 } 6459 } 6460 if (nal_length == 0) { 6461 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); 6462 if (m_frame_parser.parse_sc_frame(psource_frame, 6463 &h264_scratch,&partial_frame) == -1) { 6464 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 6465 return OMX_ErrorBadParameter; 6466 } 6467 } else { 6468 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); 6469 if (m_frame_parser.parse_h264_nallength(psource_frame, 6470 &h264_scratch,&partial_frame) == -1) { 6471 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 6472 return OMX_ErrorBadParameter; 6473 } 6474 } 6475 6476 if (partial_frame == 0) { 6477 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 6478 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 6479 nal_count++; 6480 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 6481 h264_scratch.nFlags = psource_frame->nFlags; 6482 } else { 6483 DEBUG_PRINT_LOW("Parsed New NAL Length = %d",h264_scratch.nFilledLen); 6484 if (h264_scratch.nFilledLen) { 6485 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, 6486 NALU_TYPE_SPS); 6487#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 6488 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 6489 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 6490 h264_scratch.nFilledLen, NALU_TYPE_SEI); 6491 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 6492 // If timeinfo is present frame info from SEI is already processed 6493 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 6494 h264_scratch.nFilledLen, NALU_TYPE_SEI); 6495#endif 6496 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 6497 nal_count++; 6498 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { 6499 pdest_frame->nTimeStamp = h264_last_au_ts; 6500 pdest_frame->nFlags = h264_last_au_flags; 6501#ifdef PANSCAN_HDLR 6502 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 6503 h264_parser->update_panscan_data(h264_last_au_ts); 6504#endif 6505 } 6506 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || 6507 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { 6508 h264_last_au_ts = h264_scratch.nTimeStamp; 6509 h264_last_au_flags = h264_scratch.nFlags; 6510#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 6511 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 6512 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); 6513 if (!VALID_TS(h264_last_au_ts)) 6514 h264_last_au_ts = ts_in_sei; 6515 } 6516#endif 6517 } else 6518 h264_last_au_ts = LLONG_MAX; 6519 } 6520 6521 if (!isNewFrame) { 6522 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 6523 h264_scratch.nFilledLen) { 6524 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %d", 6525 h264_scratch.nFilledLen); 6526 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 6527 h264_scratch.pBuffer,h264_scratch.nFilledLen); 6528 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 6529 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) 6530 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 6531 h264_scratch.nFilledLen = 0; 6532 } else { 6533 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264"); 6534 return OMX_ErrorBadParameter; 6535 } 6536 } else { 6537 look_ahead_nal = true; 6538 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", 6539 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 6540 DEBUG_PRINT_LOW("Found a frame size = %d number = %d", 6541 pdest_frame->nFilledLen,frame_count++); 6542 6543 if (pdest_frame->nFilledLen == 0) { 6544 DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); 6545 look_ahead_nal = false; 6546 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 6547 h264_scratch.nFilledLen) { 6548 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 6549 h264_scratch.pBuffer,h264_scratch.nFilledLen); 6550 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 6551 h264_scratch.nFilledLen = 0; 6552 } else { 6553 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264"); 6554 return OMX_ErrorBadParameter; 6555 } 6556 } else { 6557 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 6558 DEBUG_PRINT_LOW("Reset the EOS Flag"); 6559 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 6560 } 6561 /*Push the frame to the Decoder*/ 6562 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6563 return OMX_ErrorBadParameter; 6564 } 6565 //frame_count++; 6566 pdest_frame = NULL; 6567 if (m_input_free_q.m_size) { 6568 m_input_free_q.pop_entry(&address,&p2,&id); 6569 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 6570 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); 6571 pdest_frame->nFilledLen = 0; 6572 pdest_frame->nFlags = 0; 6573 pdest_frame->nTimeStamp = LLONG_MAX; 6574 } 6575 } 6576 } 6577 } 6578 } else { 6579 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); 6580 /*Check if Destination Buffer is full*/ 6581 if (h264_scratch.nAllocLen == 6582 h264_scratch.nFilledLen + h264_scratch.nOffset) { 6583 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 6584 return OMX_ErrorStreamCorrupt; 6585 } 6586 } 6587 6588 if (!psource_frame->nFilledLen) { 6589 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); 6590 6591 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 6592 if (pdest_frame) { 6593 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 6594 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 6595 h264_scratch.nFilledLen) { 6596 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 6597 h264_scratch.pBuffer,h264_scratch.nFilledLen); 6598 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 6599 h264_scratch.nFilledLen = 0; 6600 } else { 6601 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264"); 6602 return OMX_ErrorBadParameter; 6603 } 6604 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 6605 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 6606 6607 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%d TimeStamp = %x", 6608 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 6609 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); 6610#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 6611 if (client_extradata & OMX_TIMEINFO_EXTRADATA) { 6612 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); 6613 if (!VALID_TS(pdest_frame->nTimeStamp)) 6614 pdest_frame->nTimeStamp = ts_in_sei; 6615 } 6616#endif 6617 /*Push the frame to the Decoder*/ 6618 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6619 return OMX_ErrorBadParameter; 6620 } 6621 frame_count++; 6622 pdest_frame = NULL; 6623 } else { 6624 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %d", 6625 pdest_frame,h264_scratch.nFilledLen); 6626 generate_ebd = OMX_FALSE; 6627 } 6628 } 6629 } 6630 if (generate_ebd && !psource_frame->nFilledLen) { 6631 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 6632 psource_frame = NULL; 6633 if (m_input_pending_q.m_size) { 6634 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); 6635 m_input_pending_q.pop_entry(&address,&p2,&id); 6636 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 6637 DEBUG_PRINT_LOW("Next source Buffer flag %d src length %d", 6638 psource_frame->nFlags,psource_frame->nFilledLen); 6639 } 6640 } 6641 return OMX_ErrorNone; 6642} 6643 6644OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) 6645{ 6646 OMX_ERRORTYPE rc = OMX_ErrorNone; 6647 if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) { 6648 memcpy ((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); 6649 if (pDst->nTimeStamp == LLONG_MAX) { 6650 pDst->nTimeStamp = pSrc->nTimeStamp; 6651 DEBUG_PRINT_LOW("Assign Dst nTimeStamp=%lld", pDst->nTimeStamp); 6652 } 6653 pDst->nFilledLen += pSrc->nFilledLen; 6654 pSrc->nFilledLen = 0; 6655 } else { 6656 DEBUG_PRINT_ERROR("Error: Destination buffer overflow"); 6657 rc = OMX_ErrorBadParameter; 6658 } 6659 return rc; 6660} 6661 6662OMX_ERRORTYPE omx_vdec::push_input_hevc (OMX_HANDLETYPE hComp) 6663{ 6664 OMX_U32 partial_frame = 1; 6665 unsigned address,p2,id; 6666 OMX_BOOL isNewFrame = OMX_FALSE; 6667 OMX_BOOL generate_ebd = OMX_TRUE; 6668 OMX_ERRORTYPE rc = OMX_ErrorNone; 6669 6670 if (h264_scratch.pBuffer == NULL) { 6671 DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated"); 6672 return OMX_ErrorBadParameter; 6673 } 6674 6675 6676 DEBUG_PRINT_LOW("h264_scratch.nFilledLen %d has look_ahead_nal %d pdest_frame nFilledLen %d nTimeStamp %lld", 6677 h264_scratch.nFilledLen, look_ahead_nal, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 6678 6679 if (h264_scratch.nFilledLen && look_ahead_nal) { 6680 look_ahead_nal = false; 6681 6682 // copy the lookahead buffer in the scratch 6683 rc = copy_buffer(pdest_frame, &h264_scratch); 6684 if (rc != OMX_ErrorNone) { 6685 return rc; 6686 } 6687 } 6688 if (nal_length == 0) { 6689 if (m_frame_parser.parse_sc_frame(psource_frame, 6690 &h264_scratch,&partial_frame) == -1) { 6691 DEBUG_PRINT_ERROR("Error In Parsing Return Error"); 6692 return OMX_ErrorBadParameter; 6693 } 6694 } else { 6695 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length); 6696 if (m_frame_parser.parse_h264_nallength(psource_frame, 6697 &h264_scratch,&partial_frame) == -1) { 6698 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error"); 6699 return OMX_ErrorBadParameter; 6700 } 6701 } 6702 6703 if (partial_frame == 0) { 6704 if (nal_count == 0 && h264_scratch.nFilledLen == 0) { 6705 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); 6706 nal_count++; 6707 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 6708 h264_scratch.nFlags = psource_frame->nFlags; 6709 } else { 6710 DEBUG_PRINT_LOW("Parsed New NAL Length = %d",h264_scratch.nFilledLen); 6711 if (h264_scratch.nFilledLen) { 6712 mHEVCutils.isNewFrame(&h264_scratch, 0, isNewFrame); 6713 nal_count++; 6714 } 6715 6716 if (!isNewFrame) { 6717 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %d nTimestamp %lld, pdest_frame nFilledLen %d nTimestamp %lld", 6718 h264_scratch.nFilledLen, h264_scratch.nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); 6719 rc = copy_buffer(pdest_frame, &h264_scratch); 6720 if ( rc != OMX_ErrorNone) { 6721 return rc; 6722 } 6723 } else { 6724 look_ahead_nal = true; 6725 if (pdest_frame->nFilledLen == 0) { 6726 look_ahead_nal = false; 6727 DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer"); 6728 rc = copy_buffer(pdest_frame, &h264_scratch); 6729 if ( rc != OMX_ErrorNone ) { 6730 return OMX_ErrorBadParameter; 6731 } 6732 } else { 6733 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) { 6734 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 6735 } 6736 6737 DEBUG_PRINT_LOW("FrameDetecetd # %d pdest_frame nFilledLen %d nTimeStamp %lld, look_ahead_nal in h264_scratch nFilledLen %d nTimeStamp %lld", 6738 frame_count++, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); 6739 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6740 return OMX_ErrorBadParameter; 6741 } 6742 pdest_frame = NULL; 6743 if (m_input_free_q.m_size) { 6744 m_input_free_q.pop_entry(&address,&p2,&id); 6745 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 6746 DEBUG_PRINT_LOW("pop the next pdest_buffer %p",pdest_frame); 6747 pdest_frame->nFilledLen = 0; 6748 pdest_frame->nFlags = 0; 6749 pdest_frame->nTimeStamp = LLONG_MAX; 6750 } 6751 } 6752 } 6753 } 6754 } else { 6755 DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %d nTimeStamp %lld, pdest_frame nFilledLen %d nTimeStamp %lld, h264_scratch nFilledLen %d nTimeStamp %lld", 6756 psource_frame->nFilledLen, psource_frame->nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); 6757 6758 /*Check if Destination Buffer is full*/ 6759 if (h264_scratch.nAllocLen == 6760 h264_scratch.nFilledLen + h264_scratch.nOffset) { 6761 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled"); 6762 return OMX_ErrorStreamCorrupt; 6763 } 6764 } 6765 6766 if (!psource_frame->nFilledLen) { 6767 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); 6768 6769 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 6770 if (pdest_frame) { 6771 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); 6772 rc = copy_buffer(pdest_frame, &h264_scratch); 6773 if ( rc != OMX_ErrorNone ) { 6774 return rc; 6775 } 6776 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 6777 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 6778 6779 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%d TimeStamp = %lld", 6780 frame_count, pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 6781 6782 /*Push the frame to the Decoder*/ 6783 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) { 6784 return OMX_ErrorBadParameter; 6785 } 6786 frame_count++; 6787 pdest_frame = NULL; 6788 } else { 6789 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %d", 6790 pdest_frame,h264_scratch.nFilledLen); 6791 generate_ebd = OMX_FALSE; 6792 } 6793 } 6794 } 6795 if (generate_ebd && !psource_frame->nFilledLen) { 6796 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 6797 psource_frame = NULL; 6798 if (m_input_pending_q.m_size) { 6799 m_input_pending_q.pop_entry(&address,&p2,&id); 6800 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 6801 DEBUG_PRINT_LOW("Next source Buffer flag %d nFilledLen %d, nTimeStamp %lld", 6802 psource_frame->nFlags,psource_frame->nFilledLen, psource_frame->nTimeStamp); 6803 } 6804 } 6805 return OMX_ErrorNone; 6806} 6807 6808OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) 6809{ 6810 OMX_U8 *buf, *pdest; 6811 OMX_U32 partial_frame = 1; 6812 OMX_U32 buf_len, dest_len; 6813 6814 if (first_frame == 0) { 6815 first_frame = 1; 6816 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); 6817 if (!m_vendor_config.pData) { 6818 DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); 6819 buf = psource_frame->pBuffer; 6820 buf_len = psource_frame->nFilledLen; 6821 6822 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 6823 VC1_SP_MP_START_CODE) { 6824 m_vc1_profile = VC1_SP_MP_RCV; 6825 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) { 6826 m_vc1_profile = VC1_AP; 6827 } else { 6828 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer"); 6829 return OMX_ErrorStreamCorrupt; 6830 } 6831 } else { 6832 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 6833 pdest_frame->nOffset; 6834 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 6835 pdest_frame->nOffset); 6836 6837 if (dest_len < m_vendor_config.nDataSize) { 6838 DEBUG_PRINT_ERROR("Destination buffer full"); 6839 return OMX_ErrorBadParameter; 6840 } else { 6841 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 6842 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 6843 } 6844 } 6845 } 6846 6847 switch (m_vc1_profile) { 6848 case VC1_AP: 6849 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); 6850 if (push_input_sc_codec(hComp) != OMX_ErrorNone) { 6851 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code"); 6852 return OMX_ErrorBadParameter; 6853 } 6854 break; 6855 6856 case VC1_SP_MP_RCV: 6857 default: 6858 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode"); 6859 return OMX_ErrorBadParameter; 6860 } 6861 return OMX_ErrorNone; 6862} 6863 6864bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 6865 OMX_U32 alignment) 6866{ 6867 struct pmem_allocation allocation; 6868 allocation.size = buffer_size; 6869 allocation.align = clip2(alignment); 6870 if (allocation.align < 4096) { 6871 allocation.align = 4096; 6872 } 6873 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) { 6874 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)", 6875 allocation.align, allocation.size); 6876 return false; 6877 } 6878 return true; 6879} 6880#ifdef USE_ION 6881int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, 6882 OMX_U32 alignment, struct ion_allocation_data *alloc_data, 6883 struct ion_fd_data *fd_data, int flag) 6884{ 6885 int fd = -EINVAL; 6886 int rc = -EINVAL; 6887 int ion_dev_flag; 6888 struct vdec_ion ion_buf_info; 6889 if (!alloc_data || buffer_size <= 0 || !fd_data) { 6890 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory"); 6891 return -EINVAL; 6892 } 6893 ion_dev_flag = O_RDONLY; 6894 fd = open (MEM_DEVICE, ion_dev_flag); 6895 if (fd < 0) { 6896 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd); 6897 return fd; 6898 } 6899 alloc_data->flags = 0; 6900 if (!secure_mode && (flag & ION_FLAG_CACHED)) { 6901 alloc_data->flags |= ION_FLAG_CACHED; 6902 } 6903 alloc_data->len = buffer_size; 6904 alloc_data->align = clip2(alignment); 6905 if (alloc_data->align < 4096) { 6906 alloc_data->align = 4096; 6907 } 6908 if ((secure_mode) && (flag & ION_SECURE)) 6909 alloc_data->flags |= ION_SECURE; 6910 6911#ifdef _HEVC_USE_ADSP_HEAP_ 6912 alloc_data->heap_id_mask = ION_HEAP(ION_ADSP_HEAP_ID); 6913#else 6914 alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID); 6915#endif 6916 if (secure_mode) { 6917 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 6918 } 6919 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); 6920 if (rc || !alloc_data->handle) { 6921 DEBUG_PRINT_ERROR("ION ALLOC memory failed "); 6922 alloc_data->handle = NULL; 6923 close(fd); 6924 fd = -ENOMEM; 6925 return fd; 6926 } 6927 fd_data->handle = alloc_data->handle; 6928 rc = ioctl(fd,ION_IOC_MAP,fd_data); 6929 if (rc) { 6930 DEBUG_PRINT_ERROR("ION MAP failed "); 6931 ion_buf_info.ion_alloc_data = *alloc_data; 6932 ion_buf_info.ion_device_fd = fd; 6933 ion_buf_info.fd_ion_data = *fd_data; 6934 free_ion_memory(&ion_buf_info); 6935 fd_data->fd =-1; 6936 fd = -ENOMEM; 6937 } 6938 6939 return fd; 6940} 6941 6942void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) 6943{ 6944 6945 if (!buf_ion_info) { 6946 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata"); 6947 return; 6948 } 6949 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 6950 &buf_ion_info->ion_alloc_data.handle)) { 6951 DEBUG_PRINT_ERROR("ION: free failed" ); 6952 } 6953 close(buf_ion_info->ion_device_fd); 6954 buf_ion_info->ion_device_fd = -1; 6955 buf_ion_info->ion_alloc_data.handle = NULL; 6956 buf_ion_info->fd_ion_data.fd = -1; 6957} 6958#endif 6959void omx_vdec::free_output_buffer_header() 6960{ 6961 DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); 6962 output_use_buffer = false; 6963 ouput_egl_buffers = false; 6964 6965 if (m_out_mem_ptr) { 6966 free (m_out_mem_ptr); 6967 m_out_mem_ptr = NULL; 6968 } 6969 6970 if (m_platform_list) { 6971 free(m_platform_list); 6972 m_platform_list = NULL; 6973 } 6974 6975 if (drv_ctx.ptr_respbuffer) { 6976 free (drv_ctx.ptr_respbuffer); 6977 drv_ctx.ptr_respbuffer = NULL; 6978 } 6979 if (drv_ctx.ptr_outputbuffer) { 6980 free (drv_ctx.ptr_outputbuffer); 6981 drv_ctx.ptr_outputbuffer = NULL; 6982 } 6983#ifdef USE_ION 6984 if (drv_ctx.op_buf_ion_info) { 6985 DEBUG_PRINT_LOW("Free o/p ion context"); 6986 free(drv_ctx.op_buf_ion_info); 6987 drv_ctx.op_buf_ion_info = NULL; 6988 } 6989#endif 6990} 6991 6992void omx_vdec::free_input_buffer_header() 6993{ 6994 input_use_buffer = false; 6995 if (arbitrary_bytes) { 6996 if (m_frame_parser.mutils) { 6997 DEBUG_PRINT_LOW("Free utils parser"); 6998 delete (m_frame_parser.mutils); 6999 m_frame_parser.mutils = NULL; 7000 } 7001 7002 if (m_inp_heap_ptr) { 7003 DEBUG_PRINT_LOW("Free input Heap Pointer"); 7004 free (m_inp_heap_ptr); 7005 m_inp_heap_ptr = NULL; 7006 } 7007 7008 if (m_phdr_pmem_ptr) { 7009 DEBUG_PRINT_LOW("Free input pmem header Pointer"); 7010 free (m_phdr_pmem_ptr); 7011 m_phdr_pmem_ptr = NULL; 7012 } 7013 } 7014 if (m_inp_mem_ptr) { 7015 DEBUG_PRINT_LOW("Free input pmem Pointer area"); 7016 free (m_inp_mem_ptr); 7017 m_inp_mem_ptr = NULL; 7018 } 7019 if (drv_ctx.ptr_inputbuffer) { 7020 DEBUG_PRINT_LOW("Free Driver Context pointer"); 7021 free (drv_ctx.ptr_inputbuffer); 7022 drv_ctx.ptr_inputbuffer = NULL; 7023 } 7024#ifdef USE_ION 7025 if (drv_ctx.ip_buf_ion_info) { 7026 DEBUG_PRINT_LOW("Free ion context"); 7027 free(drv_ctx.ip_buf_ion_info); 7028 drv_ctx.ip_buf_ion_info = NULL; 7029 } 7030#endif 7031} 7032 7033int omx_vdec::stream_off(OMX_U32 port) 7034{ 7035 enum v4l2_buf_type btype; 7036 int rc = 0; 7037 enum v4l2_ports v4l2_port = OUTPUT_PORT; 7038 7039 if (port == OMX_CORE_INPUT_PORT_INDEX) { 7040 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7041 v4l2_port = OUTPUT_PORT; 7042 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { 7043 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7044 v4l2_port = CAPTURE_PORT; 7045 } else if (port == OMX_ALL) { 7046 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); 7047 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); 7048 7049 if (!rc_input) 7050 return rc_input; 7051 else 7052 return rc_output; 7053 } 7054 7055 if (!streaming[v4l2_port]) { 7056 // already streamed off, warn and move on 7057 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," 7058 " which is already streamed off", v4l2_port); 7059 return 0; 7060 } 7061 7062 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); 7063 7064 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); 7065 if (rc) { 7066 /*TODO: How to handle this case */ 7067 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port); 7068 } else { 7069 streaming[v4l2_port] = false; 7070 } 7071 7072 return rc; 7073} 7074 7075OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) 7076{ 7077 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7078 struct v4l2_requestbuffers bufreq; 7079 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; 7080 struct v4l2_format fmt; 7081 int ret = 0; 7082 7083 bufreq.memory = V4L2_MEMORY_USERPTR; 7084 bufreq.count = 1; 7085 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 7086 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7087 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7088 fmt.fmt.pix_mp.pixelformat = output_capability; 7089 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 7090 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7091 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7092 fmt.fmt.pix_mp.pixelformat = capture_capability; 7093 } else { 7094 eRet = OMX_ErrorBadParameter; 7095 } 7096 if (eRet==OMX_ErrorNone) { 7097 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 7098 } 7099 if (ret) { 7100 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 7101 /*TODO: How to handle this case */ 7102 eRet = OMX_ErrorInsufficientResources; 7103 return eRet; 7104 } else { 7105 buffer_prop->actualcount = bufreq.count; 7106 buffer_prop->mincount = bufreq.count; 7107 DEBUG_PRINT_HIGH("Count = %d",bufreq.count); 7108 } 7109 DEBUG_PRINT_HIGH("GetBufReq: ActCnt(%d) Size(%d), BufType(%d)", 7110 buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); 7111 7112 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 7113 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 7114 7115 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); 7116 7117 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); 7118 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 7119 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; 7120 DEBUG_PRINT_HIGH("Buffer Size (plane[0].sizeimage) = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); 7121 7122 if (ret) { 7123 /*TODO: How to handle this case */ 7124 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 7125 eRet = OMX_ErrorInsufficientResources; 7126 } else { 7127 int extra_idx = 0; 7128 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 7129 buf_size = buffer_prop->buffer_size; 7130 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); 7131 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 7132 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 7133 } else if (extra_idx >= VIDEO_MAX_PLANES) { 7134 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 7135 return OMX_ErrorBadParameter; 7136 } 7137 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) { 7138 DEBUG_PRINT_HIGH("Frame info extra data enabled!"); 7139 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; 7140 } 7141 if (client_extradata & OMX_INTERLACE_EXTRADATA) { 7142 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; 7143 } 7144 if (client_extradata & OMX_PORTDEF_EXTRADATA) { 7145 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; 7146 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d", 7147 client_extra_data_size); 7148 } 7149 if (client_extra_data_size) { 7150 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator 7151 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit 7152 } 7153 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size; 7154 drv_ctx.extradata_info.count = buffer_prop->actualcount; 7155 drv_ctx.extradata_info.buffer_size = extra_data_size; 7156 buf_size += client_extra_data_size; 7157 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 7158 DEBUG_PRINT_HIGH("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d) BufType(%d)", 7159 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type); 7160 if (in_reconfig) // BufReq will be set to driver when port is disabled 7161 buffer_prop->buffer_size = buf_size; 7162 else if (buf_size != buffer_prop->buffer_size) { 7163 buffer_prop->buffer_size = buf_size; 7164 eRet = set_buffer_req(buffer_prop); 7165 } 7166 } 7167 DEBUG_PRINT_HIGH("GetBufReq OUT: ActCnt(%d) Size(%d), BufType(%d)", 7168 buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); 7169 return eRet; 7170} 7171 7172OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) 7173{ 7174 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7175 unsigned buf_size = 0; 7176 struct v4l2_format fmt; 7177 struct v4l2_requestbuffers bufreq; 7178 int ret; 7179 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", 7180 buffer_prop->actualcount, buffer_prop->buffer_size); 7181 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 7182 if (buf_size != buffer_prop->buffer_size) { 7183 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", 7184 buffer_prop->buffer_size, buf_size); 7185 eRet = OMX_ErrorBadParameter; 7186 } else { 7187 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; 7188 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; 7189 7190 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 7191 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7192 fmt.fmt.pix_mp.pixelformat = output_capability; 7193 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 7194 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7195 fmt.fmt.pix_mp.pixelformat = capture_capability; 7196 } else { 7197 eRet = OMX_ErrorBadParameter; 7198 } 7199 7200 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); 7201 if (ret) { 7202 /*TODO: How to handle this case */ 7203 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); 7204 eRet = OMX_ErrorInsufficientResources; 7205 } 7206 7207 bufreq.memory = V4L2_MEMORY_USERPTR; 7208 bufreq.count = buffer_prop->actualcount; 7209 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { 7210 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 7211 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 7212 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 7213 } else { 7214 eRet = OMX_ErrorBadParameter; 7215 } 7216 7217 if (eRet==OMX_ErrorNone) { 7218 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); 7219 } 7220 7221 if (ret) { 7222 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); 7223 /*TODO: How to handle this case */ 7224 eRet = OMX_ErrorInsufficientResources; 7225 } else if (bufreq.count < buffer_prop->actualcount) { 7226 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" 7227 " on v4l2 port %d to %d (prefers %d)", bufreq.type, 7228 buffer_prop->actualcount, bufreq.count); 7229 eRet = OMX_ErrorInsufficientResources; 7230 } else { 7231 if (!client_buffers.update_buffer_req()) { 7232 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); 7233 eRet = OMX_ErrorInsufficientResources; 7234 } 7235 } 7236 } 7237 if (!eRet && buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { 7238 // need to update extradata buffers also 7239 drv_ctx.extradata_info.size = buffer_prop->actualcount * drv_ctx.extradata_info.buffer_size; 7240 drv_ctx.extradata_info.count = buffer_prop->actualcount; 7241 } 7242 return eRet; 7243} 7244 7245OMX_ERRORTYPE omx_vdec::update_picture_resolution() 7246{ 7247 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7248 return eRet; 7249} 7250 7251OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 7252{ 7253 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7254 if (!portDefn) { 7255 return OMX_ErrorBadParameter; 7256 } 7257 DEBUG_PRINT_LOW("omx_vdec::update_portdef"); 7258 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 7259 portDefn->nSize = sizeof(portDefn); 7260 portDefn->eDomain = OMX_PortDomainVideo; 7261 if (drv_ctx.frame_rate.fps_denominator > 0) 7262 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / 7263 drv_ctx.frame_rate.fps_denominator; 7264 else { 7265 DEBUG_PRINT_ERROR("Error: Divide by zero"); 7266 return OMX_ErrorBadParameter; 7267 } 7268 if (0 == portDefn->nPortIndex) { 7269 portDefn->eDir = OMX_DirInput; 7270 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; 7271 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; 7272 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; 7273 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 7274 portDefn->format.video.eCompressionFormat = eCompressionFormat; 7275 portDefn->bEnabled = m_inp_bEnabled; 7276 portDefn->bPopulated = m_inp_bPopulated; 7277 } else if (1 == portDefn->nPortIndex) { 7278 unsigned int buf_size = 0; 7279 if (!client_buffers.update_buffer_req()) { 7280 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed"); 7281 return OMX_ErrorHardware; 7282 } 7283 if (!client_buffers.get_buffer_req(buf_size)) { 7284 DEBUG_PRINT_ERROR("update buffer requirements"); 7285 return OMX_ErrorHardware; 7286 } 7287 portDefn->nBufferSize = buf_size; 7288 portDefn->eDir = OMX_DirOutput; 7289 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; 7290 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; 7291 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 7292 portDefn->bEnabled = m_out_bEnabled; 7293 portDefn->bPopulated = m_out_bPopulated; 7294 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { 7295 DEBUG_PRINT_ERROR("Error in getting color format"); 7296 return OMX_ErrorHardware; 7297 } 7298 } else { 7299 portDefn->eDir = OMX_DirMax; 7300 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 7301 (int)portDefn->nPortIndex); 7302 eRet = OMX_ErrorBadPortIndex; 7303 } 7304 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; 7305 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; 7306 portDefn->format.video.nStride = drv_ctx.video_resolution.stride; 7307 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; 7308 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld" 7309 " SliceHeight = %lu", portDefn->format.video.nFrameWidth, 7310 portDefn->format.video.nFrameHeight, 7311 portDefn->format.video.nStride, 7312 portDefn->format.video.nSliceHeight); 7313 return eRet; 7314 7315} 7316 7317OMX_ERRORTYPE omx_vdec::allocate_output_headers() 7318{ 7319 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7320 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 7321 unsigned i= 0; 7322 7323 if (!m_out_mem_ptr) { 7324 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); 7325 int nBufHdrSize = 0; 7326 int nPlatformEntrySize = 0; 7327 int nPlatformListSize = 0; 7328 int nPMEMInfoSize = 0; 7329 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 7330 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 7331 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 7332 7333 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", 7334 drv_ctx.op_buf.actualcount); 7335 nBufHdrSize = drv_ctx.op_buf.actualcount * 7336 sizeof(OMX_BUFFERHEADERTYPE); 7337 7338 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 7339 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 7340 nPlatformListSize = drv_ctx.op_buf.actualcount * 7341 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 7342 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 7343 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 7344 7345 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, 7346 sizeof(OMX_BUFFERHEADERTYPE), 7347 nPMEMInfoSize, 7348 nPlatformListSize); 7349 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize, 7350 m_out_bm_count); 7351 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 7352 // Alloc mem for platform specific info 7353 char *pPtr=NULL; 7354 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 7355 nPMEMInfoSize,1); 7356 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 7357 calloc (sizeof(struct vdec_bufferpayload), 7358 drv_ctx.op_buf.actualcount); 7359 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 7360 calloc (sizeof (struct vdec_output_frameinfo), 7361 drv_ctx.op_buf.actualcount); 7362#ifdef USE_ION 7363 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ 7364 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); 7365#endif 7366 7367 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 7368 && drv_ctx.ptr_respbuffer) { 7369 bufHdr = m_out_mem_ptr; 7370 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 7371 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 7372 (((char *) m_platform_list) + nPlatformListSize); 7373 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 7374 (((char *) m_platform_entry) + nPlatformEntrySize); 7375 pPlatformList = m_platform_list; 7376 pPlatformEntry = m_platform_entry; 7377 pPMEMInfo = m_pmem_info; 7378 7379 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 7380 7381 // Settting the entire storage nicely 7382 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, 7383 m_out_mem_ptr,pPlatformEntry); 7384 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo); 7385 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) { 7386 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 7387 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 7388 // Set the values when we determine the right HxW param 7389 bufHdr->nAllocLen = 0; 7390 bufHdr->nFilledLen = 0; 7391 bufHdr->pAppPrivate = NULL; 7392 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7393 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 7394 pPlatformEntry->entry = pPMEMInfo; 7395 // Initialize the Platform List 7396 pPlatformList->nEntries = 1; 7397 pPlatformList->entryList = pPlatformEntry; 7398 // Keep pBuffer NULL till vdec is opened 7399 bufHdr->pBuffer = NULL; 7400 pPMEMInfo->offset = 0; 7401 pPMEMInfo->pmem_fd = 0; 7402 bufHdr->pPlatformPrivate = pPlatformList; 7403 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 7404#ifdef USE_ION 7405 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 7406#endif 7407 /*Create a mapping between buffers*/ 7408 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 7409 drv_ctx.ptr_respbuffer[i].client_data = (void *) \ 7410 &drv_ctx.ptr_outputbuffer[i]; 7411 // Move the buffer and buffer header pointers 7412 bufHdr++; 7413 pPMEMInfo++; 7414 pPlatformEntry++; 7415 pPlatformList++; 7416 } 7417 } else { 7418 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\ 7419 m_out_mem_ptr, pPtr); 7420 if (m_out_mem_ptr) { 7421 free(m_out_mem_ptr); 7422 m_out_mem_ptr = NULL; 7423 } 7424 if (pPtr) { 7425 free(pPtr); 7426 pPtr = NULL; 7427 } 7428 if (drv_ctx.ptr_outputbuffer) { 7429 free(drv_ctx.ptr_outputbuffer); 7430 drv_ctx.ptr_outputbuffer = NULL; 7431 } 7432 if (drv_ctx.ptr_respbuffer) { 7433 free(drv_ctx.ptr_respbuffer); 7434 drv_ctx.ptr_respbuffer = NULL; 7435 } 7436#ifdef USE_ION 7437 if (drv_ctx.op_buf_ion_info) { 7438 DEBUG_PRINT_LOW("Free o/p ion context"); 7439 free(drv_ctx.op_buf_ion_info); 7440 drv_ctx.op_buf_ion_info = NULL; 7441 } 7442#endif 7443 eRet = OMX_ErrorInsufficientResources; 7444 } 7445 } else { 7446 eRet = OMX_ErrorInsufficientResources; 7447 } 7448 return eRet; 7449} 7450 7451void omx_vdec::complete_pending_buffer_done_cbs() 7452{ 7453 unsigned p1; 7454 unsigned p2; 7455 unsigned ident; 7456 omx_cmd_queue tmp_q, pending_bd_q; 7457 pthread_mutex_lock(&m_lock); 7458 // pop all pending GENERATE FDB from ftb queue 7459 while (m_ftb_q.m_size) { 7460 m_ftb_q.pop_entry(&p1,&p2,&ident); 7461 if (ident == OMX_COMPONENT_GENERATE_FBD) { 7462 pending_bd_q.insert_entry(p1,p2,ident); 7463 } else { 7464 tmp_q.insert_entry(p1,p2,ident); 7465 } 7466 } 7467 //return all non GENERATE FDB to ftb queue 7468 while (tmp_q.m_size) { 7469 tmp_q.pop_entry(&p1,&p2,&ident); 7470 m_ftb_q.insert_entry(p1,p2,ident); 7471 } 7472 // pop all pending GENERATE EDB from etb queue 7473 while (m_etb_q.m_size) { 7474 m_etb_q.pop_entry(&p1,&p2,&ident); 7475 if (ident == OMX_COMPONENT_GENERATE_EBD) { 7476 pending_bd_q.insert_entry(p1,p2,ident); 7477 } else { 7478 tmp_q.insert_entry(p1,p2,ident); 7479 } 7480 } 7481 //return all non GENERATE FDB to etb queue 7482 while (tmp_q.m_size) { 7483 tmp_q.pop_entry(&p1,&p2,&ident); 7484 m_etb_q.insert_entry(p1,p2,ident); 7485 } 7486 pthread_mutex_unlock(&m_lock); 7487 // process all pending buffer dones 7488 while (pending_bd_q.m_size) { 7489 pending_bd_q.pop_entry(&p1,&p2,&ident); 7490 switch (ident) { 7491 case OMX_COMPONENT_GENERATE_EBD: 7492 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 7493 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); 7494 omx_report_error (); 7495 } 7496 break; 7497 7498 case OMX_COMPONENT_GENERATE_FBD: 7499 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 7500 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); 7501 omx_report_error (); 7502 } 7503 break; 7504 } 7505 } 7506} 7507 7508void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) 7509{ 7510 OMX_U32 new_frame_interval = 0; 7511 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts 7512 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) { 7513 new_frame_interval = (act_timestamp > prev_ts)? 7514 act_timestamp - prev_ts : 7515 prev_ts - act_timestamp; 7516 if (new_frame_interval < frm_int || frm_int == 0) { 7517 frm_int = new_frame_interval; 7518 if (frm_int) { 7519 drv_ctx.frame_rate.fps_numerator = 1e6; 7520 drv_ctx.frame_rate.fps_denominator = frm_int; 7521 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", 7522 frm_int, drv_ctx.frame_rate.fps_numerator / 7523 (float)drv_ctx.frame_rate.fps_denominator); 7524 } 7525 } 7526 } 7527 prev_ts = act_timestamp; 7528} 7529 7530void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) 7531{ 7532 if (rst_prev_ts && VALID_TS(act_timestamp)) { 7533 prev_ts = act_timestamp; 7534 rst_prev_ts = false; 7535 } else if (VALID_TS(prev_ts)) { 7536 bool codec_cond = (drv_ctx.timestamp_adjust)? 7537 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? 7538 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): 7539 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); 7540 if (frm_int > 0 && codec_cond) { 7541 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); 7542 act_timestamp = prev_ts + frm_int; 7543 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); 7544 prev_ts = act_timestamp; 7545 } else 7546 set_frame_rate(act_timestamp); 7547 } else if (frm_int > 0) // In this case the frame rate was set along 7548 { // with the port definition, start ts with 0 7549 act_timestamp = prev_ts = 0; // and correct if a valid ts is received. 7550 rst_prev_ts = true; 7551 } 7552} 7553 7554void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) 7555{ 7556 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; 7557 OMX_U32 num_conceal_MB = 0; 7558 OMX_U32 frame_rate = 0; 7559 int consumed_len = 0; 7560 OMX_U32 num_MB_in_frame; 7561 OMX_U32 recovery_sei_flags = 1; 7562 int buf_index = p_buf_hdr - m_out_mem_ptr; 7563 struct msm_vidc_panscan_window_payload *panscan_payload = NULL; 7564 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + 7565 p_buf_hdr->nOffset; 7566 if (!drv_ctx.extradata_info.uaddr) { 7567 return; 7568 } 7569 p_extra = (OMX_OTHER_EXTRADATATYPE *) 7570 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); 7571 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; 7572 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) 7573 p_extra = NULL; 7574 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; 7575 if (data) { 7576 while ((consumed_len < drv_ctx.extradata_info.buffer_size) 7577 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) { 7578 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) { 7579 DEBUG_PRINT_LOW("Invalid extra data size"); 7580 break; 7581 } 7582 switch ((unsigned long)data->eType) { 7583 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO: 7584 struct msm_vidc_interlace_payload *payload; 7585 payload = (struct msm_vidc_interlace_payload *)data->data; 7586 if (payload->format != MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) { 7587 int enable = 1; 7588 OMX_U32 mbaff = 0; 7589 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; 7590 if ((payload->format == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !mbaff) 7591 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 7592 else 7593 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 7594 if (m_enable_android_native_buffers) 7595 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, 7596 PP_PARAM_INTERLACED, (void*)&enable); 7597 } 7598 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { 7599 append_interlace_extradata(p_extra, payload->format); 7600 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 7601 } 7602 break; 7603 case MSM_VIDC_EXTRADATA_FRAME_RATE: 7604 struct msm_vidc_framerate_payload *frame_rate_payload; 7605 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data; 7606 frame_rate = frame_rate_payload->frame_rate; 7607 break; 7608 case MSM_VIDC_EXTRADATA_TIMESTAMP: 7609 struct msm_vidc_ts_payload *time_stamp_payload; 7610 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data; 7611 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo; 7612 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); 7613 break; 7614 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB: 7615 struct msm_vidc_concealmb_payload *conceal_mb_payload; 7616 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data; 7617 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 7618 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 7619 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); 7620 break; 7621 case MSM_VIDC_EXTRADATA_ASPECT_RATIO: 7622 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; 7623 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data; 7624 ((struct vdec_output_frameinfo *) 7625 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; 7626 ((struct vdec_output_frameinfo *) 7627 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; 7628 break; 7629 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI: 7630 struct msm_vidc_recoverysei_payload *recovery_sei_payload; 7631 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data; 7632 recovery_sei_flags = recovery_sei_payload->flags; 7633 if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) { 7634 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; 7635 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received"); 7636 } 7637 break; 7638 case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW: 7639 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data; 7640 break; 7641 default: 7642 goto unrecognized_extradata; 7643 } 7644 consumed_len += data->nSize; 7645 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 7646 } 7647 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { 7648 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 7649 append_frame_info_extradata(p_extra, 7650 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, 7651 panscan_payload,&((struct vdec_output_frameinfo *) 7652 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 7653 } 7654 } 7655unrecognized_extradata: 7656 if (!secure_mode && client_extradata) 7657 append_terminator_extradata(p_extra); 7658 return; 7659} 7660 7661OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, 7662 bool is_internal, bool enable) 7663{ 7664 OMX_ERRORTYPE ret = OMX_ErrorNone; 7665 struct v4l2_control control; 7666 if (m_state != OMX_StateLoaded) { 7667 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); 7668 return OMX_ErrorIncorrectStateOperation; 7669 } 7670 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d", 7671 client_extradata, requested_extradata, enable, is_internal); 7672 7673 if (!is_internal) { 7674 if (enable) 7675 client_extradata |= requested_extradata; 7676 else 7677 client_extradata = client_extradata & ~requested_extradata; 7678 } 7679 7680 if (enable) { 7681 if (requested_extradata & OMX_INTERLACE_EXTRADATA) { 7682 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7683 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; 7684 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7685 DEBUG_PRINT_HIGH("Failed to set interlaced extradata." 7686 " Quality of interlaced clips might be impacted."); 7687 } 7688 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) { 7689 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7690 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; 7691 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7692 DEBUG_PRINT_HIGH("Failed to set framerate extradata"); 7693 } 7694 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7695 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; 7696 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7697 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata"); 7698 } 7699 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7700 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; 7701 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7702 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata"); 7703 } 7704 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7705 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; 7706 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7707 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 7708 } 7709 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7710 control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO; 7711 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7712 DEBUG_PRINT_HIGH("Failed to set panscan extradata"); 7713 } 7714 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) { 7715 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 7716 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; 7717 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { 7718 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata"); 7719 } 7720 } 7721 } 7722 ret = get_buffer_req(&drv_ctx.op_buf); 7723 return ret; 7724} 7725 7726OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) 7727{ 7728 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; 7729 OMX_U8 *data_ptr = extra->data, data = 0; 7730 while (byte_count < extra->nDataSize) { 7731 data = *data_ptr; 7732 while (data) { 7733 num_MB += (data&0x01); 7734 data >>= 1; 7735 } 7736 data_ptr++; 7737 byte_count++; 7738 } 7739 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 7740 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 7741 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); 7742} 7743 7744void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) 7745{ 7746 if (!m_debug_extradata) 7747 return; 7748 7749 DEBUG_PRINT_HIGH( 7750 "============== Extra Data ==============\n" 7751 " Size: %lu\n" 7752 " Version: %lu\n" 7753 " PortIndex: %lu\n" 7754 " Type: %x\n" 7755 " DataSize: %lu", 7756 extra->nSize, extra->nVersion.nVersion, 7757 extra->nPortIndex, extra->eType, extra->nDataSize); 7758 7759 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) { 7760 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; 7761 DEBUG_PRINT_HIGH( 7762 "------ Interlace Format ------\n" 7763 " Size: %lu\n" 7764 " Version: %lu\n" 7765 " PortIndex: %lu\n" 7766 " Is Interlace Format: %d\n" 7767 " Interlace Formats: %lu\n" 7768 "=========== End of Interlace ===========", 7769 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, 7770 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); 7771 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) { 7772 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; 7773 7774 DEBUG_PRINT_HIGH( 7775 "-------- Frame Format --------\n" 7776 " Picture Type: %d\n" 7777 " Interlace Type: %d\n" 7778 " Pan Scan Total Frame Num: %lu\n" 7779 " Concealed Macro Blocks: %lu\n" 7780 " frame rate: %lu\n" 7781 " Aspect Ratio X: %lu\n" 7782 " Aspect Ratio Y: %lu", 7783 fminfo->ePicType, 7784 fminfo->interlaceType, 7785 fminfo->panScan.numWindows, 7786 fminfo->nConcealedMacroblocks, 7787 fminfo->nFrameRate, 7788 fminfo->aspectRatio.aspectRatioX, 7789 fminfo->aspectRatio.aspectRatioY); 7790 7791 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) { 7792 DEBUG_PRINT_HIGH( 7793 "------------------------------\n" 7794 " Pan Scan Frame Num: %lu\n" 7795 " Rectangle x: %ld\n" 7796 " Rectangle y: %ld\n" 7797 " Rectangle dx: %ld\n" 7798 " Rectangle dy: %ld", 7799 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, 7800 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); 7801 } 7802 7803 DEBUG_PRINT_HIGH("========= End of Frame Format =========="); 7804 } else if (extra->eType == OMX_ExtraDataNone) { 7805 DEBUG_PRINT_HIGH("========== End of Terminator ==========="); 7806 } else { 7807 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); 7808 } 7809} 7810 7811void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, 7812 OMX_U32 interlaced_format_type) 7813{ 7814 OMX_STREAMINTERLACEFORMAT *interlace_format; 7815 OMX_U32 mbaff = 0; 7816 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { 7817 return; 7818 } 7819 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; 7820 extra->nVersion.nVersion = OMX_SPEC_VERSION; 7821 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7822 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; 7823 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); 7824 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; 7825 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); 7826 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; 7827 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7828 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; 7829 if ((interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !mbaff) { 7830 interlace_format->bInterlaceFormat = OMX_FALSE; 7831 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 7832 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 7833 } else { 7834 interlace_format->bInterlaceFormat = OMX_TRUE; 7835 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 7836 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 7837 } 7838 print_debug_extradata(extra); 7839} 7840 7841void omx_vdec::fill_aspect_ratio_info( 7842 struct vdec_aspectratioinfo *aspect_ratio_info, 7843 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 7844{ 7845 m_extradata = frame_info; 7846 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; 7847 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; 7848 DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX, 7849 m_extradata->aspectRatio.aspectRatioY); 7850} 7851 7852void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, 7853 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, 7854 struct msm_vidc_panscan_window_payload *panscan_payload, 7855 struct vdec_aspectratioinfo *aspect_ratio_info) 7856{ 7857 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; 7858 struct msm_vidc_panscan_window *panscan_window; 7859 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { 7860 return; 7861 } 7862 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; 7863 extra->nVersion.nVersion = OMX_SPEC_VERSION; 7864 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7865 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; 7866 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); 7867 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; 7868 switch (picture_type) { 7869 case PICTURE_TYPE_I: 7870 frame_info->ePicType = OMX_VIDEO_PictureTypeI; 7871 break; 7872 case PICTURE_TYPE_P: 7873 frame_info->ePicType = OMX_VIDEO_PictureTypeP; 7874 break; 7875 case PICTURE_TYPE_B: 7876 frame_info->ePicType = OMX_VIDEO_PictureTypeB; 7877 break; 7878 default: 7879 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; 7880 } 7881 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 7882 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 7883 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 7884 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 7885 else 7886 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; 7887 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); 7888 frame_info->nConcealedMacroblocks = num_conceal_mb; 7889 frame_info->nFrameRate = frame_rate; 7890 frame_info->panScan.numWindows = 0; 7891 if (panscan_payload) { 7892 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; 7893 panscan_window = &panscan_payload->wnd[0]; 7894 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) { 7895 frame_info->panScan.window[i].x = panscan_window->panscan_window_width; 7896 frame_info->panScan.window[i].y = panscan_window->panscan_window_height; 7897 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; 7898 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; 7899 panscan_window++; 7900 } 7901 } 7902 fill_aspect_ratio_info(aspect_ratio_info, frame_info); 7903 print_debug_extradata(extra); 7904} 7905 7906void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) 7907{ 7908 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; 7909 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; 7910 extra->nVersion.nVersion = OMX_SPEC_VERSION; 7911 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7912 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; 7913 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 7914 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; 7915 *portDefn = m_port_def; 7916 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" 7917 "sliceheight = %u",portDefn->format.video.nFrameHeight, 7918 portDefn->format.video.nFrameWidth, 7919 portDefn->format.video.nStride, 7920 portDefn->format.video.nSliceHeight); 7921} 7922 7923void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) 7924{ 7925 if (!client_extradata) { 7926 return; 7927 } 7928 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 7929 extra->nVersion.nVersion = OMX_SPEC_VERSION; 7930 extra->eType = OMX_ExtraDataNone; 7931 extra->nDataSize = 0; 7932 extra->data[0] = 0; 7933 7934 print_debug_extradata(extra); 7935} 7936 7937OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) 7938{ 7939 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7940 if (index >= drv_ctx.ip_buf.actualcount) { 7941 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found"); 7942 return OMX_ErrorInsufficientResources; 7943 } 7944 if (m_desc_buffer_ptr == NULL) { 7945 m_desc_buffer_ptr = (desc_buffer_hdr*) \ 7946 calloc( (sizeof(desc_buffer_hdr)), 7947 drv_ctx.ip_buf.actualcount); 7948 if (m_desc_buffer_ptr == NULL) { 7949 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed "); 7950 return OMX_ErrorInsufficientResources; 7951 } 7952 } 7953 7954 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); 7955 if (m_desc_buffer_ptr[index].buf_addr == NULL) { 7956 DEBUG_PRINT_ERROR("desc buffer Allocation failed "); 7957 return OMX_ErrorInsufficientResources; 7958 } 7959 7960 return eRet; 7961} 7962 7963void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) 7964{ 7965 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); 7966 if (m_demux_entries < 8192) { 7967 m_demux_offsets[m_demux_entries++] = address_offset; 7968 } 7969 return; 7970} 7971 7972void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) 7973{ 7974 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; 7975 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; 7976 OMX_U32 index = 0; 7977 7978 m_demux_entries = 0; 7979 7980 while (index < bytes_to_parse) { 7981 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 7982 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || 7983 ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 7984 (buf[index+2] == 0x01)) ) { 7985 //Found start code, insert address offset 7986 insert_demux_addr_offset(index); 7987 if (buf[index+2] == 0x01) // 3 byte start code 7988 index += 3; 7989 else //4 byte start code 7990 index += 4; 7991 } else 7992 index++; 7993 } 7994 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); 7995 return; 7996} 7997 7998OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) 7999{ 8000 //fix this, handle 3 byte start code, vc1 terminator entry 8001 OMX_U8 *p_demux_data = NULL; 8002 OMX_U32 desc_data = 0; 8003 OMX_U32 start_addr = 0; 8004 OMX_U32 nal_size = 0; 8005 OMX_U32 suffix_byte = 0; 8006 OMX_U32 demux_index = 0; 8007 OMX_U32 buffer_index = 0; 8008 8009 if (m_desc_buffer_ptr == NULL) { 8010 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); 8011 return OMX_ErrorBadParameter; 8012 } 8013 8014 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 8015 if (buffer_index > drv_ctx.ip_buf.actualcount) { 8016 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index); 8017 return OMX_ErrorBadParameter; 8018 } 8019 8020 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; 8021 8022 if ( ((OMX_U8*)p_demux_data == NULL) || 8023 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) { 8024 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); 8025 return OMX_ErrorBadParameter; 8026 } else { 8027 for (; demux_index < m_demux_entries; demux_index++) { 8028 desc_data = 0; 8029 start_addr = m_demux_offsets[demux_index]; 8030 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) { 8031 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; 8032 } else { 8033 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; 8034 } 8035 if (demux_index < (m_demux_entries - 1)) { 8036 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; 8037 } else { 8038 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; 8039 } 8040 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", 8041 start_addr, 8042 suffix_byte, 8043 nal_size, 8044 demux_index); 8045 desc_data = (start_addr >> 3) << 1; 8046 desc_data |= (start_addr & 7) << 21; 8047 desc_data |= suffix_byte << 24; 8048 8049 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 8050 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); 8051 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 8052 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 8053 8054 p_demux_data += 16; 8055 } 8056 if (codec_type_parse == CODEC_TYPE_VC1) { 8057 DEBUG_PRINT_LOW("VC1 terminator entry"); 8058 desc_data = 0; 8059 desc_data = 0x82 << 24; 8060 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 8061 memset(p_demux_data + 4, 0, sizeof(OMX_U32)); 8062 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 8063 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 8064 p_demux_data += 16; 8065 m_demux_entries++; 8066 } 8067 //Add zero word to indicate end of descriptors 8068 memset(p_demux_data, 0, sizeof(OMX_U32)); 8069 8070 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); 8071 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); 8072 } 8073 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 8074 m_demux_entries = 0; 8075 DEBUG_PRINT_LOW("Demux table complete!"); 8076 return OMX_ErrorNone; 8077} 8078 8079omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() 8080{ 8081 enabled = false; 8082 omx = NULL; 8083 init_members(); 8084 ColorFormat = OMX_COLOR_FormatMax; 8085} 8086 8087void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) 8088{ 8089 omx = reinterpret_cast<omx_vdec*>(client); 8090} 8091 8092void omx_vdec::allocate_color_convert_buf::init_members() 8093{ 8094 allocated_count = 0; 8095 buffer_size_req = 0; 8096 buffer_alignment_req = 0; 8097 memset(m_platform_list_client,0,sizeof(m_platform_list_client)); 8098 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); 8099 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); 8100 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); 8101#ifdef USE_ION 8102 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); 8103#endif 8104 for (int i = 0; i < MAX_COUNT; i++) 8105 pmem_fd[i] = -1; 8106} 8107 8108omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() 8109{ 8110 c2d.destroy(); 8111} 8112 8113bool omx_vdec::allocate_color_convert_buf::update_buffer_req() 8114{ 8115 bool status = true; 8116 unsigned int src_size = 0, destination_size = 0; 8117 OMX_COLOR_FORMATTYPE drv_color_format; 8118 if (!omx) { 8119 DEBUG_PRINT_ERROR("Invalid client in color convert"); 8120 return false; 8121 } 8122 if (!enabled) { 8123 DEBUG_PRINT_HIGH("No color conversion required"); 8124 return status; 8125 } 8126 pthread_mutex_lock(&omx->c_lock); 8127 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && 8128 ColorFormat != OMX_COLOR_FormatYUV420Planar) { 8129 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion"); 8130 status = false; 8131 goto fail_update_buf_req; 8132 } 8133 c2d.close(); 8134 status = c2d.open(omx->drv_ctx.video_resolution.frame_height, 8135 omx->drv_ctx.video_resolution.frame_width, 8136 NV12_128m,YCbCr420P); 8137 if (status) { 8138 status = c2d.get_buffer_size(C2D_INPUT,src_size); 8139 if (status) 8140 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); 8141 } 8142 if (status) { 8143 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || 8144 !destination_size) { 8145 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d" 8146 "driver size %d destination size %d", 8147 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); 8148 status = false; 8149 c2d.close(); 8150 buffer_size_req = 0; 8151 } else { 8152 buffer_size_req = destination_size; 8153 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) 8154 buffer_size_req = omx->drv_ctx.op_buf.buffer_size; 8155 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 8156 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 8157 } 8158 } 8159fail_update_buf_req: 8160 pthread_mutex_unlock(&omx->c_lock); 8161 return status; 8162} 8163 8164bool omx_vdec::allocate_color_convert_buf::set_color_format( 8165 OMX_COLOR_FORMATTYPE dest_color_format) 8166{ 8167 bool status = true; 8168 OMX_COLOR_FORMATTYPE drv_color_format; 8169 if (!omx) { 8170 DEBUG_PRINT_ERROR("Invalid client in color convert"); 8171 return false; 8172 } 8173 pthread_mutex_lock(&omx->c_lock); 8174 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 8175 drv_color_format = (OMX_COLOR_FORMATTYPE) 8176 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 8177 else { 8178 DEBUG_PRINT_ERROR("Incorrect color format"); 8179 status = false; 8180 } 8181 if (status && (drv_color_format != dest_color_format)) { 8182 DEBUG_PRINT_LOW("Enabling C2D"); 8183 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { 8184 DEBUG_PRINT_ERROR("Unsupported color format for c2d"); 8185 status = false; 8186 } else { 8187 ColorFormat = OMX_COLOR_FormatYUV420Planar; 8188 if (enabled) 8189 c2d.destroy(); 8190 enabled = false; 8191 if (!c2d.init()) { 8192 DEBUG_PRINT_ERROR("open failed for c2d"); 8193 status = false; 8194 } else 8195 enabled = true; 8196 } 8197 } else { 8198 if (enabled) 8199 c2d.destroy(); 8200 enabled = false; 8201 } 8202 pthread_mutex_unlock(&omx->c_lock); 8203 return status; 8204} 8205 8206OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() 8207{ 8208 if (!omx) { 8209 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 8210 return NULL; 8211 } 8212 if (!enabled) 8213 return omx->m_out_mem_ptr; 8214 return m_out_mem_ptr_client; 8215} 8216 8217 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr 8218(OMX_BUFFERHEADERTYPE *bufadd) 8219{ 8220 if (!omx) { 8221 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 8222 return NULL; 8223 } 8224 if (!enabled) 8225 return bufadd; 8226 8227 unsigned index = 0; 8228 index = bufadd - omx->m_out_mem_ptr; 8229 if (index < omx->drv_ctx.op_buf.actualcount) { 8230 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); 8231 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; 8232 bool status; 8233 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { 8234 pthread_mutex_lock(&omx->c_lock); 8235 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, 8236 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer,pmem_fd[index], 8237 pmem_baseaddress[index], pmem_baseaddress[index]); 8238 pthread_mutex_unlock(&omx->c_lock); 8239 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; 8240 if (!status) { 8241 DEBUG_PRINT_ERROR("Failed color conversion %d", status); 8242 m_out_mem_ptr_client[index].nFilledLen = 0; 8243 return &m_out_mem_ptr_client[index]; 8244 } 8245 } else 8246 m_out_mem_ptr_client[index].nFilledLen = 0; 8247 return &m_out_mem_ptr_client[index]; 8248 } 8249 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr"); 8250 return NULL; 8251} 8252 8253 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr 8254(OMX_BUFFERHEADERTYPE *bufadd) 8255{ 8256 if (!omx) { 8257 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr"); 8258 return NULL; 8259 } 8260 if (!enabled) 8261 return bufadd; 8262 unsigned index = 0; 8263 index = bufadd - m_out_mem_ptr_client; 8264 if (index < omx->drv_ctx.op_buf.actualcount) { 8265 return &omx->m_out_mem_ptr[index]; 8266 } 8267 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr"); 8268 return NULL; 8269} 8270 bool omx_vdec::allocate_color_convert_buf::get_buffer_req 8271(unsigned int &buffer_size) 8272{ 8273 bool status = true; 8274 pthread_mutex_lock(&omx->c_lock); 8275 if (!enabled) 8276 buffer_size = omx->drv_ctx.op_buf.buffer_size; 8277 else { 8278 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { 8279 DEBUG_PRINT_ERROR("Get buffer size failed"); 8280 status = false; 8281 goto fail_get_buffer_size; 8282 } 8283 } 8284 if (buffer_size < omx->drv_ctx.op_buf.buffer_size) 8285 buffer_size = omx->drv_ctx.op_buf.buffer_size; 8286 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 8287 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 8288fail_get_buffer_size: 8289 pthread_mutex_unlock(&omx->c_lock); 8290 return status; 8291} 8292OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( 8293 OMX_BUFFERHEADERTYPE *bufhdr) 8294{ 8295 unsigned int index = 0; 8296 8297 if (!enabled) 8298 return omx->free_output_buffer(bufhdr); 8299 if (enabled && omx->is_component_secure()) 8300 return OMX_ErrorNone; 8301 if (!allocated_count || !bufhdr) { 8302 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); 8303 return OMX_ErrorBadParameter; 8304 } 8305 index = bufhdr - m_out_mem_ptr_client; 8306 if (index >= omx->drv_ctx.op_buf.actualcount) { 8307 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer"); 8308 return OMX_ErrorBadParameter; 8309 } 8310 if (pmem_fd[index] > 0) { 8311 munmap(pmem_baseaddress[index], buffer_size_req); 8312 close(pmem_fd[index]); 8313 } 8314 pmem_fd[index] = -1; 8315#ifdef USE_ION 8316 omx->free_ion_memory(&op_buf_ion_info[index]); 8317#endif 8318 m_heap_ptr[index].video_heap_ptr = NULL; 8319 if (allocated_count > 0) 8320 allocated_count--; 8321 else 8322 allocated_count = 0; 8323 if (!allocated_count) { 8324 pthread_mutex_lock(&omx->c_lock); 8325 c2d.close(); 8326 init_members(); 8327 pthread_mutex_unlock(&omx->c_lock); 8328 } 8329 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); 8330} 8331 8332OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, 8333 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) 8334{ 8335 OMX_ERRORTYPE eRet = OMX_ErrorNone; 8336 if (!enabled) { 8337 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 8338 return eRet; 8339 } 8340 if (enabled && omx->is_component_secure()) { 8341 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d", 8342 omx->is_component_secure()); 8343 return OMX_ErrorUnsupportedSetting; 8344 } 8345 if (!bufferHdr || bytes > buffer_size_req) { 8346 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr); 8347 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu", 8348 buffer_size_req,bytes); 8349 return OMX_ErrorBadParameter; 8350 } 8351 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { 8352 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert"); 8353 return OMX_ErrorInsufficientResources; 8354 } 8355 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; 8356 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, 8357 port,appData,omx->drv_ctx.op_buf.buffer_size); 8358 if (eRet != OMX_ErrorNone || !temp_bufferHdr) { 8359 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert"); 8360 return eRet; 8361 } 8362 if ((temp_bufferHdr - omx->m_out_mem_ptr) >= 8363 omx->drv_ctx.op_buf.actualcount) { 8364 DEBUG_PRINT_ERROR("Invalid header index %d", 8365 (temp_bufferHdr - omx->m_out_mem_ptr)); 8366 return OMX_ErrorUndefined; 8367 } 8368 unsigned int i = allocated_count; 8369#ifdef USE_ION 8370 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( 8371 buffer_size_req,buffer_alignment_req, 8372 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, 8373 0); 8374 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; 8375 if (op_buf_ion_info[i].ion_device_fd < 0) { 8376 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert"); 8377 return OMX_ErrorInsufficientResources; 8378 } 8379 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, 8380 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); 8381 8382 if (pmem_baseaddress[i] == MAP_FAILED) { 8383 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req); 8384 close(pmem_fd[i]); 8385 omx->free_ion_memory(&op_buf_ion_info[i]); 8386 return OMX_ErrorInsufficientResources; 8387 } 8388 m_heap_ptr[i].video_heap_ptr = new VideoHeap ( 8389 op_buf_ion_info[i].ion_device_fd,buffer_size_req, 8390 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); 8391#endif 8392 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); 8393 m_pmem_info_client[i].offset = 0; 8394 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; 8395 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 8396 m_platform_list_client[i].nEntries = 1; 8397 m_platform_list_client[i].entryList = &m_platform_entry_client[i]; 8398 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; 8399 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; 8400 m_out_mem_ptr_client[i].nFilledLen = 0; 8401 m_out_mem_ptr_client[i].nFlags = 0; 8402 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 8403 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); 8404 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; 8405 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; 8406 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; 8407 m_out_mem_ptr_client[i].pAppPrivate = appData; 8408 *bufferHdr = &m_out_mem_ptr_client[i]; 8409 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr); 8410 allocated_count++; 8411 return eRet; 8412} 8413 8414bool omx_vdec::is_component_secure() 8415{ 8416 return secure_mode; 8417} 8418 8419bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) 8420{ 8421 bool status = true; 8422 if (!enabled) { 8423 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 8424 dest_color_format = (OMX_COLOR_FORMATTYPE) 8425 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; 8426 else 8427 status = false; 8428 } else { 8429 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { 8430 status = false; 8431 } else 8432 dest_color_format = OMX_COLOR_FormatYUV420Planar; 8433 } 8434 return status; 8435} 8436