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