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