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