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