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