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