blob: 775b32481351ab04bfa46dac590fa8d2c33628a3 [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 {
3115 arbitrary_bytes = false;
3116 }
3117 else
3118 {
3119 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
3120 portFmt->nFramePackingFormat);
3121 eRet = OMX_ErrorUnsupportedSetting;
3122 }
3123 }
3124 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3125 {
3126 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3127 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3128 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3129 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3130 {
3131 m_out_mem_region_smi = OMX_TRUE;
3132 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3133 {
3134 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3135 m_use_output_pmem = OMX_TRUE;
3136 }
3137 }
3138 }
3139 }
3140 break;
3141
3142 case OMX_IndexParamStandardComponentRole:
3143 {
3144 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3145 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3146 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3147 comp_role->cRole);
3148
3149 if((m_state == OMX_StateLoaded)&&
3150 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3151 {
3152 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3153 }
3154 else
3155 {
3156 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3157 return OMX_ErrorIncorrectStateOperation;
3158 }
3159
3160 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3161 {
3162 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3163 {
3164 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3165 }
3166 else
3167 {
3168 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3169 eRet =OMX_ErrorUnsupportedSetting;
3170 }
3171 }
3172 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3173 {
3174 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3175 {
3176 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3177 }
3178 else
3179 {
3180 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3181 eRet = OMX_ErrorUnsupportedSetting;
3182 }
3183 }
3184 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3185 {
3186 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3187 {
3188 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3189 }
3190 else
3191 {
3192 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3193 eRet =OMX_ErrorUnsupportedSetting;
3194 }
3195 }
3196 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3197 {
3198 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3199 {
3200 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3201 }
3202 else
3203 {
3204 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3205 eRet = OMX_ErrorUnsupportedSetting;
3206 }
3207 }
3208 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3209 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3210 )
3211 {
3212 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3213 {
3214 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3215 }
3216 else
3217 {
3218 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3219 eRet =OMX_ErrorUnsupportedSetting;
3220 }
3221 }
3222 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3223 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3224 )
3225 {
3226 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3227 {
3228 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3229 }
3230 else
3231 {
3232 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3233 eRet =OMX_ErrorUnsupportedSetting;
3234 }
3235 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003236 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3237 {
3238 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3239 {
3240 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3241 }
3242 else
3243 {
3244 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3245 eRet = OMX_ErrorUnsupportedSetting;
3246 }
3247 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003248 else
3249 {
3250 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3251 eRet = OMX_ErrorInvalidComponentName;
3252 }
3253 break;
3254 }
3255
3256 case OMX_IndexParamPriorityMgmt:
3257 {
3258 if(m_state != OMX_StateLoaded)
3259 {
3260 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3261 return OMX_ErrorIncorrectStateOperation;
3262 }
3263 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3264 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
3265 priorityMgmtype->nGroupID);
3266
3267 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
3268 priorityMgmtype->nGroupPriority);
3269
3270 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3271 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3272
3273 break;
3274 }
3275
3276 case OMX_IndexParamCompBufferSupplier:
3277 {
3278 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3279 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3280 bufferSupplierType->eBufferSupplier);
3281 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3282 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3283
3284 else
3285
3286 eRet = OMX_ErrorBadPortIndex;
3287
3288 break;
3289
3290 }
3291 case OMX_IndexParamVideoAvc:
3292 {
3293 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3294 paramIndex);
3295 break;
3296 }
3297 case OMX_IndexParamVideoH263:
3298 {
3299 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3300 paramIndex);
3301 break;
3302 }
3303 case OMX_IndexParamVideoMpeg4:
3304 {
3305 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3306 paramIndex);
3307 break;
3308 }
3309 case OMX_IndexParamVideoMpeg2:
3310 {
3311 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3312 paramIndex);
3313 break;
3314 }
3315 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3316 {
3317 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3318 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003319 struct v4l2_control control;
3320 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003321 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3322 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003323 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3324 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3325 }
3326 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3327 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003328 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003329 }
3330 else
3331 eRet = OMX_ErrorBadParameter;
3332 if (eRet == OMX_ErrorNone)
3333 {
3334 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3335 control.value = pic_order;
3336 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3337 if(rc)
3338 {
3339 DEBUG_PRINT_ERROR("\n Set picture order failed");
3340 eRet = OMX_ErrorUnsupportedSetting;
3341 }
3342 }
3343 break;
3344 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003345 case OMX_QcomIndexParamConcealMBMapExtraData:
3346 if(!secure_mode)
3347 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP,
3348 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3349 else {
3350 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3351 eRet = OMX_ErrorUnsupportedSetting;
3352 }
3353 break;
3354 case OMX_QcomIndexParamFrameInfoExtraData:
3355 {
3356 if(!secure_mode)
3357 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA,
3358 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3359 else {
3360 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3361 eRet = OMX_ErrorUnsupportedSetting;
3362 }
3363 break;
3364 }
3365 case OMX_QcomIndexParamInterlaceExtraData:
3366 if(!secure_mode)
3367 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA,
3368 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3369 else {
3370 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3371 eRet = OMX_ErrorUnsupportedSetting;
3372 }
3373 break;
3374 case OMX_QcomIndexParamH264TimeInfo:
3375 if(!secure_mode)
3376 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA,
3377 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3378 else {
3379 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3380 eRet = OMX_ErrorUnsupportedSetting;
3381 }
3382 break;
3383 case OMX_QcomIndexParamVideoDivx:
3384 {
3385 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3386
3387#if 0
3388 createDivxDrmContext( divXType->pDrmHandle );
3389#endif
3390 }
3391 break;
3392 case OMX_QcomIndexPlatformPvt:
3393 {
3394 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3395 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3396 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3397 {
3398 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3399 eRet = OMX_ErrorUnsupportedSetting;
3400 }
3401 else
3402 {
3403 m_out_pvt_entry_pmem = OMX_TRUE;
3404 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3405 {
3406 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3407 m_use_output_pmem = OMX_TRUE;
3408 }
3409 }
3410
3411 }
3412 break;
3413 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3414 {
3415 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3416 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3417 drv_ctx.idr_only_decoding = 1;
3418 int rc; //= ioctl(drv_ctx.video_driver_fd,
3419 // VDEC_IOCTL_SET_IDR_ONLY_DECODING);
3420 if(rc < 0) {
3421 DEBUG_PRINT_ERROR("Failed to set IDR only decoding on driver.");
3422 eRet = OMX_ErrorHardware;
3423 }
3424 }
3425 break;
3426
3427 case OMX_QcomIndexParamIndexExtraDataType:
3428 {
3429 if(!secure_mode) {
3430 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3431 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3432 (extradataIndexType->bEnabled == OMX_TRUE) &&
3433 (extradataIndexType->nPortIndex == 1))
3434 {
3435 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3436 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003437
Shalaj Jain273b3e02012-06-22 19:08:03 -07003438 }
3439 }
3440 }
3441 break;
3442
3443#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3444 /* Need to allow following two set_parameters even in Idle
3445 * state. This is ANDROID architecture which is not in sync
3446 * with openmax standard. */
3447 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3448 {
3449 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3450 if(enableNativeBuffers) {
3451 m_enable_android_native_buffers = enableNativeBuffers->enable;
3452 }
3453 }
3454 break;
3455 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3456 {
3457 eRet = use_android_native_buffer(hComp, paramData);
3458 }
3459 break;
3460#endif
3461 case OMX_QcomIndexParamEnableTimeStampReorder:
3462 {
3463 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3464 if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) {
3465 if (reorder->bEnable == OMX_TRUE) {
3466 frm_int =0;
3467 time_stamp_dts.set_timestamp_reorder_mode(true);
3468 }
3469 else
3470 time_stamp_dts.set_timestamp_reorder_mode(false);
3471 } else {
3472 time_stamp_dts.set_timestamp_reorder_mode(false);
3473 if (reorder->bEnable == OMX_TRUE)
3474 {
3475 eRet = OMX_ErrorUnsupportedSetting;
3476 }
3477 }
3478 }
3479 break;
3480 default:
3481 {
3482 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3483 eRet = OMX_ErrorUnsupportedIndex;
3484 }
3485 }
3486 return eRet;
3487}
3488
3489/* ======================================================================
3490FUNCTION
3491 omx_vdec::GetConfig
3492
3493DESCRIPTION
3494 OMX Get Config Method implementation.
3495
3496PARAMETERS
3497 <TBD>.
3498
3499RETURN VALUE
3500 OMX Error None if successful.
3501
3502========================================================================== */
3503OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3504 OMX_IN OMX_INDEXTYPE configIndex,
3505 OMX_INOUT OMX_PTR configData)
3506{
3507 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3508
3509 if (m_state == OMX_StateInvalid)
3510 {
3511 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3512 return OMX_ErrorInvalidState;
3513 }
3514
3515 switch (configIndex)
3516 {
3517 case OMX_QcomIndexConfigInterlaced:
3518 {
3519 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3520 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3521 if (configFmt->nPortIndex == 1)
3522 {
3523 if (configFmt->nIndex == 0)
3524 {
3525 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3526 }
3527 else if (configFmt->nIndex == 1)
3528 {
3529 configFmt->eInterlaceType =
3530 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3531 }
3532 else if (configFmt->nIndex == 2)
3533 {
3534 configFmt->eInterlaceType =
3535 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3536 }
3537 else
3538 {
3539 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3540 " NoMore Interlaced formats\n");
3541 eRet = OMX_ErrorNoMore;
3542 }
3543
3544 }
3545 else
3546 {
3547 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3548 (int)configFmt->nPortIndex);
3549 eRet = OMX_ErrorBadPortIndex;
3550 }
3551 break;
3552 }
3553 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3554 {
3555 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3556 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3557 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3558 //ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances;
3559 //(void)(ioctl(drv_ctx.video_driver_fd,
3560 //VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
3561
3562 decoderinstances->nNumOfInstances = 16;
3563 /*TODO: How to handle this case */
3564 break;
3565 }
3566 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3567 {
3568 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3569 {
3570 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3571 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3572 h264_parser->get_frame_pack_data(configFmt);
3573 }
3574 else
3575 {
3576 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3577 }
3578 break;
3579 }
3580 default:
3581 {
3582 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3583 eRet = OMX_ErrorBadParameter;
3584 }
3585
3586 }
3587
3588 return eRet;
3589}
3590
3591/* ======================================================================
3592FUNCTION
3593 omx_vdec::SetConfig
3594
3595DESCRIPTION
3596 OMX Set Config method implementation
3597
3598PARAMETERS
3599 <TBD>.
3600
3601RETURN VALUE
3602 OMX Error None if successful.
3603========================================================================== */
3604OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3605 OMX_IN OMX_INDEXTYPE configIndex,
3606 OMX_IN OMX_PTR configData)
3607{
3608 if(m_state == OMX_StateInvalid)
3609 {
3610 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3611 return OMX_ErrorInvalidState;
3612 }
3613
3614 OMX_ERRORTYPE ret = OMX_ErrorNone;
3615 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3616
3617 DEBUG_PRINT_LOW("\n Set Config Called");
3618
3619 if (m_state == OMX_StateExecuting)
3620 {
3621 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3622 return ret;
3623 }
3624
3625 if (configIndex == OMX_IndexVendorVideoExtraData)
3626 {
3627 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3628 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3629 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3630 {
3631 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3632 OMX_U32 extra_size;
3633 // Parsing done here for the AVC atom is definitely not generic
3634 // Currently this piece of code is working, but certainly
3635 // not tested with all .mp4 files.
3636 // Incase of failure, we might need to revisit this
3637 // for a generic piece of code.
3638
3639 // Retrieve size of NAL length field
3640 // byte #4 contains the size of NAL lenght field
3641 nal_length = (config->pData[4] & 0x03) + 1;
3642
3643 extra_size = 0;
3644 if (nal_length > 2)
3645 {
3646 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3647 extra_size = (nal_length - 2) * 2;
3648 }
3649
3650 // SPS starts from byte #6
3651 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3652 OMX_U8 *pDestBuf;
3653 m_vendor_config.nPortIndex = config->nPortIndex;
3654
3655 // minus 6 --> SPS starts from byte #6
3656 // minus 1 --> picture param set byte to be ignored from avcatom
3657 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3658 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3659 OMX_U32 len;
3660 OMX_U8 index = 0;
3661 // case where SPS+PPS is sent as part of set_config
3662 pDestBuf = m_vendor_config.pData;
3663
3664 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
3665 m_vendor_config.nPortIndex,
3666 m_vendor_config.nDataSize,
3667 m_vendor_config.pData);
3668 while (index < 2)
3669 {
3670 uint8 *psize;
3671 len = *pSrcBuf;
3672 len = len << 8;
3673 len |= *(pSrcBuf + 1);
3674 psize = (uint8 *) & len;
3675 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3676 for (int i = 0; i < nal_length; i++)
3677 {
3678 pDestBuf[i] = psize[nal_length - 1 - i];
3679 }
3680 //memcpy(pDestBuf,pSrcBuf,(len+2));
3681 pDestBuf += len + nal_length;
3682 pSrcBuf += len + 2;
3683 index++;
3684 pSrcBuf++; // skip picture param set
3685 len = 0;
3686 }
3687 }
3688 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3689 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3690 {
3691 m_vendor_config.nPortIndex = config->nPortIndex;
3692 m_vendor_config.nDataSize = config->nDataSize;
3693 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3694 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3695 }
3696 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3697 {
3698 if(m_vendor_config.pData)
3699 {
3700 free(m_vendor_config.pData);
3701 m_vendor_config.pData = NULL;
3702 m_vendor_config.nDataSize = 0;
3703 }
3704
3705 if (((*((OMX_U32 *) config->pData)) &
3706 VC1_SP_MP_START_CODE_MASK) ==
3707 VC1_SP_MP_START_CODE)
3708 {
3709 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3710 m_vendor_config.nPortIndex = config->nPortIndex;
3711 m_vendor_config.nDataSize = config->nDataSize;
3712 m_vendor_config.pData =
3713 (OMX_U8 *) malloc(config->nDataSize);
3714 memcpy(m_vendor_config.pData, config->pData,
3715 config->nDataSize);
3716 m_vc1_profile = VC1_SP_MP_RCV;
3717 }
3718 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3719 {
3720 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3721 m_vendor_config.nPortIndex = config->nPortIndex;
3722 m_vendor_config.nDataSize = config->nDataSize;
3723 m_vendor_config.pData =
3724 (OMX_U8 *) malloc((config->nDataSize));
3725 memcpy(m_vendor_config.pData, config->pData,
3726 config->nDataSize);
3727 m_vc1_profile = VC1_AP;
3728 }
3729 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3730 {
3731 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3732 m_vendor_config.nPortIndex = config->nPortIndex;
3733 m_vendor_config.nDataSize = config->nDataSize;
3734 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3735 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3736 m_vc1_profile = VC1_SP_MP_RCV;
3737 }
3738 else
3739 {
3740 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3741 }
3742 }
3743 return ret;
3744 }
3745 else if (configIndex == OMX_IndexConfigVideoNalSize)
3746 {
3747
3748 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3749 nal_length = pNal->nNaluBytes;
3750 m_frame_parser.init_nal_length(nal_length);
3751 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3752 return ret;
3753 }
3754
3755 return OMX_ErrorNotImplemented;
3756}
3757
3758/* ======================================================================
3759FUNCTION
3760 omx_vdec::GetExtensionIndex
3761
3762DESCRIPTION
3763 OMX GetExtensionIndex method implementaion. <TBD>
3764
3765PARAMETERS
3766 <TBD>.
3767
3768RETURN VALUE
3769 OMX Error None if everything successful.
3770
3771========================================================================== */
3772OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3773 OMX_IN OMX_STRING paramName,
3774 OMX_OUT OMX_INDEXTYPE* indexType)
3775{
3776 if(m_state == OMX_StateInvalid)
3777 {
3778 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3779 return OMX_ErrorInvalidState;
3780 }
3781 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3782 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3783 }
3784 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3785 {
3786 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3787 }
3788#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3789 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3790 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3791 }
3792 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3793 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3794 }
3795 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3796 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3797 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3798 }
3799 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3800 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3801 }
3802#endif
3803 else {
3804 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3805 return OMX_ErrorNotImplemented;
3806 }
3807 return OMX_ErrorNone;
3808}
3809
3810/* ======================================================================
3811FUNCTION
3812 omx_vdec::GetState
3813
3814DESCRIPTION
3815 Returns the state information back to the caller.<TBD>
3816
3817PARAMETERS
3818 <TBD>.
3819
3820RETURN VALUE
3821 Error None if everything is successful.
3822========================================================================== */
3823OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
3824 OMX_OUT OMX_STATETYPE* state)
3825{
3826 *state = m_state;
3827 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3828 return OMX_ErrorNone;
3829}
3830
3831/* ======================================================================
3832FUNCTION
3833 omx_vdec::ComponentTunnelRequest
3834
3835DESCRIPTION
3836 OMX Component Tunnel Request method implementation. <TBD>
3837
3838PARAMETERS
3839 None.
3840
3841RETURN VALUE
3842 OMX Error None if everything successful.
3843
3844========================================================================== */
3845OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
3846 OMX_IN OMX_U32 port,
3847 OMX_IN OMX_HANDLETYPE peerComponent,
3848 OMX_IN OMX_U32 peerPort,
3849 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
3850{
3851 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3852 return OMX_ErrorNotImplemented;
3853}
3854
3855/* ======================================================================
3856FUNCTION
3857 omx_vdec::UseOutputBuffer
3858
3859DESCRIPTION
3860 Helper function for Use buffer in the input pin
3861
3862PARAMETERS
3863 None.
3864
3865RETURN VALUE
3866 true/false
3867
3868========================================================================== */
3869OMX_ERRORTYPE omx_vdec::use_output_buffer(
3870 OMX_IN OMX_HANDLETYPE hComp,
3871 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3872 OMX_IN OMX_U32 port,
3873 OMX_IN OMX_PTR appData,
3874 OMX_IN OMX_U32 bytes,
3875 OMX_IN OMX_U8* buffer)
3876{
3877 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3878 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3879 unsigned i= 0; // Temporary counter
3880 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3881 struct vdec_setbuffer_cmd setbuffers;
3882 OMX_PTR privateAppData = NULL;
3883 private_handle_t *handle = NULL;
3884 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003885 struct v4l2_buffer buf;
3886 struct v4l2_plane plane;
3887
Shalaj Jain273b3e02012-06-22 19:08:03 -07003888 if (!m_out_mem_ptr) {
3889 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3890 eRet = allocate_output_headers();
3891 }
3892
3893 if (eRet == OMX_ErrorNone) {
3894 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
3895 if(BITMASK_ABSENT(&m_out_bm_count,i))
3896 {
3897 break;
3898 }
3899 }
3900 }
3901
3902 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003903 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003904 eRet = OMX_ErrorInsufficientResources;
3905 }
3906
3907 if (eRet == OMX_ErrorNone) {
3908#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
3909 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003910 if (m_use_android_native_buffers) {
3911 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3912 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3913 handle = (private_handle_t *)nBuf->handle;
3914 privateAppData = params->pAppPrivate;
3915 } else {
3916 handle = (private_handle_t *)buff;
3917 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003918 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003919
3920 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3921 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3922 " expected %u, got %lu",
3923 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3924 return OMX_ErrorBadParameter;
3925 }
3926
3927 if (!m_use_android_native_buffers) {
3928 if (!secure_mode) {
3929 buff = (OMX_U8*)mmap(0, handle->size,
3930 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3931 if (buff == MAP_FAILED) {
3932 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3933 return OMX_ErrorInsufficientResources;
3934 }
3935 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003936 }
3937#if defined(_ANDROID_ICS_)
3938 native_buffer[i].nativehandle = handle;
3939#endif
3940 if(!handle) {
3941 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3942 return OMX_ErrorBadParameter;
3943 }
3944 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3945 drv_ctx.ptr_outputbuffer[i].offset = 0;
3946 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3947 drv_ctx.ptr_outputbuffer[i].mmaped_size =
3948 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3949 } else
3950#endif
3951
3952 if (!ouput_egl_buffers && !m_use_output_pmem) {
3953#ifdef USE_ION
3954 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3955 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3956 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3957 &drv_ctx.op_buf_ion_info[i].fd_ion_data, 0);
3958 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003959 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 -07003960 return OMX_ErrorInsufficientResources;
3961 }
3962 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3963 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3964#else
3965 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3966 open (MEM_DEVICE,O_RDWR);
3967
3968 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003969 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 -07003970 return OMX_ErrorInsufficientResources;
3971 }
3972
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003973 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003974 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
3975 {
3976 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3977 open (MEM_DEVICE,O_RDWR);
3978 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003979 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 -07003980 return OMX_ErrorInsufficientResources;
3981 }
3982 }
3983
3984 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
3985 drv_ctx.op_buf.buffer_size,
3986 drv_ctx.op_buf.alignment))
3987 {
3988 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3989 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3990 return OMX_ErrorInsufficientResources;
3991 }
3992#endif
3993 if(!secure_mode) {
3994 drv_ctx.ptr_outputbuffer[i].bufferaddr =
3995 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
3996 PROT_READ|PROT_WRITE, MAP_SHARED,
3997 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
3998 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
3999 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4000#ifdef USE_ION
4001 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4002#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004003 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004004 return OMX_ErrorInsufficientResources;
4005 }
4006 }
4007 drv_ctx.ptr_outputbuffer[i].offset = 0;
4008 privateAppData = appData;
4009 }
4010 else {
4011
4012 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4013 if (!appData || !bytes ) {
4014 if(!secure_mode && !buffer) {
4015 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4016 return OMX_ErrorBadParameter;
4017 }
4018 }
4019
4020 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4021 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4022 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4023 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4024 !pmem_list->nEntries ||
4025 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4026 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4027 return OMX_ErrorBadParameter;
4028 }
4029 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4030 pmem_list->entryList->entry;
4031 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
4032 pmem_info->pmem_fd);
4033 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4034 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4035 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4036 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4037 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4038 privateAppData = appData;
4039 }
4040 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4041 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4042
4043 *bufferHdr = (m_out_mem_ptr + i );
4044 if(secure_mode)
4045 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4046 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4047 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4048 sizeof (vdec_bufferpayload));
4049
4050 // ioctl_msg.in = &setbuffers;
4051 // ioctl_msg.out = NULL;
4052
4053 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i,
4054 drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd );
4055 // if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4056 // &ioctl_msg) < 0)
4057 // {
4058 // DEBUG_PRINT_ERROR("\n Set output buffer failed");
4059 // return OMX_ErrorInsufficientResources;
4060 // }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004061
4062
4063
4064 buf.index = i;
4065 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4066 buf.memory = V4L2_MEMORY_USERPTR;
4067 plane.length = drv_ctx.op_buf.buffer_size;
4068 plane.m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[i].bufferaddr-drv_ctx.ptr_outputbuffer[i].offset);
4069 plane.reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4070 plane.reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4071 plane.data_offset = 0;
4072 buf.m.planes = &plane;
4073 buf.length = 1;
4074
4075 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4076
4077 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4078 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4079 /*TODO: How to handle this case */
4080 return OMX_ErrorInsufficientResources;
4081 }
4082
4083 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4084 enum v4l2_buf_type buf_type;
4085 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4086 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4087 return OMX_ErrorInsufficientResources;
4088 } else {
4089 streaming[CAPTURE_PORT] = true;
4090 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4091 }
4092 }
4093
Shalaj Jain273b3e02012-06-22 19:08:03 -07004094 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004095 if (m_enable_android_native_buffers) {
4096 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4097 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4098 } else {
4099 (*bufferHdr)->pBuffer = buff;
4100 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004101 (*bufferHdr)->pAppPrivate = privateAppData;
4102 BITMASK_SET(&m_out_bm_count,i);
4103 }
4104 return eRet;
4105}
4106
4107/* ======================================================================
4108FUNCTION
4109 omx_vdec::use_input_heap_buffers
4110
4111DESCRIPTION
4112 OMX Use Buffer Heap allocation method implementation.
4113
4114PARAMETERS
4115 <TBD>.
4116
4117RETURN VALUE
4118 OMX Error None , if everything successful.
4119
4120========================================================================== */
4121OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4122 OMX_IN OMX_HANDLETYPE hComp,
4123 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4124 OMX_IN OMX_U32 port,
4125 OMX_IN OMX_PTR appData,
4126 OMX_IN OMX_U32 bytes,
4127 OMX_IN OMX_U8* buffer)
4128{
4129 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4130 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4131 if(!m_inp_heap_ptr)
4132 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4133 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4134 drv_ctx.ip_buf.actualcount);
4135 if(!m_phdr_pmem_ptr)
4136 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4137 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4138 drv_ctx.ip_buf.actualcount);
4139 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4140 {
4141 DEBUG_PRINT_ERROR("Insufficent memory");
4142 eRet = OMX_ErrorInsufficientResources;
4143 }
4144 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4145 {
4146 input_use_buffer = true;
4147 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4148 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4149 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4150 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4151 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4152 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4153 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4154 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4155 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4156 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL))
4157 {
4158 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4159 return OMX_ErrorInsufficientResources;
4160 }
4161 m_in_alloc_cnt++;
4162 }
4163 else
4164 {
4165 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4166 eRet = OMX_ErrorInsufficientResources;
4167 }
4168 return eRet;
4169}
4170
4171/* ======================================================================
4172FUNCTION
4173 omx_vdec::UseBuffer
4174
4175DESCRIPTION
4176 OMX Use Buffer method implementation.
4177
4178PARAMETERS
4179 <TBD>.
4180
4181RETURN VALUE
4182 OMX Error None , if everything successful.
4183
4184========================================================================== */
4185OMX_ERRORTYPE omx_vdec::use_buffer(
4186 OMX_IN OMX_HANDLETYPE hComp,
4187 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4188 OMX_IN OMX_U32 port,
4189 OMX_IN OMX_PTR appData,
4190 OMX_IN OMX_U32 bytes,
4191 OMX_IN OMX_U8* buffer)
4192{
4193 OMX_ERRORTYPE error = OMX_ErrorNone;
4194 struct vdec_setbuffer_cmd setbuffers;
4195 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4196
4197 if (bufferHdr == NULL || bytes == 0)
4198 {
4199 if(!secure_mode && buffer == NULL) {
4200 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4201 return OMX_ErrorBadParameter;
4202 }
4203 }
4204 if(m_state == OMX_StateInvalid)
4205 {
4206 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4207 return OMX_ErrorInvalidState;
4208 }
4209 if(port == OMX_CORE_INPUT_PORT_INDEX)
4210 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4211 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4212 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4213 else
4214 {
4215 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4216 error = OMX_ErrorBadPortIndex;
4217 }
4218 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
4219 if(error == OMX_ErrorNone)
4220 {
4221 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4222 {
4223 // Send the callback now
4224 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4225 post_event(OMX_CommandStateSet,OMX_StateIdle,
4226 OMX_COMPONENT_GENERATE_EVENT);
4227 }
4228 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4229 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4230 {
4231 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4232 post_event(OMX_CommandPortEnable,
4233 OMX_CORE_INPUT_PORT_INDEX,
4234 OMX_COMPONENT_GENERATE_EVENT);
4235 }
4236 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4237 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4238 {
4239 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4240 post_event(OMX_CommandPortEnable,
4241 OMX_CORE_OUTPUT_PORT_INDEX,
4242 OMX_COMPONENT_GENERATE_EVENT);
4243 }
4244 }
4245 return error;
4246}
4247
4248OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4249 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4250{
4251 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4252 {
4253 if(m_inp_heap_ptr[bufferindex].pBuffer)
4254 free(m_inp_heap_ptr[bufferindex].pBuffer);
4255 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4256 }
4257 if (pmem_bufferHdr)
4258 free_input_buffer(pmem_bufferHdr);
4259 return OMX_ErrorNone;
4260}
4261
4262OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4263{
4264 unsigned int index = 0;
4265 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4266 {
4267 return OMX_ErrorBadParameter;
4268 }
4269
4270 index = bufferHdr - m_inp_mem_ptr;
4271 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4272
4273 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4274 {
4275 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4276 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4277 {
4278 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4279 struct vdec_setbuffer_cmd setbuffers;
4280 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4281 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4282 sizeof (vdec_bufferpayload));
4283 ioctl_msg.in = &setbuffers;
4284 ioctl_msg.out = NULL;
4285 int ioctl_r; //= ioctl (drv_ctx.video_driver_fd,
4286 // VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
4287 if (ioctl_r < 0)
4288 {
4289 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
4290 }
4291
4292 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4293 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4294 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d",
4295 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4296 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4297 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4298 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4299 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4300 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4301 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4302 {
4303 free(m_desc_buffer_ptr[index].buf_addr);
4304 m_desc_buffer_ptr[index].buf_addr = NULL;
4305 m_desc_buffer_ptr[index].desc_data_size = 0;
4306 }
4307#ifdef USE_ION
4308 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4309#endif
4310 }
4311 }
4312
4313 return OMX_ErrorNone;
4314}
4315
4316OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4317{
4318 unsigned int index = 0;
4319
4320 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4321 {
4322 return OMX_ErrorBadParameter;
4323 }
4324
4325 index = bufferHdr - m_out_mem_ptr;
4326 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4327
4328 if (index < drv_ctx.op_buf.actualcount
4329 && drv_ctx.ptr_outputbuffer)
4330 {
4331 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
4332 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4333
4334 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4335 struct vdec_setbuffer_cmd setbuffers;
4336 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4337 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4338 sizeof (vdec_bufferpayload));
4339 ioctl_msg.in = &setbuffers;
4340 ioctl_msg.out = NULL;
4341 DEBUG_PRINT_LOW("\nRelease the Output Buffer");
4342 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
4343 &ioctl_msg) < */0)
4344 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
4345
4346#ifdef _ANDROID_
4347 if(m_enable_android_native_buffers) {
4348 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4349 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4350 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4351 }
4352 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4353 } else {
4354#endif
4355 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4356 {
4357 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4358 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4359 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d",
4360 drv_ctx.ptr_outputbuffer[0].mmaped_size,
4361 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4362 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4363 drv_ctx.ptr_outputbuffer[0].mmaped_size);
4364 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4365 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4366#ifdef USE_ION
4367 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4368#endif
4369 }
4370#ifdef _ANDROID_
4371 }
4372#endif
4373 }
4374
4375 return OMX_ErrorNone;
4376
4377}
4378
4379OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4380 OMX_BUFFERHEADERTYPE **bufferHdr,
4381 OMX_U32 port,
4382 OMX_PTR appData,
4383 OMX_U32 bytes)
4384{
4385 OMX_BUFFERHEADERTYPE *input = NULL;
4386 unsigned char *buf_addr = NULL;
4387 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4388 unsigned i = 0;
4389
4390 /* Sanity Check*/
4391 if (bufferHdr == NULL)
4392 {
4393 return OMX_ErrorBadParameter;
4394 }
4395
4396 if (m_inp_heap_ptr == NULL)
4397 {
4398 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4399 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4400 drv_ctx.ip_buf.actualcount);
4401 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4402 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4403 drv_ctx.ip_buf.actualcount);
4404
4405 if (m_inp_heap_ptr == NULL)
4406 {
4407 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4408 return OMX_ErrorInsufficientResources;
4409 }
4410 }
4411
4412 /*Find a Free index*/
4413 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4414 {
4415 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4416 {
4417 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4418 break;
4419 }
4420 }
4421
4422 if (i < drv_ctx.ip_buf.actualcount)
4423 {
4424 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4425
4426 if (buf_addr == NULL)
4427 {
4428 return OMX_ErrorInsufficientResources;
4429 }
4430
4431 *bufferHdr = (m_inp_heap_ptr + i);
4432 input = *bufferHdr;
4433 BITMASK_SET(&m_heap_inp_bm_count,i);
4434
4435 input->pBuffer = (OMX_U8 *)buf_addr;
4436 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4437 input->nVersion.nVersion = OMX_SPEC_VERSION;
4438 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4439 input->pAppPrivate = appData;
4440 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4441 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4442 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4443 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
4444 /*Add the Buffers to freeq*/
4445 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL))
4446 {
4447 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4448 return OMX_ErrorInsufficientResources;
4449 }
4450 }
4451 else
4452 {
4453 return OMX_ErrorBadParameter;
4454 }
4455
4456 return eRet;
4457
4458}
4459
4460
4461/* ======================================================================
4462FUNCTION
4463 omx_vdec::AllocateInputBuffer
4464
4465DESCRIPTION
4466 Helper function for allocate buffer in the input pin
4467
4468PARAMETERS
4469 None.
4470
4471RETURN VALUE
4472 true/false
4473
4474========================================================================== */
4475OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4476 OMX_IN OMX_HANDLETYPE hComp,
4477 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4478 OMX_IN OMX_U32 port,
4479 OMX_IN OMX_PTR appData,
4480 OMX_IN OMX_U32 bytes)
4481{
4482
4483 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4484 struct vdec_setbuffer_cmd setbuffers;
4485 OMX_BUFFERHEADERTYPE *input = NULL;
4486 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4487 unsigned i = 0;
4488 unsigned char *buf_addr = NULL;
4489 int pmem_fd = -1;
4490
4491 if(bytes != drv_ctx.ip_buf.buffer_size)
4492 {
4493 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",
4494 bytes, drv_ctx.ip_buf.buffer_size);
4495 return OMX_ErrorBadParameter;
4496 }
4497
4498 if(!m_inp_mem_ptr)
4499 {
4500 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4501 drv_ctx.ip_buf.actualcount,
4502 drv_ctx.ip_buf.buffer_size);
4503
4504 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4505 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4506
4507 if (m_inp_mem_ptr == NULL)
4508 {
4509 return OMX_ErrorInsufficientResources;
4510 }
4511
4512 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4513 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4514
4515 if (drv_ctx.ptr_inputbuffer == NULL)
4516 {
4517 return OMX_ErrorInsufficientResources;
4518 }
4519#ifdef USE_ION
4520 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4521 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4522
4523 if (drv_ctx.ip_buf_ion_info == NULL)
4524 {
4525 return OMX_ErrorInsufficientResources;
4526 }
4527#endif
4528
4529 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4530 {
4531 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4532#ifdef USE_ION
4533 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4534#endif
4535 }
4536 }
4537
4538 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4539 {
4540 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4541 {
4542 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4543 break;
4544 }
4545 }
4546
4547 if(i < drv_ctx.ip_buf.actualcount)
4548 {
4549 struct v4l2_buffer buf;
4550 struct v4l2_plane plane;
4551 int rc;
4552 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4553#ifdef USE_ION
4554 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4555 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4556 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4557 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, 0);
4558 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4559 return OMX_ErrorInsufficientResources;
4560 }
4561 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4562#else
4563 pmem_fd = open (MEM_DEVICE,O_RDWR);
4564
4565 if (pmem_fd < 0)
4566 {
4567 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4568 return OMX_ErrorInsufficientResources;
4569 }
4570
4571 if (pmem_fd == 0)
4572 {
4573 pmem_fd = open (MEM_DEVICE,O_RDWR);
4574
4575 if (pmem_fd < 0)
4576 {
4577 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4578 return OMX_ErrorInsufficientResources;
4579 }
4580 }
4581
4582 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4583 drv_ctx.ip_buf.alignment))
4584 {
4585 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4586 close(pmem_fd);
4587 return OMX_ErrorInsufficientResources;
4588 }
4589#endif
4590 if (!secure_mode) {
4591 buf_addr = (unsigned char *)mmap(NULL,
4592 drv_ctx.ip_buf.buffer_size,
4593 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4594
4595 if (buf_addr == MAP_FAILED)
4596 {
4597 close(pmem_fd);
4598#ifdef USE_ION
4599 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4600#endif
4601 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4602 return OMX_ErrorInsufficientResources;
4603 }
4604 }
4605 *bufferHdr = (m_inp_mem_ptr + i);
4606 if (secure_mode)
4607 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4608 else
4609 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4610 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4611 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4612 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4613 drv_ctx.ptr_inputbuffer [i].offset = 0;
4614
4615
4616 buf.index = i;
4617 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4618 buf.memory = V4L2_MEMORY_USERPTR;
4619 plane.bytesused = 0;
4620 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4621 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4622 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4623 plane.reserved[1] = 0;
4624 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4625 buf.m.planes = &plane;
4626 buf.length = 1;
4627
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004628 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 -07004629
4630 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4631
4632 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004633 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004634 /*TODO: How to handle this case */
4635 return OMX_ErrorInsufficientResources;
4636 }
4637
4638 input = *bufferHdr;
4639 BITMASK_SET(&m_inp_bm_count,i);
4640 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4641 if (secure_mode)
4642 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4643 else
4644 input->pBuffer = (OMX_U8 *)buf_addr;
4645 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4646 input->nVersion.nVersion = OMX_SPEC_VERSION;
4647 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4648 input->pAppPrivate = appData;
4649 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4650 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4651
4652 if (drv_ctx.disable_dmx)
4653 {
4654 eRet = allocate_desc_buffer(i);
4655 }
4656 }
4657 else
4658 {
4659 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4660 eRet = OMX_ErrorInsufficientResources;
4661 }
4662 return eRet;
4663}
4664
4665
4666/* ======================================================================
4667FUNCTION
4668 omx_vdec::AllocateOutputBuffer
4669
4670DESCRIPTION
4671 Helper fn for AllocateBuffer in the output pin
4672
4673PARAMETERS
4674 <TBD>.
4675
4676RETURN VALUE
4677 OMX Error None if everything went well.
4678
4679========================================================================== */
4680OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4681 OMX_IN OMX_HANDLETYPE hComp,
4682 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4683 OMX_IN OMX_U32 port,
4684 OMX_IN OMX_PTR appData,
4685 OMX_IN OMX_U32 bytes)
4686{
4687 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4688 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4689 unsigned i= 0; // Temporary counter
4690 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4691 struct vdec_setbuffer_cmd setbuffers;
4692#ifdef USE_ION
4693 int ion_device_fd =-1;
4694 struct ion_allocation_data ion_alloc_data;
4695 struct ion_fd_data fd_ion_data;
4696#endif
4697 if(!m_out_mem_ptr)
4698 {
4699 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4700 drv_ctx.op_buf.actualcount,
4701 drv_ctx.op_buf.buffer_size);
4702 int nBufHdrSize = 0;
4703 int nPlatformEntrySize = 0;
4704 int nPlatformListSize = 0;
4705 int nPMEMInfoSize = 0;
4706 int pmem_fd = -1;
4707 unsigned char *pmem_baseaddress = NULL;
4708
4709 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4710 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4711 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4712
4713 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4714 drv_ctx.op_buf.actualcount);
4715 nBufHdrSize = drv_ctx.op_buf.actualcount *
4716 sizeof(OMX_BUFFERHEADERTYPE);
4717
4718 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4719 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4720 nPlatformListSize = drv_ctx.op_buf.actualcount *
4721 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4722 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4723 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4724
4725 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4726 sizeof(OMX_BUFFERHEADERTYPE),
4727 nPMEMInfoSize,
4728 nPlatformListSize);
4729 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4730 drv_ctx.op_buf.actualcount);
4731#ifdef USE_ION
4732 ion_device_fd = alloc_map_ion_memory(
4733 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4734 drv_ctx.op_buf.alignment,
4735 &ion_alloc_data, &fd_ion_data, 0);
4736 if (ion_device_fd < 0) {
4737 return OMX_ErrorInsufficientResources;
4738 }
4739 pmem_fd = fd_ion_data.fd;
4740#else
4741 pmem_fd = open (MEM_DEVICE,O_RDWR);
4742
4743 if (pmem_fd < 0)
4744 {
4745 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4746 drv_ctx.op_buf.buffer_size);
4747 return OMX_ErrorInsufficientResources;
4748 }
4749
4750 if(pmem_fd == 0)
4751 {
4752 pmem_fd = open (MEM_DEVICE,O_RDWR);
4753
4754 if (pmem_fd < 0)
4755 {
4756 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4757 drv_ctx.op_buf.buffer_size);
4758 return OMX_ErrorInsufficientResources;
4759 }
4760 }
4761
4762 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4763 drv_ctx.op_buf.actualcount,
4764 drv_ctx.op_buf.alignment))
4765 {
4766 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4767 close(pmem_fd);
4768 return OMX_ErrorInsufficientResources;
4769 }
4770#endif
4771 if (!secure_mode) {
4772 pmem_baseaddress = (unsigned char *)mmap(NULL,
4773 (drv_ctx.op_buf.buffer_size *
4774 drv_ctx.op_buf.actualcount),
4775 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4776 if (pmem_baseaddress == MAP_FAILED)
4777 {
4778 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4779 drv_ctx.op_buf.buffer_size);
4780 close(pmem_fd);
4781#ifdef USE_ION
4782 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4783#endif
4784 return OMX_ErrorInsufficientResources;
4785 }
4786 }
4787 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4788 // Alloc mem for platform specific info
4789 char *pPtr=NULL;
4790 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4791 nPMEMInfoSize,1);
4792 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4793 calloc (sizeof(struct vdec_bufferpayload),
4794 drv_ctx.op_buf.actualcount);
4795 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4796 calloc (sizeof (struct vdec_output_frameinfo),
4797 drv_ctx.op_buf.actualcount);
4798#ifdef USE_ION
4799 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4800 calloc (sizeof(struct vdec_ion),
4801 drv_ctx.op_buf.actualcount);
4802#endif
4803
4804 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4805 && drv_ctx.ptr_respbuffer)
4806 {
4807 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4808 (drv_ctx.op_buf.buffer_size *
4809 drv_ctx.op_buf.actualcount);
4810 bufHdr = m_out_mem_ptr;
4811 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4812 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4813 (((char *) m_platform_list) + nPlatformListSize);
4814 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4815 (((char *) m_platform_entry) + nPlatformEntrySize);
4816 pPlatformList = m_platform_list;
4817 pPlatformEntry = m_platform_entry;
4818 pPMEMInfo = m_pmem_info;
4819
4820 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4821
4822 // Settting the entire storage nicely
4823 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4824 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4825 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
4826 {
4827 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4828 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4829 // Set the values when we determine the right HxW param
4830 bufHdr->nAllocLen = bytes;
4831 bufHdr->nFilledLen = 0;
4832 bufHdr->pAppPrivate = appData;
4833 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4834 // Platform specific PMEM Information
4835 // Initialize the Platform Entry
4836 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4837 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4838 pPlatformEntry->entry = pPMEMInfo;
4839 // Initialize the Platform List
4840 pPlatformList->nEntries = 1;
4841 pPlatformList->entryList = pPlatformEntry;
4842 // Keep pBuffer NULL till vdec is opened
4843 bufHdr->pBuffer = NULL;
4844 bufHdr->nOffset = 0;
4845
4846 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4847 pPMEMInfo->pmem_fd = 0;
4848 bufHdr->pPlatformPrivate = pPlatformList;
4849
4850 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4851#ifdef USE_ION
4852 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4853 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4854 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4855#endif
4856
4857 /*Create a mapping between buffers*/
4858 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4859 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4860 &drv_ctx.ptr_outputbuffer[i];
4861 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4862 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4863 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4864
4865 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4866 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4867 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4868 // Move the buffer and buffer header pointers
4869 bufHdr++;
4870 pPMEMInfo++;
4871 pPlatformEntry++;
4872 pPlatformList++;
4873 }
4874 }
4875 else
4876 {
4877 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
4878 m_out_mem_ptr, pPtr);
4879 if(m_out_mem_ptr)
4880 {
4881 free(m_out_mem_ptr);
4882 m_out_mem_ptr = NULL;
4883 }
4884 if(pPtr)
4885 {
4886 free(pPtr);
4887 pPtr = NULL;
4888 }
4889 if(drv_ctx.ptr_outputbuffer)
4890 {
4891 free(drv_ctx.ptr_outputbuffer);
4892 drv_ctx.ptr_outputbuffer = NULL;
4893 }
4894 if(drv_ctx.ptr_respbuffer)
4895 {
4896 free(drv_ctx.ptr_respbuffer);
4897 drv_ctx.ptr_respbuffer = NULL;
4898 }
4899#ifdef USE_ION
4900 if (drv_ctx.op_buf_ion_info) {
4901 DEBUG_PRINT_LOW("\n Free o/p ion context");
4902 free(drv_ctx.op_buf_ion_info);
4903 drv_ctx.op_buf_ion_info = NULL;
4904 }
4905#endif
4906 eRet = OMX_ErrorInsufficientResources;
4907 }
4908 }
4909
4910 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
4911 {
4912 if(BITMASK_ABSENT(&m_out_bm_count,i))
4913 {
4914 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4915 break;
4916 }
4917 }
4918
4919 if (eRet == OMX_ErrorNone)
4920 {
4921 if(i < drv_ctx.op_buf.actualcount)
4922 {
4923 struct v4l2_buffer buf;
4924 struct v4l2_plane plane;
4925 int rc;
4926 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4927
4928 drv_ctx.ptr_outputbuffer[i].buffer_len =
4929 drv_ctx.op_buf.buffer_size;
4930
4931 *bufferHdr = (m_out_mem_ptr + i );
4932 if (secure_mode) {
4933 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4934 }
4935 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4936
4937 buf.index = i;
4938 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4939 buf.memory = V4L2_MEMORY_USERPTR;
4940 plane.length = drv_ctx.op_buf.buffer_size;
4941 plane.m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[i].bufferaddr-drv_ctx.ptr_outputbuffer[i].offset);
4942#ifdef USE_ION
4943 plane.reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4944#endif
4945 plane.reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4946 plane.data_offset = 0;
4947 buf.m.planes = &plane;
4948 buf.length = 1;
4949
4950 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4951 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4952 if (rc) {
4953 /*TODO: How to handle this case */
4954 return OMX_ErrorInsufficientResources;
4955 }
4956
4957 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4958 enum v4l2_buf_type buf_type;
4959 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4960 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4961 if (rc) {
4962 return OMX_ErrorInsufficientResources;
4963 } else {
4964 streaming[CAPTURE_PORT] = true;
4965 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4966 }
4967 }
4968
4969 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4970 (*bufferHdr)->pAppPrivate = appData;
4971 BITMASK_SET(&m_out_bm_count,i);
4972 }
4973 else
4974 {
4975 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4976 eRet = OMX_ErrorInsufficientResources;
4977 }
4978 }
4979
4980 return eRet;
4981}
4982
4983
4984// AllocateBuffer -- API Call
4985/* ======================================================================
4986FUNCTION
4987 omx_vdec::AllocateBuffer
4988
4989DESCRIPTION
4990 Returns zero if all the buffers released..
4991
4992PARAMETERS
4993 None.
4994
4995RETURN VALUE
4996 true/false
4997
4998========================================================================== */
4999OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5000 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5001 OMX_IN OMX_U32 port,
5002 OMX_IN OMX_PTR appData,
5003 OMX_IN OMX_U32 bytes)
5004{
5005 unsigned i = 0;
5006 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5007
5008 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5009 if(m_state == OMX_StateInvalid)
5010 {
5011 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5012 return OMX_ErrorInvalidState;
5013 }
5014
5015 if(port == OMX_CORE_INPUT_PORT_INDEX)
5016 {
5017 if (arbitrary_bytes)
5018 {
5019 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5020 }
5021 else
5022 {
5023 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5024 }
5025 }
5026 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5027 {
5028 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
5029 }
5030 else
5031 {
5032 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5033 eRet = OMX_ErrorBadPortIndex;
5034 }
5035 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5036 if(eRet == OMX_ErrorNone)
5037 {
5038 if(allocate_done()){
5039 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5040 {
5041 // Send the callback now
5042 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5043 post_event(OMX_CommandStateSet,OMX_StateIdle,
5044 OMX_COMPONENT_GENERATE_EVENT);
5045 }
5046 }
5047 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5048 {
5049 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5050 {
5051 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5052 post_event(OMX_CommandPortEnable,
5053 OMX_CORE_INPUT_PORT_INDEX,
5054 OMX_COMPONENT_GENERATE_EVENT);
5055 }
5056 }
5057 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5058 {
5059 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5060 {
5061 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5062 post_event(OMX_CommandPortEnable,
5063 OMX_CORE_OUTPUT_PORT_INDEX,
5064 OMX_COMPONENT_GENERATE_EVENT);
5065 }
5066 }
5067 }
5068 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5069 return eRet;
5070}
5071
5072// Free Buffer - API call
5073/* ======================================================================
5074FUNCTION
5075 omx_vdec::FreeBuffer
5076
5077DESCRIPTION
5078
5079PARAMETERS
5080 None.
5081
5082RETURN VALUE
5083 true/false
5084
5085========================================================================== */
5086OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5087 OMX_IN OMX_U32 port,
5088 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5089{
5090 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5091 unsigned int nPortIndex;
5092 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5093
5094 if(m_state == OMX_StateIdle &&
5095 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5096 {
5097 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5098 }
5099 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5100 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5101 {
5102 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
5103 }
5104 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5105 {
5106 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5107 post_event(OMX_EventError,
5108 OMX_ErrorPortUnpopulated,
5109 OMX_COMPONENT_GENERATE_EVENT);
5110
5111 return OMX_ErrorIncorrectStateOperation;
5112 }
5113 else if (m_state != OMX_StateInvalid)
5114 {
5115 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5116 post_event(OMX_EventError,
5117 OMX_ErrorPortUnpopulated,
5118 OMX_COMPONENT_GENERATE_EVENT);
5119 }
5120
5121 if(port == OMX_CORE_INPUT_PORT_INDEX)
5122 {
5123 /*Check if arbitrary bytes*/
5124 if(!arbitrary_bytes && !input_use_buffer)
5125 nPortIndex = buffer - m_inp_mem_ptr;
5126 else
5127 nPortIndex = buffer - m_inp_heap_ptr;
5128
5129 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5130 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5131 {
5132 // Clear the bit associated with it.
5133 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5134 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5135 if (input_use_buffer == true)
5136 {
5137
5138 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5139 if(m_phdr_pmem_ptr)
5140 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5141 }
5142 else
5143 {
5144 if (arbitrary_bytes)
5145 {
5146 if(m_phdr_pmem_ptr)
5147 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5148 else
5149 free_input_buffer(nPortIndex,NULL);
5150 }
5151 else
5152 free_input_buffer(buffer);
5153 }
5154 m_inp_bPopulated = OMX_FALSE;
5155 /*Free the Buffer Header*/
5156 if (release_input_done())
5157 {
5158 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5159 free_input_buffer_header();
5160 }
5161 }
5162 else
5163 {
5164 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5165 eRet = OMX_ErrorBadPortIndex;
5166 }
5167
5168 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5169 && release_input_done())
5170 {
5171 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5172 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5173 post_event(OMX_CommandPortDisable,
5174 OMX_CORE_INPUT_PORT_INDEX,
5175 OMX_COMPONENT_GENERATE_EVENT);
5176 }
5177 }
5178 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5179 {
5180 // check if the buffer is valid
5181 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
5182 if(nPortIndex < drv_ctx.op_buf.actualcount)
5183 {
5184 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5185 // Clear the bit associated with it.
5186 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5187 m_out_bPopulated = OMX_FALSE;
5188 free_output_buffer (buffer);
5189
5190 if (release_output_done())
5191 {
5192 free_output_buffer_header();
5193 }
5194 }
5195 else
5196 {
5197 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5198 eRet = OMX_ErrorBadPortIndex;
5199 }
5200 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5201 && release_output_done())
5202 {
5203 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5204
5205 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5206 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5207#ifdef _ANDROID_ICS_
5208 if (m_enable_android_native_buffers)
5209 {
5210 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5211 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5212 }
5213#endif
5214
5215 post_event(OMX_CommandPortDisable,
5216 OMX_CORE_OUTPUT_PORT_INDEX,
5217 OMX_COMPONENT_GENERATE_EVENT);
5218 }
5219 }
5220 else
5221 {
5222 eRet = OMX_ErrorBadPortIndex;
5223 }
5224 if((eRet == OMX_ErrorNone) &&
5225 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5226 {
5227 if(release_done())
5228 {
5229 // Send the callback now
5230 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5231 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5232 OMX_COMPONENT_GENERATE_EVENT);
5233 }
5234 }
5235 return eRet;
5236}
5237
5238
5239/* ======================================================================
5240FUNCTION
5241 omx_vdec::EmptyThisBuffer
5242
5243DESCRIPTION
5244 This routine is used to push the encoded video frames to
5245 the video decoder.
5246
5247PARAMETERS
5248 None.
5249
5250RETURN VALUE
5251 OMX Error None if everything went successful.
5252
5253========================================================================== */
5254OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5255 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5256{
5257 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5258 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5259
5260 if(m_state == OMX_StateInvalid)
5261 {
5262 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5263 return OMX_ErrorInvalidState;
5264 }
5265
5266 if (buffer == NULL)
5267 {
5268 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5269 return OMX_ErrorBadParameter;
5270 }
5271
5272 if (!m_inp_bEnabled)
5273 {
5274 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5275 return OMX_ErrorIncorrectStateOperation;
5276 }
5277
5278 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5279 {
5280 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex);
5281 return OMX_ErrorBadPortIndex;
5282 }
5283
5284#ifdef _ANDROID_
5285 if(iDivXDrmDecrypt)
5286 {
5287 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5288 if(drmErr != OMX_ErrorNone) {
5289 // this error can be ignored
5290 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5291 }
5292 }
5293#endif //_ANDROID_
5294 if (perf_flag)
5295 {
5296 if (!latency)
5297 {
5298 dec_time.stop();
5299 latency = dec_time.processing_time_us();
5300 dec_time.start();
5301 }
5302 }
5303
5304 if (arbitrary_bytes)
5305 {
5306 nBufferIndex = buffer - m_inp_heap_ptr;
5307 }
5308 else
5309 {
5310 if (input_use_buffer == true)
5311 {
5312 nBufferIndex = buffer - m_inp_heap_ptr;
5313 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5314 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5315 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5316 buffer = &m_inp_mem_ptr[nBufferIndex];
5317 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d",
5318 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5319 }
5320 else{
5321 nBufferIndex = buffer - m_inp_mem_ptr;
5322 }
5323 }
5324
5325 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5326 {
5327 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5328 return OMX_ErrorBadParameter;
5329 }
5330
5331 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5332 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5333 if (arbitrary_bytes)
5334 {
5335 post_event ((unsigned)hComp,(unsigned)buffer,
5336 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5337 }
5338 else
5339 {
5340 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5341 set_frame_rate(buffer->nTimeStamp);
5342 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5343 }
5344 return OMX_ErrorNone;
5345}
5346
5347/* ======================================================================
5348FUNCTION
5349 omx_vdec::empty_this_buffer_proxy
5350
5351DESCRIPTION
5352 This routine is used to push the encoded video frames to
5353 the video decoder.
5354
5355PARAMETERS
5356 None.
5357
5358RETURN VALUE
5359 OMX Error None if everything went successful.
5360
5361========================================================================== */
5362OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5363 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5364{
5365 int push_cnt = 0,i=0;
5366 unsigned nPortIndex = 0;
5367 OMX_ERRORTYPE ret = OMX_ErrorNone;
5368 struct vdec_input_frameinfo frameinfo;
5369 struct vdec_bufferpayload *temp_buffer;
5370 struct vdec_ioctl_msg ioctl_msg;
5371 struct vdec_seqheader seq_header;
5372 bool port_setting_changed = true;
5373 bool not_coded_vop = false;
5374
5375 /*Should we generate a Aync error event*/
5376 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5377 {
5378 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5379 return OMX_ErrorBadParameter;
5380 }
5381
5382 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5383
5384 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5385 {
5386 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5387 nPortIndex);
5388 return OMX_ErrorBadParameter;
5389 }
5390
5391 pending_input_buffers++;
5392
5393 /* return zero length and not an EOS buffer */
5394 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5395 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5396 {
5397 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5398 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5399 OMX_COMPONENT_GENERATE_EBD);
5400 return OMX_ErrorNone;
5401 }
5402
5403
5404 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5405 mp4StreamType psBits;
5406 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5407 psBits.numBytes = buffer->nFilledLen;
5408 mp4_headerparser.parseHeader(&psBits);
5409 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5410 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5411 if(not_coded_vop) {
5412 DEBUG_PRINT_HIGH("\n Found Not coded vop len %d frame number %d",
5413 buffer->nFilledLen,frame_count);
5414 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5415 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5416 not_coded_vop = false;
5417 buffer->nFilledLen = 0;
5418 }
5419 }
5420 }
5421
5422 if(input_flush_progress == true
5423
5424 || not_coded_vop
5425
5426 )
5427 {
5428 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5429 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5430 OMX_COMPONENT_GENERATE_EBD);
5431 return OMX_ErrorNone;
5432 }
5433
5434 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5435
5436 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5437 {
5438 return OMX_ErrorBadParameter;
5439 }
5440
5441 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5442 /*for use buffer we need to memcpy the data*/
5443 temp_buffer->buffer_len = buffer->nFilledLen;
5444
5445 if (input_use_buffer)
5446 {
5447 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5448 {
5449 if(arbitrary_bytes)
5450 {
5451 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5452 }
5453 else
5454 {
5455 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5456 buffer->nFilledLen);
5457 }
5458 }
5459 else
5460 {
5461 return OMX_ErrorBadParameter;
5462 }
5463
5464 }
5465
5466 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5467 frameinfo.client_data = (void *) buffer;
5468 frameinfo.datalen = temp_buffer->buffer_len;
5469 frameinfo.flags = 0;
5470 frameinfo.offset = buffer->nOffset;
5471 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5472 frameinfo.pmem_offset = temp_buffer->offset;
5473 frameinfo.timestamp = buffer->nTimeStamp;
5474 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5475 {
5476 DEBUG_PRINT_LOW("ETB: dmx enabled");
5477 if (m_demux_entries == 0)
5478 {
5479 extract_demux_addr_offsets(buffer);
5480 }
5481
5482 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries);
5483 handle_demux_data(buffer);
5484 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5485 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5486 }
5487 else
5488 {
5489 frameinfo.desc_addr = NULL;
5490 frameinfo.desc_size = 0;
5491 }
5492 if(!arbitrary_bytes)
5493 {
5494 frameinfo.flags |= buffer->nFlags;
5495 }
5496
5497#ifdef _ANDROID_
5498 if (m_debug_timestamp)
5499 {
5500 if(arbitrary_bytes)
5501 {
5502 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5503 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5504 }
5505 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5506 {
5507 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5508 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5509 }
5510 }
5511#endif
5512
5513#ifdef INPUT_BUFFER_LOG
5514 if (inputBufferFile1)
5515 {
5516 fwrite((const char *)temp_buffer->bufferaddr,
5517 temp_buffer->buffer_len,1,inputBufferFile1);
5518 }
5519#endif
5520
5521 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5522 {
5523 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5524 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5525 }
5526
5527 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5528 {
5529 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5530 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5531 h264_scratch.nFilledLen = 0;
5532 nal_count = 0;
5533 look_ahead_nal = false;
5534 frame_count = 0;
5535 if (m_frame_parser.mutils)
5536 m_frame_parser.mutils->initialize_frame_checking_environment();
5537 m_frame_parser.flush();
5538 h264_last_au_ts = LLONG_MAX;
5539 h264_last_au_flags = 0;
5540 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5541 m_demux_entries = 0;
5542 }
5543 struct v4l2_buffer buf = {0};
5544 struct v4l2_plane plane;
5545 int rc;
5546 unsigned long print_count;
5547 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5548 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005549 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005550 }
5551 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5552 buf.index = nPortIndex;
5553 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5554 buf.memory = V4L2_MEMORY_USERPTR;
5555 plane.bytesused = temp_buffer->buffer_len;
5556 plane.length = drv_ctx.ip_buf.buffer_size;
5557 plane.m.userptr = (unsigned long)(temp_buffer->bufferaddr-temp_buffer->offset);
5558 plane.reserved[0] = temp_buffer->pmem_fd;
5559 plane.reserved[1] = temp_buffer->offset;
5560 plane.data_offset = 0;
5561 buf.m.planes = &plane;
5562 buf.length = 1;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005563 //assumption is that timestamp is in milliseconds
5564 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5565 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005566 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5567
Shalaj Jain273b3e02012-06-22 19:08:03 -07005568 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5569 if(!streaming[OUTPUT_PORT])
5570 {
5571 enum v4l2_buf_type buf_type;
5572 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005573
5574 struct v4l2_control control;
5575 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
5576 control.value = 1;
5577 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
5578 if(ret)
5579 printf("\n Continue data Xfer failed \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005580 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5581 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5582 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5583 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005584 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585 streaming[OUTPUT_PORT] = true;
5586 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
5587 if(ret < 0)
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005588 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005589 } else{
5590 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005591 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005592 }
5593}
5594 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5595 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5596 time_stamp_dts.insert_timestamp(buffer);
5597
5598 return ret;
5599}
5600
5601/* ======================================================================
5602FUNCTION
5603 omx_vdec::FillThisBuffer
5604
5605DESCRIPTION
5606 IL client uses this method to release the frame buffer
5607 after displaying them.
5608
5609PARAMETERS
5610 None.
5611
5612RETURN VALUE
5613 true/false
5614
5615========================================================================== */
5616OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5617 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5618{
5619
5620 if(m_state == OMX_StateInvalid)
5621 {
5622 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5623 return OMX_ErrorInvalidState;
5624 }
5625
5626 if (!m_out_bEnabled)
5627 {
5628 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5629 return OMX_ErrorIncorrectStateOperation;
5630 }
5631
5632 if (buffer == NULL || ((buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount))
5633 {
5634 return OMX_ErrorBadParameter;
5635 }
5636
5637 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5638 {
5639 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex);
5640 return OMX_ErrorBadPortIndex;
5641 }
5642
5643 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5644 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
5645 return OMX_ErrorNone;
5646}
5647/* ======================================================================
5648FUNCTION
5649 omx_vdec::fill_this_buffer_proxy
5650
5651DESCRIPTION
5652 IL client uses this method to release the frame buffer
5653 after displaying them.
5654
5655PARAMETERS
5656 None.
5657
5658RETURN VALUE
5659 true/false
5660
5661========================================================================== */
5662OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5663 OMX_IN OMX_HANDLETYPE hComp,
5664 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5665{
5666 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5667 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
5668 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5669 unsigned nPortIndex = 0;
5670 struct vdec_fillbuffer_cmd fillbuffer;
5671 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5672 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5673
5674 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_out_mem_ptr);
5675
5676 if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) >
5677 drv_ctx.op_buf.actualcount) )
5678 return OMX_ErrorBadParameter;
5679
5680 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5681 bufferAdd, bufferAdd->pBuffer);
5682 /*Return back the output buffer to client*/
5683 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5684 {
5685 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5686 buffer->nFilledLen = 0;
5687 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5688 return OMX_ErrorNone;
5689 }
5690 pending_output_buffers++;
5691 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5692 if (ptr_respbuffer)
5693 {
5694 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5695 }
5696
5697 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5698 {
5699 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5700 buffer->nFilledLen = 0;
5701 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5702 pending_output_buffers--;
5703 return OMX_ErrorBadParameter;
5704 }
5705
5706 // memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
5707 sizeof(struct vdec_bufferpayload));
5708 // fillbuffer.client_data = bufferAdd;
5709
5710#ifdef _ANDROID_ICS_
5711 if (m_enable_android_native_buffers)
5712 {
5713 // Acquire a write lock on this buffer.
5714 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5715 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5716 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5717 buffer->nFilledLen = 0;
5718 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5719 pending_output_buffers--;
5720 return OMX_ErrorInsufficientResources;
5721 } else {
5722 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5723 }
5724 }
5725#endif
5726 int rc = 0;
5727 struct v4l2_buffer buf={0};
5728 struct v4l2_plane plane;
5729
5730 buf.index = nPortIndex;
5731 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5732 buf.memory = V4L2_MEMORY_USERPTR;
5733 plane.bytesused = buffer->nFilledLen;
5734 plane.length = drv_ctx.op_buf.buffer_size;
5735 plane.m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr-drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5736 plane.reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5737 plane.reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5738 plane.data_offset = 0;
5739 buf.m.planes = &plane;
5740 buf.length = 1;
5741
5742 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5743 if (rc) {
5744 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005745 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005746 }
5747//#ifdef _ANDROID_ICS_
5748 // if (m_enable_android_native_buffers)
5749 // {
5750 // Unlock the buffer
5751 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
5752 // DEBUG_PRINT_ERROR("Releasing genlock failed");
5753 // return OMX_ErrorInsufficientResources;
5754 /// } else {
5755 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
5756 // }
5757 // }
5758//#endif
5759 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
5760 // pending_output_buffers--;
5761 // return OMX_ErrorBadParameter;
5762 //}
5763 return OMX_ErrorNone;
5764}
5765
5766/* ======================================================================
5767FUNCTION
5768 omx_vdec::SetCallbacks
5769
5770DESCRIPTION
5771 Set the callbacks.
5772
5773PARAMETERS
5774 None.
5775
5776RETURN VALUE
5777 OMX Error None if everything successful.
5778
5779========================================================================== */
5780OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
5781 OMX_IN OMX_CALLBACKTYPE* callbacks,
5782 OMX_IN OMX_PTR appData)
5783{
5784
5785 m_cb = *callbacks;
5786 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5787 m_cb.EventHandler,m_cb.FillBufferDone);
5788 m_app_data = appData;
5789 return OMX_ErrorNotImplemented;
5790}
5791
5792/* ======================================================================
5793FUNCTION
5794 omx_vdec::ComponentDeInit
5795
5796DESCRIPTION
5797 Destroys the component and release memory allocated to the heap.
5798
5799PARAMETERS
5800 <TBD>.
5801
5802RETURN VALUE
5803 OMX Error None if everything successful.
5804
5805========================================================================== */
5806OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5807{
5808#ifdef _ANDROID_
5809 if(iDivXDrmDecrypt)
5810 {
5811 delete iDivXDrmDecrypt;
5812 iDivXDrmDecrypt=NULL;
5813 }
5814#endif //_ANDROID_
5815
5816 int i = 0;
5817 if (OMX_StateLoaded != m_state)
5818 {
5819 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
5820 m_state);
5821 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
5822 }
5823 else
5824 {
5825 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
5826 }
5827
5828 /*Check if the output buffers have to be cleaned up*/
5829 if(m_out_mem_ptr)
5830 {
5831 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
5832 for (i=0; i < drv_ctx.op_buf.actualcount; i++ )
5833 {
5834 free_output_buffer (&m_out_mem_ptr[i]);
5835#ifdef _ANDROID_ICS_
5836 if (m_enable_android_native_buffers)
5837 {
5838 if (native_buffer[i].inuse)
5839 {
5840 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
5841 DEBUG_PRINT_ERROR("Unlocking genlock failed");
5842 }
5843 native_buffer[i].inuse = false;
5844 }
5845 }
5846#endif
5847 }
5848#ifdef _ANDROID_ICS_
5849 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5850#endif
5851 }
5852
5853 /*Check if the input buffers have to be cleaned up*/
5854 if(m_inp_mem_ptr || m_inp_heap_ptr)
5855 {
5856 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
5857 for (i=0; i<drv_ctx.ip_buf.actualcount; i++ )
5858 {
5859 if (m_inp_mem_ptr)
5860 free_input_buffer (i,&m_inp_mem_ptr[i]);
5861 else
5862 free_input_buffer (i,NULL);
5863 }
5864 }
5865 free_input_buffer_header();
5866 free_output_buffer_header();
5867 if(h264_scratch.pBuffer)
5868 {
5869 free(h264_scratch.pBuffer);
5870 h264_scratch.pBuffer = NULL;
5871 }
5872
5873 if (h264_parser)
5874 {
5875 delete h264_parser;
5876 h264_parser = NULL;
5877 }
5878
5879 if(m_platform_list)
5880 {
5881 free(m_platform_list);
5882 m_platform_list = NULL;
5883 }
5884 if(m_vendor_config.pData)
5885 {
5886 free(m_vendor_config.pData);
5887 m_vendor_config.pData = NULL;
5888 }
5889
5890 // Reset counters in mesg queues
5891 m_ftb_q.m_size=0;
5892 m_cmd_q.m_size=0;
5893 m_etb_q.m_size=0;
5894 m_ftb_q.m_read = m_ftb_q.m_write =0;
5895 m_cmd_q.m_read = m_cmd_q.m_write =0;
5896 m_etb_q.m_read = m_etb_q.m_write =0;
5897#ifdef _ANDROID_
5898 if (m_debug_timestamp)
5899 {
5900 m_timestamp_list.reset_ts_list();
5901 }
5902#endif
5903
5904 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5905 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
5906 // NULL);
5907 DEBUG_PRINT_HIGH("\n Close the driver instance");
5908
5909#ifdef INPUT_BUFFER_LOG
5910 fclose (inputBufferFile1);
5911#endif
5912#ifdef OUTPUT_BUFFER_LOG
5913 fclose (outputBufferFile1);
5914#endif
5915#ifdef OUTPUT_EXTRADATA_LOG
5916 fclose (outputExtradataFile);
5917#endif
5918 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5919 return OMX_ErrorNone;
5920}
5921
5922/* ======================================================================
5923FUNCTION
5924 omx_vdec::UseEGLImage
5925
5926DESCRIPTION
5927 OMX Use EGL Image method implementation <TBD>.
5928
5929PARAMETERS
5930 <TBD>.
5931
5932RETURN VALUE
5933 Not Implemented error.
5934
5935========================================================================== */
5936OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
5937 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5938 OMX_IN OMX_U32 port,
5939 OMX_IN OMX_PTR appData,
5940 OMX_IN void* eglImage)
5941{
5942 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5943 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5944 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
5945
5946#ifdef USE_EGL_IMAGE_GPU
5947 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5948 EGLint fd = -1, offset = 0,pmemPtr = 0;
5949#else
5950 int fd = -1, offset = 0;
5951#endif
5952 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5953 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5954 DEBUG_PRINT_ERROR("\n ");
5955 }
5956#ifdef USE_EGL_IMAGE_GPU
5957 if(m_display_id == NULL) {
5958 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5959 return OMX_ErrorInsufficientResources;
5960 }
5961 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5962 eglGetProcAddress("eglQueryImageKHR");
5963 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5964 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5965 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
5966#else //with OMX test app
5967 struct temp_egl {
5968 int pmem_fd;
5969 int offset;
5970 };
5971 struct temp_egl *temp_egl_id = NULL;
5972 void * pmemPtr = (void *) eglImage;
5973 temp_egl_id = (struct temp_egl *)eglImage;
5974 if (temp_egl_id != NULL)
5975 {
5976 fd = temp_egl_id->pmem_fd;
5977 offset = temp_egl_id->offset;
5978 }
5979#endif
5980 if (fd < 0) {
5981 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5982 return OMX_ErrorInsufficientResources;
5983 }
5984 pmem_info.pmem_fd = (OMX_U32) fd;
5985 pmem_info.offset = (OMX_U32) offset;
5986 pmem_entry.entry = (void *) &pmem_info;
5987 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5988 pmem_list.entryList = &pmem_entry;
5989 pmem_list.nEntries = 1;
5990 ouput_egl_buffers = true;
5991 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5992 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5993 (OMX_U8 *)pmemPtr)) {
5994 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5995 return OMX_ErrorInsufficientResources;
5996 }
5997 return OMX_ErrorNone;
5998}
5999
6000/* ======================================================================
6001FUNCTION
6002 omx_vdec::ComponentRoleEnum
6003
6004DESCRIPTION
6005 OMX Component Role Enum method implementation.
6006
6007PARAMETERS
6008 <TBD>.
6009
6010RETURN VALUE
6011 OMX Error None if everything is successful.
6012========================================================================== */
6013OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6014 OMX_OUT OMX_U8* role,
6015 OMX_IN OMX_U32 index)
6016{
6017 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6018
6019 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6020 {
6021 if((0 == index) && role)
6022 {
6023 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6024 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6025 }
6026 else
6027 {
6028 eRet = OMX_ErrorNoMore;
6029 }
6030 }
6031 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6032 {
6033 if((0 == index) && role)
6034 {
6035 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6036 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6037 }
6038 else
6039 {
6040 eRet = OMX_ErrorNoMore;
6041 }
6042 }
6043 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6044 {
6045 if((0 == index) && role)
6046 {
6047 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6048 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6049 }
6050 else
6051 {
6052 DEBUG_PRINT_LOW("\n No more roles \n");
6053 eRet = OMX_ErrorNoMore;
6054 }
6055 }
6056
6057 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6058 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6059 )
6060
6061 {
6062 if((0 == index) && role)
6063 {
6064 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6065 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6066 }
6067 else
6068 {
6069 DEBUG_PRINT_LOW("\n No more roles \n");
6070 eRet = OMX_ErrorNoMore;
6071 }
6072 }
6073 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6074 {
6075 if((0 == index) && role)
6076 {
6077 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6078 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6079 }
6080 else
6081 {
6082 DEBUG_PRINT_LOW("\n No more roles \n");
6083 eRet = OMX_ErrorNoMore;
6084 }
6085 }
6086 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6087 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6088 )
6089 {
6090 if((0 == index) && role)
6091 {
6092 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6093 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6094 }
6095 else
6096 {
6097 DEBUG_PRINT_LOW("\n No more roles \n");
6098 eRet = OMX_ErrorNoMore;
6099 }
6100 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006101 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6102 {
6103 if((0 == index) && role)
6104 {
6105 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6106 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6107 }
6108 else
6109 {
6110 DEBUG_PRINT_LOW("\n No more roles \n");
6111 eRet = OMX_ErrorNoMore;
6112 }
6113 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006114 else
6115 {
6116 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6117 eRet = OMX_ErrorInvalidComponentName;
6118 }
6119 return eRet;
6120}
6121
6122
6123
6124
6125/* ======================================================================
6126FUNCTION
6127 omx_vdec::AllocateDone
6128
6129DESCRIPTION
6130 Checks if entire buffer pool is allocated by IL Client or not.
6131 Need this to move to IDLE state.
6132
6133PARAMETERS
6134 None.
6135
6136RETURN VALUE
6137 true/false.
6138
6139========================================================================== */
6140bool omx_vdec::allocate_done(void)
6141{
6142 bool bRet = false;
6143 bool bRet_In = false;
6144 bool bRet_Out = false;
6145
6146 bRet_In = allocate_input_done();
6147 bRet_Out = allocate_output_done();
6148
6149 if(bRet_In && bRet_Out)
6150 {
6151 bRet = true;
6152 }
6153
6154 return bRet;
6155}
6156/* ======================================================================
6157FUNCTION
6158 omx_vdec::AllocateInputDone
6159
6160DESCRIPTION
6161 Checks if I/P buffer pool is allocated by IL Client or not.
6162
6163PARAMETERS
6164 None.
6165
6166RETURN VALUE
6167 true/false.
6168
6169========================================================================== */
6170bool omx_vdec::allocate_input_done(void)
6171{
6172 bool bRet = false;
6173 unsigned i=0;
6174
6175 if (m_inp_mem_ptr == NULL)
6176 {
6177 return bRet;
6178 }
6179 if(m_inp_mem_ptr )
6180 {
6181 for(;i<drv_ctx.ip_buf.actualcount;i++)
6182 {
6183 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6184 {
6185 break;
6186 }
6187 }
6188 }
6189 if(i == drv_ctx.ip_buf.actualcount)
6190 {
6191 bRet = true;
6192 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6193 }
6194 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6195 {
6196 m_inp_bPopulated = OMX_TRUE;
6197 }
6198 return bRet;
6199}
6200/* ======================================================================
6201FUNCTION
6202 omx_vdec::AllocateOutputDone
6203
6204DESCRIPTION
6205 Checks if entire O/P buffer pool is allocated by IL Client or not.
6206
6207PARAMETERS
6208 None.
6209
6210RETURN VALUE
6211 true/false.
6212
6213========================================================================== */
6214bool omx_vdec::allocate_output_done(void)
6215{
6216 bool bRet = false;
6217 unsigned j=0;
6218
6219 if (m_out_mem_ptr == NULL)
6220 {
6221 return bRet;
6222 }
6223
6224 if (m_out_mem_ptr)
6225 {
6226 for(;j < drv_ctx.op_buf.actualcount;j++)
6227 {
6228 if(BITMASK_ABSENT(&m_out_bm_count,j))
6229 {
6230 break;
6231 }
6232 }
6233 }
6234
6235 if(j == drv_ctx.op_buf.actualcount)
6236 {
6237 bRet = true;
6238 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6239 if(m_out_bEnabled)
6240 m_out_bPopulated = OMX_TRUE;
6241 }
6242
6243 return bRet;
6244}
6245
6246/* ======================================================================
6247FUNCTION
6248 omx_vdec::ReleaseDone
6249
6250DESCRIPTION
6251 Checks if IL client has released all the buffers.
6252
6253PARAMETERS
6254 None.
6255
6256RETURN VALUE
6257 true/false
6258
6259========================================================================== */
6260bool omx_vdec::release_done(void)
6261{
6262 bool bRet = false;
6263
6264 if(release_input_done())
6265 {
6266 if(release_output_done())
6267 {
6268 bRet = true;
6269 }
6270 }
6271 return bRet;
6272}
6273
6274
6275/* ======================================================================
6276FUNCTION
6277 omx_vdec::ReleaseOutputDone
6278
6279DESCRIPTION
6280 Checks if IL client has released all the buffers.
6281
6282PARAMETERS
6283 None.
6284
6285RETURN VALUE
6286 true/false
6287
6288========================================================================== */
6289bool omx_vdec::release_output_done(void)
6290{
6291 bool bRet = false;
6292 unsigned i=0,j=0;
6293
6294 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6295 if(m_out_mem_ptr)
6296 {
6297 for(;j < drv_ctx.op_buf.actualcount ; j++)
6298 {
6299 if(BITMASK_PRESENT(&m_out_bm_count,j))
6300 {
6301 break;
6302 }
6303 }
6304 if(j == drv_ctx.op_buf.actualcount)
6305 {
6306 m_out_bm_count = 0;
6307 bRet = true;
6308 }
6309 }
6310 else
6311 {
6312 m_out_bm_count = 0;
6313 bRet = true;
6314 }
6315 return bRet;
6316}
6317/* ======================================================================
6318FUNCTION
6319 omx_vdec::ReleaseInputDone
6320
6321DESCRIPTION
6322 Checks if IL client has released all the buffers.
6323
6324PARAMETERS
6325 None.
6326
6327RETURN VALUE
6328 true/false
6329
6330========================================================================== */
6331bool omx_vdec::release_input_done(void)
6332{
6333 bool bRet = false;
6334 unsigned i=0,j=0;
6335
6336 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6337 if(m_inp_mem_ptr)
6338 {
6339 for(;j<drv_ctx.ip_buf.actualcount;j++)
6340 {
6341 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6342 {
6343 break;
6344 }
6345 }
6346 if(j==drv_ctx.ip_buf.actualcount)
6347 {
6348 bRet = true;
6349 }
6350 }
6351 else
6352 {
6353 bRet = true;
6354 }
6355 return bRet;
6356}
6357
6358OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6359 OMX_BUFFERHEADERTYPE * buffer)
6360{
6361 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6362 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6363 {
6364 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6365 return OMX_ErrorBadParameter;
6366 }
6367 else if (output_flush_progress)
6368 {
6369 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6370 buffer->nFilledLen = 0;
6371 buffer->nTimeStamp = 0;
6372 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6373 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6374 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6375 }
6376
6377 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6378 buffer, buffer->pBuffer);
6379 pending_output_buffers --;
6380
6381 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6382 {
6383 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6384 if (!output_flush_progress)
6385 post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE);
6386
6387 if (psource_frame)
6388 {
6389 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6390 psource_frame = NULL;
6391 }
6392 if (pdest_frame)
6393 {
6394 pdest_frame->nFilledLen = 0;
6395 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6396 pdest_frame = NULL;
6397 }
6398 }
6399
6400 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6401#ifdef OUTPUT_BUFFER_LOG
6402 if (outputBufferFile1)
6403 {
6404 fwrite (buffer->pBuffer,1,buffer->nFilledLen,
6405 outputBufferFile1);
6406 }
6407#endif
6408
6409 /* For use buffer we need to copy the data */
6410 if (!output_flush_progress)
6411 {
6412 time_stamp_dts.get_next_timestamp(buffer,
6413 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6414 ?true:false);
6415 }
6416 if (m_cb.FillBufferDone)
6417 {
6418 if (buffer->nFilledLen > 0)
6419 {
Vinay Kalia46b59ef2012-08-03 18:07:17 -07006420 /*if (client_extradata)
6421 handle_extradata(buffer);*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07006422 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6423 // Keep min timestamp interval to handle corrupted bit stream scenario
6424 set_frame_rate(buffer->nTimeStamp);
6425 else if (arbitrary_bytes)
6426 adjust_timestamp(buffer->nTimeStamp);
6427 if (perf_flag)
6428 {
6429 if (!proc_frms)
6430 {
6431 dec_time.stop();
6432 latency = dec_time.processing_time_us() - latency;
6433 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6434 dec_time.start();
6435 fps_metrics.start();
6436 }
6437 proc_frms++;
6438 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6439 {
6440 OMX_U64 proc_time = 0;
6441 fps_metrics.stop();
6442 proc_time = fps_metrics.processing_time_us();
6443 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6444 proc_frms, (float)proc_time / 1e6,
6445 (float)(1e6 * proc_frms) / proc_time);
6446 proc_frms = 0;
6447 }
6448 }
6449
6450#ifdef OUTPUT_EXTRADATA_LOG
6451 if (outputExtradataFile)
6452 {
6453
6454 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6455 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6456 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6457 buffer->nFilledLen + 3)&(~3));
6458 while(p_extra &&
6459 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6460 {
6461 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6462 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6463 if (p_extra->eType == OMX_ExtraDataNone)
6464 {
6465 break;
6466 }
6467 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6468 }
6469 }
6470#endif
6471 }
6472 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6473 prev_ts = LLONG_MAX;
6474 rst_prev_ts = true;
6475 }
6476
6477 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6478 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6479 buffer->pPlatformPrivate)->entryList->entry;
6480 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
6481#ifdef _ANDROID_ICS_
6482 if (m_enable_android_native_buffers)
6483 {
6484 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6485 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6486 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6487 return OMX_ErrorInsufficientResources;
6488 }
6489 else {
6490 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6491 }
6492 }
6493 }
6494#endif
6495 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6496 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
6497 }
6498 else
6499 {
6500 return OMX_ErrorBadParameter;
6501 }
6502
6503 return OMX_ErrorNone;
6504}
6505
6506OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6507 OMX_BUFFERHEADERTYPE* buffer)
6508{
6509
6510 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6511 {
6512 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6513 return OMX_ErrorBadParameter;
6514 }
6515
6516 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6517 buffer, buffer->pBuffer);
6518 pending_input_buffers--;
6519
6520 if (arbitrary_bytes)
6521 {
6522 if (pdest_frame == NULL && input_flush_progress == false)
6523 {
6524 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6525 pdest_frame = buffer;
6526 buffer->nFilledLen = 0;
6527 buffer->nTimeStamp = LLONG_MAX;
6528 push_input_buffer (hComp);
6529 }
6530 else
6531 {
6532 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6533 buffer->nFilledLen = 0;
6534 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
6535 {
6536 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6537 }
6538 }
6539 }
6540 else if(m_cb.EmptyBufferDone)
6541 {
6542 buffer->nFilledLen = 0;
6543 if (input_use_buffer == true){
6544 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6545 }
6546 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6547 }
6548 return OMX_ErrorNone;
6549}
6550
6551
6552int omx_vdec::async_message_process (void *context, void* message)
6553{
6554 omx_vdec* omx = NULL;
6555 struct vdec_msginfo *vdec_msg = NULL;
6556 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6557 struct v4l2_buffer *v4l2_buf_ptr=NULL;
6558 struct vdec_output_frameinfo *output_respbuf = NULL;
6559 int rc=1;
6560 if (context == NULL || message == NULL)
6561 {
6562 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6563 return -1;
6564 }
6565 vdec_msg = (struct vdec_msginfo *)message;
6566
6567 omx = reinterpret_cast<omx_vdec*>(context);
6568
6569#ifdef _ANDROID_
6570 if (omx->m_debug_timestamp)
6571 {
6572 if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) &&
6573 !(omx->output_flush_progress) )
6574 {
6575 OMX_TICKS expected_ts = 0;
6576 omx->m_timestamp_list.pop_min_ts(expected_ts);
6577 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6578 vdec_msg->msgdata.output_frame.time_stamp, expected_ts);
6579
6580 if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts)
6581 {
6582 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6583 }
6584 }
6585 }
6586#endif
6587
6588 switch (vdec_msg->msgcode)
6589 {
6590
6591 case VDEC_MSG_EVT_HW_ERROR:
6592 omx->post_event (NULL,vdec_msg->status_code,\
6593 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6594 break;
6595
6596 case VDEC_MSG_RESP_START_DONE:
6597 omx->post_event (NULL,vdec_msg->status_code,\
6598 OMX_COMPONENT_GENERATE_START_DONE);
6599 break;
6600
6601 case VDEC_MSG_RESP_STOP_DONE:
6602 omx->post_event (NULL,vdec_msg->status_code,\
6603 OMX_COMPONENT_GENERATE_STOP_DONE);
6604 break;
6605
6606 case VDEC_MSG_RESP_RESUME_DONE:
6607 omx->post_event (NULL,vdec_msg->status_code,\
6608 OMX_COMPONENT_GENERATE_RESUME_DONE);
6609 break;
6610
6611 case VDEC_MSG_RESP_PAUSE_DONE:
6612 omx->post_event (NULL,vdec_msg->status_code,\
6613 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6614 break;
6615
6616 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6617 omx->post_event (NULL,vdec_msg->status_code,\
6618 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6619 break;
6620 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07006621 if(BITMASK_PRESENT(&omx->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
6622 int rc=0;
6623 enum v4l2_buf_type btype;
6624 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6625 rc = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
6626 if (rc) {
6627 //TODO: How to handle this case /
6628 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
6629 } else {
6630 omx->streaming[OUTPUT_PORT] = false;
6631 }
6632 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6633 rc = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
6634 if (rc) {
6635 //TODO: How to handle this case /
6636 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
6637 } else {
6638 omx->streaming[CAPTURE_PORT] = false;
6639 }
6640
6641 omx->post_event (NULL,vdec_msg->status_code,\
6642 OMX_COMPONENT_GENERATE_STOP_DONE);
6643 }
6644 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07006645 omx->post_event (NULL,vdec_msg->status_code,\
6646 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6647 break;
6648 case VDEC_MSG_RESP_INPUT_FLUSHED:
6649 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6650
6651 // omxhdr = (OMX_BUFFERHEADERTYPE* ) \
6652 // vdec_msg->msgdata.input_frame_clientdata;
6653
6654 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6655 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6656 if (omxhdr == NULL ||
6657 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6658 {
6659 omxhdr = NULL;
6660 vdec_msg->status_code = VDEC_S_EFATAL;
6661 }
6662
6663 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6664 OMX_COMPONENT_GENERATE_EBD);
6665 break;
6666 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6667 int64_t *timestamp;
6668 timestamp = (int64_t *) malloc(sizeof(int64_t));
6669 if (timestamp) {
6670 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6671 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6672 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6673 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6674 vdec_msg->msgdata.output_frame.time_stamp);
6675 }
6676 break;
6677 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6678 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6679
6680 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6681 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6682 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6683 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6684 vdec_msg->msgdata.output_frame.pic_type);
6685
6686 if (omxhdr && omxhdr->pOutputPortPrivate &&
6687 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6688 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6689 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6690 {
6691 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6692 {
6693 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6694 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006695 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006696 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6697
6698 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6699 {
6700 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6701 //rc = -1;
6702 }
6703 vdec_msg->msgdata.output_frame.bufferaddr=omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6704 output_respbuf = (struct vdec_output_frameinfo *)\
6705 omxhdr->pOutputPortPrivate;
6706 // output_respbuf->framesize.bottom =
6707 // vdec_msg->msgdata.output_frame.framesize.bottom;
6708 // output_respbuf->framesize.left =
6709 // vdec_msg->msgdata.output_frame.framesize.left;
6710 // output_respbuf->framesize.right =
6711 // vdec_msg->msgdata.output_frame.framesize.right;
6712 // output_respbuf->framesize.top =
6713 // vdec_msg->msgdata.output_frame.framesize.top;
6714 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6715 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6716 // output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp;
6717 // output_respbuf->flags = vdec_msg->msgdata.output_frame.flags;
6718 // output_respbuf->pic_type = vdec_msg->msgdata.output_frame.pic_type;
6719 // output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format;
6720
6721 if (omx->output_use_buffer)
6722 memcpy ( omxhdr->pBuffer,
6723 (vdec_msg->msgdata.output_frame.bufferaddr +
6724 vdec_msg->msgdata.output_frame.offset),
6725 vdec_msg->msgdata.output_frame.len );
6726 }
6727 else
6728 omxhdr->nFilledLen = 0;
6729 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6730 OMX_COMPONENT_GENERATE_FBD);
6731 }
6732 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6733 omx->post_event (NULL, vdec_msg->status_code,
6734 OMX_COMPONENT_GENERATE_EOS_DONE);
6735 else
6736 omx->post_event (NULL, vdec_msg->status_code,
6737 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6738 break;
6739 case VDEC_MSG_EVT_CONFIG_CHANGED:
6740 DEBUG_PRINT_HIGH("\n Port settings changed");
6741 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6742 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6743 break;
6744 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
6745 {
6746 DEBUG_PRINT_HIGH("\n Port settings changed info");
6747 // get_buffer_req and populate port defn structure
6748 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6749 omx->m_port_def.nPortIndex = 1;
6750 eRet = omx->update_portdef(&(omx->m_port_def));
6751 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6752 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
6753 break;
6754 }
6755 default:
6756 break;
6757 }
6758 return rc;
6759}
6760
6761OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
6762 OMX_HANDLETYPE hComp,
6763 OMX_BUFFERHEADERTYPE *buffer
6764 )
6765{
6766 unsigned address,p2,id;
6767 DEBUG_PRINT_LOW("\n Empty this arbitrary");
6768
6769 if (buffer == NULL)
6770 {
6771 return OMX_ErrorBadParameter;
6772 }
6773 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6774 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
6775 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
6776
6777 /* return zero length and not an EOS buffer */
6778 /* return buffer if input flush in progress */
6779 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6780 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
6781 {
6782 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6783 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6784 return OMX_ErrorNone;
6785 }
6786
6787 if (psource_frame == NULL)
6788 {
6789 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
6790 psource_frame = buffer;
6791 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6792 push_input_buffer (hComp);
6793 }
6794 else
6795 {
6796 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6797 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
6798 {
6799 return OMX_ErrorBadParameter;
6800 }
6801 }
6802
6803
6804 return OMX_ErrorNone;
6805}
6806
6807OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6808{
6809 unsigned address,p2,id;
6810 OMX_ERRORTYPE ret = OMX_ErrorNone;
6811
6812 if (pdest_frame == NULL || psource_frame == NULL)
6813 {
6814 /*Check if we have a destination buffer*/
6815 if (pdest_frame == NULL)
6816 {
6817 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6818 if (m_input_free_q.m_size)
6819 {
6820 m_input_free_q.pop_entry(&address,&p2,&id);
6821 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6822 pdest_frame->nFilledLen = 0;
6823 pdest_frame->nTimeStamp = LLONG_MAX;
6824 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6825 }
6826 }
6827
6828 /*Check if we have a destination buffer*/
6829 if (psource_frame == NULL)
6830 {
6831 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6832 if (m_input_pending_q.m_size)
6833 {
6834 m_input_pending_q.pop_entry(&address,&p2,&id);
6835 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6836 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
6837 psource_frame->nTimeStamp);
6838 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
6839 psource_frame->nFlags,psource_frame->nFilledLen);
6840
6841 }
6842 }
6843
6844 }
6845
6846 while ((pdest_frame != NULL) && (psource_frame != NULL))
6847 {
6848 switch (codec_type_parse)
6849 {
6850 case CODEC_TYPE_MPEG4:
6851 case CODEC_TYPE_H263:
6852 case CODEC_TYPE_MPEG2:
6853 ret = push_input_sc_codec(hComp);
6854 break;
6855 case CODEC_TYPE_H264:
6856 ret = push_input_h264(hComp);
6857 break;
6858 case CODEC_TYPE_VC1:
6859 ret = push_input_vc1(hComp);
6860 break;
6861 }
6862 if (ret != OMX_ErrorNone)
6863 {
6864 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6865 omx_report_error ();
6866 break;
6867 }
6868 }
6869
6870 return ret;
6871}
6872
6873OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6874{
6875 OMX_U32 partial_frame = 1;
6876 OMX_BOOL generate_ebd = OMX_TRUE;
6877 unsigned address,p2,id;
6878
6879 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
6880 psource_frame,psource_frame->nTimeStamp);
6881 if (m_frame_parser.parse_sc_frame(psource_frame,
6882 pdest_frame,&partial_frame) == -1)
6883 {
6884 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6885 return OMX_ErrorBadParameter;
6886 }
6887
6888 if (partial_frame == 0)
6889 {
6890 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
6891 pdest_frame->nFilledLen,psource_frame,frame_count);
6892
6893
6894 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
6895 /*First Parsed buffer will have only header Hence skip*/
6896 if (frame_count == 0)
6897 {
6898 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6899
6900 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
6901 codec_type_parse == CODEC_TYPE_DIVX) {
6902 mp4StreamType psBits;
6903 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6904 psBits.numBytes = pdest_frame->nFilledLen;
6905 mp4_headerparser.parseHeader(&psBits);
6906 }
6907
6908 frame_count++;
6909 }
6910 else
6911 {
6912 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6913 if(pdest_frame->nFilledLen)
6914 {
6915 /*Push the frame to the Decoder*/
6916 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
6917 {
6918 return OMX_ErrorBadParameter;
6919 }
6920 frame_count++;
6921 pdest_frame = NULL;
6922
6923 if (m_input_free_q.m_size)
6924 {
6925 m_input_free_q.pop_entry(&address,&p2,&id);
6926 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6927 pdest_frame->nFilledLen = 0;
6928 }
6929 }
6930 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
6931 {
6932 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6933 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6934 pdest_frame = NULL;
6935 }
6936 }
6937 }
6938 else
6939 {
6940 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
6941 /*Check if Destination Buffer is full*/
6942 if (pdest_frame->nAllocLen ==
6943 pdest_frame->nFilledLen + pdest_frame->nOffset)
6944 {
6945 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6946 return OMX_ErrorStreamCorrupt;
6947 }
6948 }
6949
6950 if (psource_frame->nFilledLen == 0)
6951 {
6952 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
6953 {
6954 if (pdest_frame)
6955 {
6956 pdest_frame->nFlags |= psource_frame->nFlags;
6957 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
6958 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6959 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
6960 pdest_frame->nFilledLen,frame_count++);
6961 /*Push the frame to the Decoder*/
6962 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
6963 {
6964 return OMX_ErrorBadParameter;
6965 }
6966 frame_count++;
6967 pdest_frame = NULL;
6968 }
6969 else
6970 {
6971 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6972 generate_ebd = OMX_FALSE;
6973 }
6974 }
6975 if(generate_ebd)
6976 {
6977 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6978 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6979 psource_frame = NULL;
6980
6981 if (m_input_pending_q.m_size)
6982 {
6983 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6984 m_input_pending_q.pop_entry(&address,&p2,&id);
6985 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6986 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
6987 psource_frame->nTimeStamp);
6988 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
6989 psource_frame->nFlags,psource_frame->nFilledLen);
6990 }
6991 }
6992 }
6993 return OMX_ErrorNone;
6994}
6995
6996OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6997{
6998 OMX_U32 partial_frame = 1;
6999 unsigned address,p2,id;
7000 OMX_BOOL isNewFrame = OMX_FALSE;
7001 OMX_BOOL generate_ebd = OMX_TRUE;
7002
7003 if (h264_scratch.pBuffer == NULL)
7004 {
7005 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7006 return OMX_ErrorBadParameter;
7007 }
7008 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d "
7009 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7010 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7011 if (h264_scratch.nFilledLen && look_ahead_nal)
7012 {
7013 look_ahead_nal = false;
7014 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7015 h264_scratch.nFilledLen)
7016 {
7017 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7018 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7019 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7020 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7021 h264_scratch.nFilledLen = 0;
7022 }
7023 else
7024 {
7025 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7026 return OMX_ErrorBadParameter;
7027 }
7028 }
7029 if (nal_length == 0)
7030 {
7031 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7032 if (m_frame_parser.parse_sc_frame(psource_frame,
7033 &h264_scratch,&partial_frame) == -1)
7034 {
7035 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7036 return OMX_ErrorBadParameter;
7037 }
7038 }
7039 else
7040 {
7041 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7042 if (m_frame_parser.parse_h264_nallength(psource_frame,
7043 &h264_scratch,&partial_frame) == -1)
7044 {
7045 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7046 return OMX_ErrorBadParameter;
7047 }
7048 }
7049
7050 if (partial_frame == 0)
7051 {
7052 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7053 {
7054 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7055 nal_count++;
7056 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7057 h264_scratch.nFlags = psource_frame->nFlags;
7058 }
7059 else
7060 {
7061 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen);
7062 if(h264_scratch.nFilledLen)
7063 {
7064 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7065 NALU_TYPE_SPS);
7066#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7067 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7068 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7069 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7070 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7071 // If timeinfo is present frame info from SEI is already processed
7072 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7073 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7074#endif
7075 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7076 nal_count++;
7077 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7078 pdest_frame->nTimeStamp = h264_last_au_ts;
7079 pdest_frame->nFlags = h264_last_au_flags;
7080#ifdef PANSCAN_HDLR
7081 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7082 h264_parser->update_panscan_data(h264_last_au_ts);
7083#endif
7084 }
7085 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7086 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7087 h264_last_au_ts = h264_scratch.nTimeStamp;
7088 h264_last_au_flags = h264_scratch.nFlags;
7089#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7090 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7091 {
7092 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7093 if (!VALID_TS(h264_last_au_ts))
7094 h264_last_au_ts = ts_in_sei;
7095 }
7096#endif
7097 } else
7098 h264_last_au_ts = LLONG_MAX;
7099 }
7100
7101 if (!isNewFrame)
7102 {
7103 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7104 h264_scratch.nFilledLen)
7105 {
7106 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
7107 h264_scratch.nFilledLen);
7108 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7109 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7110 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7111 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7112 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7113 h264_scratch.nFilledLen = 0;
7114 }
7115 else
7116 {
7117 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7118 return OMX_ErrorBadParameter;
7119 }
7120 }
7121 else
7122 {
7123 look_ahead_nal = true;
7124 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7125 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7126 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7127 pdest_frame->nFilledLen,frame_count++);
7128
7129 if (pdest_frame->nFilledLen == 0)
7130 {
7131 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7132 look_ahead_nal = false;
7133 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7134 h264_scratch.nFilledLen)
7135 {
7136 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7137 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7138 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7139 h264_scratch.nFilledLen = 0;
7140 }
7141 else
7142 {
7143 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7144 return OMX_ErrorBadParameter;
7145 }
7146 }
7147 else
7148 {
7149 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7150 {
7151 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7152 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7153 }
7154 /*Push the frame to the Decoder*/
7155 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7156 {
7157 return OMX_ErrorBadParameter;
7158 }
7159 //frame_count++;
7160 pdest_frame = NULL;
7161 if (m_input_free_q.m_size)
7162 {
7163 m_input_free_q.pop_entry(&address,&p2,&id);
7164 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7165 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7166 pdest_frame->nFilledLen = 0;
7167 pdest_frame->nFlags = 0;
7168 pdest_frame->nTimeStamp = LLONG_MAX;
7169 }
7170 }
7171 }
7172 }
7173 }
7174 else
7175 {
7176 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7177 /*Check if Destination Buffer is full*/
7178 if (h264_scratch.nAllocLen ==
7179 h264_scratch.nFilledLen + h264_scratch.nOffset)
7180 {
7181 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7182 return OMX_ErrorStreamCorrupt;
7183 }
7184 }
7185
7186 if (!psource_frame->nFilledLen)
7187 {
7188 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7189
7190 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7191 {
7192 if (pdest_frame)
7193 {
7194 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7195 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7196 h264_scratch.nFilledLen)
7197 {
7198 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7199 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7200 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7201 h264_scratch.nFilledLen = 0;
7202 }
7203 else
7204 {
7205 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7206 return OMX_ErrorBadParameter;
7207 }
7208 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7209 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7210
7211 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x",
7212 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7213 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7214#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7215 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7216 {
7217 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7218 if (!VALID_TS(pdest_frame->nTimeStamp))
7219 pdest_frame->nTimeStamp = ts_in_sei;
7220 }
7221#endif
7222 /*Push the frame to the Decoder*/
7223 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7224 {
7225 return OMX_ErrorBadParameter;
7226 }
7227 frame_count++;
7228 pdest_frame = NULL;
7229 }
7230 else
7231 {
7232 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
7233 pdest_frame,h264_scratch.nFilledLen);
7234 generate_ebd = OMX_FALSE;
7235 }
7236 }
7237 }
7238 if(generate_ebd && !psource_frame->nFilledLen)
7239 {
7240 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7241 psource_frame = NULL;
7242 if (m_input_pending_q.m_size)
7243 {
7244 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7245 m_input_pending_q.pop_entry(&address,&p2,&id);
7246 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7247 DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d",
7248 psource_frame->nFlags,psource_frame->nFilledLen);
7249 }
7250 }
7251 return OMX_ErrorNone;
7252}
7253
7254OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7255{
7256 OMX_U8 *buf, *pdest;
7257 OMX_U32 partial_frame = 1;
7258 OMX_U32 buf_len, dest_len;
7259
7260 if(first_frame == 0)
7261 {
7262 first_frame = 1;
7263 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7264 if(!m_vendor_config.pData)
7265 {
7266 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7267 buf = psource_frame->pBuffer;
7268 buf_len = psource_frame->nFilledLen;
7269
7270 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7271 VC1_SP_MP_START_CODE)
7272 {
7273 m_vc1_profile = VC1_SP_MP_RCV;
7274 }
7275 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7276 {
7277 m_vc1_profile = VC1_AP;
7278 }
7279 else
7280 {
7281 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7282 return OMX_ErrorStreamCorrupt;
7283 }
7284 }
7285 else
7286 {
7287 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7288 pdest_frame->nOffset;
7289 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7290 pdest_frame->nOffset);
7291
7292 if(dest_len < m_vendor_config.nDataSize)
7293 {
7294 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7295 return OMX_ErrorBadParameter;
7296 }
7297 else
7298 {
7299 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7300 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7301 }
7302 }
7303 }
7304
7305 switch(m_vc1_profile)
7306 {
7307 case VC1_AP:
7308 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7309 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7310 {
7311 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7312 return OMX_ErrorBadParameter;
7313 }
7314 break;
7315
7316 case VC1_SP_MP_RCV:
7317 default:
7318 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7319 return OMX_ErrorBadParameter;
7320 }
7321 return OMX_ErrorNone;
7322}
7323
7324bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7325 OMX_U32 alignment)
7326{
7327 struct pmem_allocation allocation;
7328 allocation.size = buffer_size;
7329 allocation.align = clip2(alignment);
7330 if (allocation.align < 4096)
7331 {
7332 allocation.align = 4096;
7333 }
7334 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7335 {
7336 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7337 allocation.align, allocation.size);
7338 return false;
7339 }
7340 return true;
7341}
7342#ifdef USE_ION
7343int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7344 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7345 struct ion_fd_data *fd_data, int flag)
7346{
7347 int fd = -EINVAL;
7348 int rc = -EINVAL;
7349 int ion_dev_flag;
7350 struct vdec_ion ion_buf_info;
7351 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7352 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7353 return -EINVAL;
7354 }
7355 if(!secure_mode && flag == CACHED)
7356 {
7357 ion_dev_flag = O_RDONLY;
7358 } else {
7359 ion_dev_flag = (O_RDONLY | O_DSYNC);
7360 }
7361 fd = open (MEM_DEVICE, ion_dev_flag);
7362 if (fd < 0) {
7363 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7364 return fd;
7365 }
7366 alloc_data->len = buffer_size;
7367 alloc_data->align = clip2(alignment);
7368 if (alloc_data->align < 4096)
7369 {
7370 alloc_data->align = 4096;
7371 }
7372 if(secure_mode) {
7373 alloc_data->flags = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
7374 } else {
7375 alloc_data->flags = ION_HEAP(MEM_HEAP_ID);
7376 }
7377 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7378 if (rc || !alloc_data->handle) {
7379 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7380 alloc_data->handle = NULL;
7381 close(fd);
7382 fd = -ENOMEM;
7383 return fd;
7384 }
7385 fd_data->handle = alloc_data->handle;
7386 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7387 if (rc) {
7388 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7389 ion_buf_info.ion_alloc_data = *alloc_data;
7390 ion_buf_info.ion_device_fd = fd;
7391 ion_buf_info.fd_ion_data = *fd_data;
7392 free_ion_memory(&ion_buf_info);
7393 fd_data->fd =-1;
7394 close(fd);
7395 fd = -ENOMEM;
7396 }
7397
7398 return fd;
7399}
7400
7401void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7402
7403 if(!buf_ion_info) {
7404 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7405 return;
7406 }
7407 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7408 &buf_ion_info->ion_alloc_data.handle)) {
7409 DEBUG_PRINT_ERROR("\n ION: free failed" );
7410 }
7411 close(buf_ion_info->ion_device_fd);
7412 buf_ion_info->ion_device_fd = -1;
7413 buf_ion_info->ion_alloc_data.handle = NULL;
7414 buf_ion_info->fd_ion_data.fd = -1;
7415}
7416#endif
7417void omx_vdec::free_output_buffer_header()
7418{
7419 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7420 output_use_buffer = false;
7421 ouput_egl_buffers = false;
7422
7423 if (m_out_mem_ptr)
7424 {
7425 free (m_out_mem_ptr);
7426 m_out_mem_ptr = NULL;
7427 }
7428
7429 if(m_platform_list)
7430 {
7431 free(m_platform_list);
7432 m_platform_list = NULL;
7433 }
7434
7435 if (drv_ctx.ptr_respbuffer)
7436 {
7437 free (drv_ctx.ptr_respbuffer);
7438 drv_ctx.ptr_respbuffer = NULL;
7439 }
7440 if (drv_ctx.ptr_outputbuffer)
7441 {
7442 free (drv_ctx.ptr_outputbuffer);
7443 drv_ctx.ptr_outputbuffer = NULL;
7444 }
7445#ifdef USE_ION
7446 if (drv_ctx.op_buf_ion_info) {
7447 DEBUG_PRINT_LOW("\n Free o/p ion context");
7448 free(drv_ctx.op_buf_ion_info);
7449 drv_ctx.op_buf_ion_info = NULL;
7450 }
7451#endif
7452}
7453
7454void omx_vdec::free_input_buffer_header()
7455{
7456 input_use_buffer = false;
7457 if (arbitrary_bytes)
7458 {
7459 if (m_frame_parser.mutils)
7460 {
7461 DEBUG_PRINT_LOW("\n Free utils parser");
7462 delete (m_frame_parser.mutils);
7463 m_frame_parser.mutils = NULL;
7464 }
7465
7466 if (m_inp_heap_ptr)
7467 {
7468 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7469 free (m_inp_heap_ptr);
7470 m_inp_heap_ptr = NULL;
7471 }
7472
7473 if (m_phdr_pmem_ptr)
7474 {
7475 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7476 free (m_phdr_pmem_ptr);
7477 m_phdr_pmem_ptr = NULL;
7478 }
7479 }
7480 if (m_inp_mem_ptr)
7481 {
7482 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7483 free (m_inp_mem_ptr);
7484 m_inp_mem_ptr = NULL;
7485 }
7486 if (drv_ctx.ptr_inputbuffer)
7487 {
7488 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7489 free (drv_ctx.ptr_inputbuffer);
7490 drv_ctx.ptr_inputbuffer = NULL;
7491 }
7492#ifdef USE_ION
7493 if (drv_ctx.ip_buf_ion_info) {
7494 DEBUG_PRINT_LOW("\n Free ion context");
7495 free(drv_ctx.ip_buf_ion_info);
7496 drv_ctx.ip_buf_ion_info = NULL;
7497 }
7498#endif
7499}
7500void omx_vdec::stream_off()
7501{
7502 int rc=0;
7503 enum v4l2_buf_type btype;
7504 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7505 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7506 if (rc) {
7507 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007508 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007509 } else {
7510 streaming[CAPTURE_PORT] = false;
7511 }
7512}
7513
7514OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7515{
7516 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7517 struct v4l2_requestbuffers bufreq;
7518 unsigned int buf_size = 0, extra_data_size = 0;
7519 struct v4l2_format fmt;
7520 int ret;
7521 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7522 buffer_prop->actualcount, buffer_prop->buffer_size);
7523 bufreq.memory = V4L2_MEMORY_USERPTR;
7524 if(in_reconfig == true)
7525 bufreq.count = 0;
7526 else
7527 bufreq.count = 2;
7528 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7529 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7530 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7531 fmt.fmt.pix_mp.pixelformat = output_capability;
7532 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7533 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7534 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7535 fmt.fmt.pix_mp.pixelformat = capture_capability;
7536 }else {eRet = OMX_ErrorBadParameter;}
7537 if(eRet==OMX_ErrorNone){
7538 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7539 }
7540 if(ret)
7541 {
7542 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7543 /*TODO: How to handle this case */
7544 eRet = OMX_ErrorInsufficientResources;
7545 return eRet;
7546 }
7547 else
7548 {
7549 buffer_prop->actualcount = bufreq.count;
7550 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007551 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007552 }
7553 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7554 buffer_prop->actualcount, buffer_prop->buffer_size);
7555
7556 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7557 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7558
7559 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7560
7561 drv_ctx.video_resolution.frame_height = fmt.fmt.pix_mp.height;
7562 drv_ctx.video_resolution.frame_width = fmt.fmt.pix_mp.width;
7563
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007564 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565
7566 if(ret)
7567 {
7568 /*TODO: How to handle this case */
7569 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7570 eRet = OMX_ErrorInsufficientResources;
7571 }
7572 else
7573 {
7574 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7575 buf_size = buffer_prop->buffer_size;
7576 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7577 {
7578 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7579 extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7580 }
7581 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7582 {
7583 DEBUG_PRINT_HIGH("Interlace extra data enabled!");
7584 extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7585 }
7586 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7587 {
7588 extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7589 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7590 extra_data_size);
7591 }
7592 if (extra_data_size)
7593 {
7594 extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7595 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7596 }
7597 buf_size += extra_data_size;
7598 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7599 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7600 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7601 if (in_reconfig) // BufReq will be set to driver when port is disabled
7602 buffer_prop->buffer_size = buf_size;
7603 else if (buf_size != buffer_prop->buffer_size)
7604 {
7605 buffer_prop->buffer_size = buf_size;
7606 eRet = set_buffer_req(buffer_prop);
7607 }
7608 }
7609 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7610 buffer_prop->actualcount, buffer_prop->buffer_size);
7611 return eRet;
7612}
7613
7614OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7615{
7616 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7617 unsigned buf_size = 0;
7618 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007619 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007620 int ret;
7621 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7622 buffer_prop->actualcount, buffer_prop->buffer_size);
7623 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7624 if (buf_size != buffer_prop->buffer_size)
7625 {
7626 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7627 buffer_prop->buffer_size, buf_size);
7628 eRet = OMX_ErrorBadParameter;
7629 }
7630 else
7631 {
7632 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7633 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007634
7635 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7636 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7637 fmt.fmt.pix_mp.pixelformat = output_capability;
7638 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7639 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7640 fmt.fmt.pix_mp.pixelformat = capture_capability;
7641 } else {eRet = OMX_ErrorBadParameter;}
7642
7643 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7644 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007645 {
7646 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007647 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007648 eRet = OMX_ErrorInsufficientResources;
7649 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007650
7651 bufreq.memory = V4L2_MEMORY_USERPTR;
7652 bufreq.count = buffer_prop->actualcount;
7653 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7654 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7655 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7656 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7657 } else {eRet = OMX_ErrorBadParameter;}
7658
7659 if (eRet==OMX_ErrorNone) {
7660 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7661 }
7662
7663 if (ret)
7664 {
7665 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7666 /*TODO: How to handle this case */
7667 eRet = OMX_ErrorInsufficientResources;
7668 } else if (bufreq.count < buffer_prop->actualcount) {
7669 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7670 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7671 buffer_prop->actualcount, bufreq.count);
7672 eRet = OMX_ErrorInsufficientResources;
7673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007674 }
7675 return eRet;
7676}
7677
Shalaj Jain273b3e02012-06-22 19:08:03 -07007678OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7679{
7680 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7681 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7682 ioctl_msg.in = NULL;
7683 ioctl_msg.out = &drv_ctx.video_resolution;
7684 if (/*ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)*/0)
7685 {
7686 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES");
7687 eRet = OMX_ErrorHardware;
7688 }
7689 return eRet;
7690}
7691
7692OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7693{
7694 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7695 if (!portDefn)
7696 {
7697 return OMX_ErrorBadParameter;
7698 }
7699 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7700 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7701 portDefn->nSize = sizeof(portDefn);
7702 portDefn->eDomain = OMX_PortDomainVideo;
7703 if (drv_ctx.frame_rate.fps_denominator > 0)
7704 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7705 drv_ctx.frame_rate.fps_denominator;
7706 else {
7707 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7708 return OMX_ErrorBadParameter;
7709 }
7710 if (0 == portDefn->nPortIndex)
7711 {
7712 portDefn->eDir = OMX_DirInput;
7713 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7714 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7715 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7716 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7717 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7718 portDefn->bEnabled = m_inp_bEnabled;
7719 portDefn->bPopulated = m_inp_bPopulated;
7720 }
7721 else if (1 == portDefn->nPortIndex)
7722 {
7723 portDefn->eDir = OMX_DirOutput;
7724 eRet=get_buffer_req(&drv_ctx.op_buf);
7725 if (in_reconfig)
7726 {
7727 portDefn->nBufferCountActual = op_buf_rcnfg.actualcount;
7728 portDefn->nBufferCountMin = op_buf_rcnfg.mincount;
7729 portDefn->nBufferSize = op_buf_rcnfg.buffer_size;
7730 }
7731 else
7732 {
7733 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7734 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7735 portDefn->nBufferSize = drv_ctx.op_buf.buffer_size;
7736 }
7737 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7738 portDefn->bEnabled = m_out_bEnabled;
7739 portDefn->bPopulated = m_out_bPopulated;
7740 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007741 portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
7742 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007743 else if (drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2)
7744 portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
7745 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
7746 else
7747 {
7748 DEBUG_PRINT_ERROR("ERROR: Color format unknown: %x\n", drv_ctx.output_format);
7749 }
7750 }
7751 else
7752 {
7753 portDefn->eDir = OMX_DirMax;
7754 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7755 (int)portDefn->nPortIndex);
7756 eRet = OMX_ErrorBadPortIndex;
7757 }
7758 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7759 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7760 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7761 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7762 DEBUG_PRINT_LOW("update_portdef Width = %d Height = %d Stride = %u"
7763 "SliceHeight = %u \n", portDefn->format.video.nFrameHeight,
7764 portDefn->format.video.nFrameWidth,
7765 portDefn->format.video.nStride,
7766 portDefn->format.video.nSliceHeight);
7767 return eRet;
7768
7769}
7770
7771OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7772{
7773 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7774 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7775 unsigned i= 0;
7776
7777 if(!m_out_mem_ptr) {
7778 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7779 int nBufHdrSize = 0;
7780 int nPlatformEntrySize = 0;
7781 int nPlatformListSize = 0;
7782 int nPMEMInfoSize = 0;
7783 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7784 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7785 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
7786
7787 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7788 drv_ctx.op_buf.actualcount);
7789 nBufHdrSize = drv_ctx.op_buf.actualcount *
7790 sizeof(OMX_BUFFERHEADERTYPE);
7791
7792 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7793 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7794 nPlatformListSize = drv_ctx.op_buf.actualcount *
7795 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7796 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7797 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
7798
7799 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7800 sizeof(OMX_BUFFERHEADERTYPE),
7801 nPMEMInfoSize,
7802 nPlatformListSize);
7803 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7804 m_out_bm_count);
7805 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7806 // Alloc mem for platform specific info
7807 char *pPtr=NULL;
7808 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7809 nPMEMInfoSize,1);
7810 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7811 calloc (sizeof(struct vdec_bufferpayload),
7812 drv_ctx.op_buf.actualcount);
7813 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7814 calloc (sizeof (struct vdec_output_frameinfo),
7815 drv_ctx.op_buf.actualcount);
7816#ifdef USE_ION
7817 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7818 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
7819#endif
7820
7821 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7822 && drv_ctx.ptr_respbuffer)
7823 {
7824 bufHdr = m_out_mem_ptr;
7825 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7826 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7827 (((char *) m_platform_list) + nPlatformListSize);
7828 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7829 (((char *) m_platform_entry) + nPlatformEntrySize);
7830 pPlatformList = m_platform_list;
7831 pPlatformEntry = m_platform_entry;
7832 pPMEMInfo = m_pmem_info;
7833
7834 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
7835
7836 // Settting the entire storage nicely
7837 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7838 m_out_mem_ptr,pPlatformEntry);
7839 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7840 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
7841 {
7842 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7843 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7844 // Set the values when we determine the right HxW param
7845 bufHdr->nAllocLen = 0;
7846 bufHdr->nFilledLen = 0;
7847 bufHdr->pAppPrivate = NULL;
7848 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7849 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7850 pPlatformEntry->entry = pPMEMInfo;
7851 // Initialize the Platform List
7852 pPlatformList->nEntries = 1;
7853 pPlatformList->entryList = pPlatformEntry;
7854 // Keep pBuffer NULL till vdec is opened
7855 bufHdr->pBuffer = NULL;
7856 pPMEMInfo->offset = 0;
7857 pPMEMInfo->pmem_fd = 0;
7858 bufHdr->pPlatformPrivate = pPlatformList;
7859 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
7860#ifdef USE_ION
7861 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
7862#endif
7863 /*Create a mapping between buffers*/
7864 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7865 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7866 &drv_ctx.ptr_outputbuffer[i];
7867 // Move the buffer and buffer header pointers
7868 bufHdr++;
7869 pPMEMInfo++;
7870 pPlatformEntry++;
7871 pPlatformList++;
7872 }
7873 }
7874 else
7875 {
7876 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
7877 m_out_mem_ptr, pPtr);
7878 if(m_out_mem_ptr)
7879 {
7880 free(m_out_mem_ptr);
7881 m_out_mem_ptr = NULL;
7882 }
7883 if(pPtr)
7884 {
7885 free(pPtr);
7886 pPtr = NULL;
7887 }
7888 if(drv_ctx.ptr_outputbuffer)
7889 {
7890 free(drv_ctx.ptr_outputbuffer);
7891 drv_ctx.ptr_outputbuffer = NULL;
7892 }
7893 if(drv_ctx.ptr_respbuffer)
7894 {
7895 free(drv_ctx.ptr_respbuffer);
7896 drv_ctx.ptr_respbuffer = NULL;
7897 }
7898#ifdef USE_ION
7899 if (drv_ctx.op_buf_ion_info) {
7900 DEBUG_PRINT_LOW("\n Free o/p ion context");
7901 free(drv_ctx.op_buf_ion_info);
7902 drv_ctx.op_buf_ion_info = NULL;
7903 }
7904#endif
7905 eRet = OMX_ErrorInsufficientResources;
7906 }
7907 } else {
7908 eRet = OMX_ErrorInsufficientResources;
7909 }
7910 return eRet;
7911}
7912
7913void omx_vdec::complete_pending_buffer_done_cbs()
7914{
7915 unsigned p1;
7916 unsigned p2;
7917 unsigned ident;
7918 omx_cmd_queue tmp_q, pending_bd_q;
7919 pthread_mutex_lock(&m_lock);
7920 // pop all pending GENERATE FDB from ftb queue
7921 while (m_ftb_q.m_size)
7922 {
7923 m_ftb_q.pop_entry(&p1,&p2,&ident);
7924 if(ident == OMX_COMPONENT_GENERATE_FBD)
7925 {
7926 pending_bd_q.insert_entry(p1,p2,ident);
7927 }
7928 else
7929 {
7930 tmp_q.insert_entry(p1,p2,ident);
7931 }
7932 }
7933 //return all non GENERATE FDB to ftb queue
7934 while(tmp_q.m_size)
7935 {
7936 tmp_q.pop_entry(&p1,&p2,&ident);
7937 m_ftb_q.insert_entry(p1,p2,ident);
7938 }
7939 // pop all pending GENERATE EDB from etb queue
7940 while (m_etb_q.m_size)
7941 {
7942 m_etb_q.pop_entry(&p1,&p2,&ident);
7943 if(ident == OMX_COMPONENT_GENERATE_EBD)
7944 {
7945 pending_bd_q.insert_entry(p1,p2,ident);
7946 }
7947 else
7948 {
7949 tmp_q.insert_entry(p1,p2,ident);
7950 }
7951 }
7952 //return all non GENERATE FDB to etb queue
7953 while(tmp_q.m_size)
7954 {
7955 tmp_q.pop_entry(&p1,&p2,&ident);
7956 m_etb_q.insert_entry(p1,p2,ident);
7957 }
7958 pthread_mutex_unlock(&m_lock);
7959 // process all pending buffer dones
7960 while(pending_bd_q.m_size)
7961 {
7962 pending_bd_q.pop_entry(&p1,&p2,&ident);
7963 switch(ident)
7964 {
7965 case OMX_COMPONENT_GENERATE_EBD:
7966 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
7967 {
7968 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7969 omx_report_error ();
7970 }
7971 break;
7972
7973 case OMX_COMPONENT_GENERATE_FBD:
7974 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
7975 {
7976 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7977 omx_report_error ();
7978 }
7979 break;
7980 }
7981 }
7982}
7983
7984void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7985{
7986 OMX_U32 new_frame_interval = 0;
7987 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7988 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7989 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
7990 {
7991 new_frame_interval = (act_timestamp > prev_ts)?
7992 act_timestamp - prev_ts :
7993 prev_ts - act_timestamp;
7994 if (new_frame_interval < frm_int || frm_int == 0)
7995 {
7996 frm_int = new_frame_interval;
7997 if(frm_int)
7998 {
7999 drv_ctx.frame_rate.fps_numerator = 1e6;
8000 drv_ctx.frame_rate.fps_denominator = frm_int;
8001 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
8002 frm_int, drv_ctx.frame_rate.fps_numerator /
8003 (float)drv_ctx.frame_rate.fps_denominator);
8004 ioctl_msg.in = &drv_ctx.frame_rate;
8005 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
8006 (void*)&ioctl_msg) < */0)
8007 {
8008 DEBUG_PRINT_ERROR("Setting frame rate failed");
8009 }
8010 }
8011 }
8012 }
8013 prev_ts = act_timestamp;
8014}
8015
8016void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8017{
8018 if (rst_prev_ts && VALID_TS(act_timestamp))
8019 {
8020 prev_ts = act_timestamp;
8021 rst_prev_ts = false;
8022 }
8023 else if (VALID_TS(prev_ts))
8024 {
8025 bool codec_cond = (drv_ctx.timestamp_adjust)?
8026 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8027 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8028 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8029 if(frm_int > 0 && codec_cond)
8030 {
8031 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8032 act_timestamp = prev_ts + frm_int;
8033 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8034 prev_ts = act_timestamp;
8035 }
8036 else
8037 set_frame_rate(act_timestamp);
8038 }
8039 else if (frm_int > 0) // In this case the frame rate was set along
8040 { // with the port definition, start ts with 0
8041 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8042 rst_prev_ts = true;
8043 }
8044}
8045
8046void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8047{
8048 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8049 OMX_U32 num_conceal_MB = 0;
8050 OMX_S64 ts_in_sei = 0;
8051 OMX_U32 frame_rate = 0;
8052 p_extra = (OMX_OTHER_EXTRADATATYPE *)
8053 ((unsigned)(p_buf_hdr->pBuffer + p_buf_hdr->nOffset +
8054 p_buf_hdr->nFilledLen + 3)&(~3));
8055 if ((OMX_U8*)p_extra > (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen))
8056 p_extra = NULL;
8057 if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA))
8058 {
8059 // Process driver extradata
8060 while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE)
8061 {
8062 DEBUG_PRINT_LOW("handle_extradata : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)",
8063 p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize);
8064 if (p_extra->nSize < p_extra->nDataSize)
8065 {
8066 DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d",
8067 p_extra->nSize, p_extra->nDataSize);
8068 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8069 if ((OMX_U8*)p_extra > (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen) ||
8070 p_extra->nDataSize == 0)
8071 p_extra = NULL;
8072 continue;
8073 }
8074 if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP)
8075 {
8076 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8077 num_conceal_MB = count_MB_in_extradata(p_extra);
8078 if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)
8079 // Map driver extradata to corresponding OMX type
8080 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB;
8081 else
8082 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8083 if (m_debug_concealedmb) {
8084 DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB);
8085 }
8086 }
8087 else if (p_extra->eType == VDEC_EXTRADATA_SEI)
8088 {
8089 p_sei = p_extra;
8090
8091 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8092
8093 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8094 }
8095 else if (p_extra->eType == VDEC_EXTRADATA_VUI)
8096 {
8097 p_vui = p_extra;
8098
8099 h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8100
8101 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8102 }
8103 print_debug_extradata(p_extra);
8104 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8105 if ((OMX_U8*)p_extra > (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen) ||
8106 p_extra->nDataSize == 0)
8107 p_extra = NULL;
8108 }
8109 if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP))
8110 {
8111 // Driver extradata is only exposed if MB map is requested by client,
8112 // otherwise can be overwritten by omx extradata.
8113 p_extra = (OMX_OTHER_EXTRADATATYPE *)
8114 ((unsigned)(p_buf_hdr->pBuffer + p_buf_hdr->nOffset +
8115 p_buf_hdr->nFilledLen + 3)&(~3));
8116 p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8117 }
8118 }
8119
8120#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT
8121 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
8122 {
8123 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
8124 {
8125 if (p_vui)
8126 h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8127 if (p_sei)
8128 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8129 ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp);
8130 if (!VALID_TS(p_buf_hdr->nTimeStamp))
8131 p_buf_hdr->nTimeStamp = ts_in_sei;
8132 }
8133 else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei)
8134 // If timeinfo is present frame info from SEI is already processed
8135 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8136 }
8137#endif
8138 if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra &&
8139 ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) <
8140 (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen))
8141 {
8142 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8143 append_interlace_extradata(p_extra,
8144 ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format);
8145 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8146 }
8147 if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra &&
8148 ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8149 (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen))
8150 {
8151 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8152 /* vui extra data (frame_rate) information */
8153 if (h264_parser)
8154 h264_parser->get_frame_rate(&frame_rate);
8155 append_frame_info_extradata(p_extra, num_conceal_MB,
8156 ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type,
8157 p_buf_hdr->nTimeStamp, frame_rate, NULL);
8158 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8159 }
8160 if ((client_extradata & OMX_PORTDEF_EXTRADATA) &&
8161 p_extra != NULL &&
8162 ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) <
8163 (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen))
8164 {
8165 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8166 append_portdef_extradata(p_extra);
8167 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8168 }
8169 if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)
8170 if (p_extra &&
8171 ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8172 (p_buf_hdr->pBuffer + p_buf_hdr->nAllocLen))
8173 append_terminator_extradata(p_extra);
8174 else
8175 {
8176 DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added");
8177 p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8178 }
8179}
8180
8181OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, bool enable)
8182{
8183 OMX_ERRORTYPE ret = OMX_ErrorNone;
8184 OMX_U32 driver_extradata = 0, extradata_size = 0;
8185 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
8186 if(m_state != OMX_StateLoaded)
8187 {
8188 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8189 return OMX_ErrorIncorrectStateOperation;
8190 }
8191 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8192 extradata_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
8193 if (requested_extradata & OMX_INTERLACE_EXTRADATA)
8194 extradata_size += OMX_INTERLACE_EXTRADATA_SIZE;
8195 if (requested_extradata & OMX_PORTDEF_EXTRADATA)
8196 {
8197 extradata_size += OMX_PORTDEF_EXTRADATA_SIZE;
8198 }
8199 DEBUG_PRINT_ERROR("enable_extradata: actual[%x] requested[%x] enable[%d]",
8200 client_extradata, requested_extradata, enable);
8201
8202 if (enable)
8203 requested_extradata |= client_extradata;
8204 else
8205 {
8206 requested_extradata = client_extradata & ~requested_extradata;
8207 extradata_size *= -1;
8208 }
8209
8210 driver_extradata = requested_extradata & DRIVER_EXTRADATA_MASK;
8211 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8212 driver_extradata |= VDEC_EXTRADATA_MB_ERROR_MAP; // Required for conceal MB frame info
8213#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT
8214 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
8215 {
8216 driver_extradata |= ((requested_extradata & OMX_FRAMEINFO_EXTRADATA)?
8217 VDEC_EXTRADATA_SEI : 0); // Required for pan scan frame info
8218 driver_extradata |= ((requested_extradata & OMX_TIMEINFO_EXTRADATA)?
8219 VDEC_EXTRADATA_VUI | VDEC_EXTRADATA_SEI : 0); //Required for time info
8220 }
8221
8222#endif
8223 if (driver_extradata != drv_ctx.extradata)
8224 {
8225 client_extradata = requested_extradata;
8226 drv_ctx.extradata = driver_extradata;
8227 //ioctl_msg.in = &drv_ctx.extradata;
8228 //ioctl_msg.out = NULL;
8229 //if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_EXTRADATA,
8230 // (void*)&ioctl_msg) < 0)
8231 //{
8232 // DEBUG_PRINT_ERROR("\nSet extradata failed");
8233 // ret = OMX_ErrorUnsupportedSetting;
8234 //} // else
8235 // ret = get_buffer_req(&drv_ctx.op_buf);
8236 }
8237 else if ((client_extradata & ~DRIVER_EXTRADATA_MASK) != (requested_extradata & ~DRIVER_EXTRADATA_MASK))
8238 {
8239 client_extradata = requested_extradata;
8240 drv_ctx.op_buf.buffer_size += extradata_size;
8241 // align the buffer size
8242 drv_ctx.op_buf.buffer_size = (drv_ctx.op_buf.buffer_size + drv_ctx.op_buf.alignment - 1)&(~(drv_ctx.op_buf.alignment - 1));
8243 DEBUG_PRINT_LOW("Aligned buffer size with exreadata = %d\n", drv_ctx.op_buf.buffer_size);
8244 if (!(client_extradata & ~DRIVER_EXTRADATA_MASK)) // If no omx extradata is required remove space for terminator
8245 drv_ctx.op_buf.buffer_size -= sizeof(OMX_OTHER_EXTRADATATYPE);
8246 ret = set_buffer_req(&drv_ctx.op_buf);
8247 }
8248 return ret;
8249}
8250
8251OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8252{
8253 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8254 OMX_U8 *data_ptr = extra->data, data = 0;
8255 while (byte_count < extra->nDataSize)
8256 {
8257 data = *data_ptr;
8258 while (data)
8259 {
8260 num_MB += (data&0x01);
8261 data >>= 1;
8262 }
8263 data_ptr++;
8264 byte_count++;
8265 }
8266 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8267 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8268 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8269}
8270
8271void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8272{
8273 if (!m_debug_extradata)
8274 return;
8275
8276 DEBUG_PRINT_HIGH(
8277 "============== Extra Data ==============\n"
8278 " Size: %u \n"
8279 " Version: %u \n"
8280 " PortIndex: %u \n"
8281 " Type: %x \n"
8282 " DataSize: %u \n",
8283 extra->nSize, extra->nVersion.nVersion,
8284 extra->nPortIndex, extra->eType, extra->nDataSize);
8285
8286 if (extra->eType == OMX_ExtraDataInterlaceFormat)
8287 {
8288 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8289 DEBUG_PRINT_HIGH(
8290 "------ Interlace Format ------\n"
8291 " Size: %u \n"
8292 " Version: %u \n"
8293 " PortIndex: %u \n"
8294 " Is Interlace Format: %u \n"
8295 " Interlace Formats: %u \n"
8296 "=========== End of Interlace ===========\n",
8297 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8298 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8299 }
8300 else if (extra->eType == OMX_ExtraDataFrameInfo)
8301 {
8302 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8303
8304 DEBUG_PRINT_HIGH(
8305 "-------- Frame Format --------\n"
8306 " Picture Type: %u \n"
8307 " Interlace Type: %u \n"
8308 " Pan Scan Total Frame Num: %u \n"
8309 " Concealed Macro Blocks: %u \n"
8310 " frame rate: %u \n"
8311 " Aspect Ratio X: %u \n"
8312 " Aspect Ratio Y: %u \n",
8313 fminfo->ePicType,
8314 fminfo->interlaceType,
8315 fminfo->panScan.numWindows,
8316 fminfo->nConcealedMacroblocks,
8317 fminfo->nFrameRate,
8318 fminfo->aspectRatio.aspectRatioX,
8319 fminfo->aspectRatio.aspectRatioY);
8320
8321 for (int i = 0; i < fminfo->panScan.numWindows; i++)
8322 {
8323 DEBUG_PRINT_HIGH(
8324 "------------------------------\n"
8325 " Pan Scan Frame Num: %d \n"
8326 " Rectangle x: %d \n"
8327 " Rectangle y: %d \n"
8328 " Rectangle dx: %d \n"
8329 " Rectangle dy: %d \n",
8330 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8331 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8332 }
8333
8334 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8335 }
8336 else if (extra->eType == OMX_ExtraDataNone)
8337 {
8338 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8339 }
8340 else
8341 {
8342 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8343 }
8344}
8345
8346void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8347 OMX_U32 interlaced_format_type)
8348{
8349 OMX_STREAMINTERLACEFORMAT *interlace_format;
8350 OMX_U32 mbaff = 0;
8351 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8352 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8353 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8354 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8355 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8356 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8357 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8358 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8359 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8360 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8361 if ((interlaced_format_type == VDEC_InterlaceFrameProgressive) && !mbaff)
8362 {
8363 interlace_format->bInterlaceFormat = OMX_FALSE;
8364 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8365 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8366 }
8367 else
8368 {
8369 interlace_format->bInterlaceFormat = OMX_TRUE;
8370 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8371 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8372 }
8373 print_debug_extradata(extra);
8374}
8375
8376
8377void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8378 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_S64 timestamp, OMX_U32 frame_rate,
8379 vdec_aspectratioinfo *aspect_ratio_info)
8380{
8381 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8382 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8383 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8384 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8385 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8386 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8387 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8388 switch (picture_type)
8389 {
8390 case PICTURE_TYPE_I:
8391 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8392 break;
8393 case PICTURE_TYPE_P:
8394 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8395 break;
8396 case PICTURE_TYPE_B:
8397 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8398 break;
8399 default:
8400 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8401 }
8402 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8403 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8404 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8405 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8406 else
8407 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8408 memset(&frame_info->panScan,0,sizeof(frame_info->panScan));
8409 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8410 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
8411 {
8412 h264_parser->fill_pan_scan_data(&frame_info->panScan, timestamp);
8413 h264_parser->fill_aspect_ratio_info(&frame_info->aspectRatio);
8414 }
8415 frame_info->nConcealedMacroblocks = num_conceal_mb;
8416 frame_info->nFrameRate = frame_rate;
8417 print_debug_extradata(extra);
8418}
8419
8420void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8421{
8422 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8423 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8424 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8425 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8426 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8427 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8428 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8429 *portDefn = m_port_def;
8430 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u"
8431 "sliceheight = %u \n",portDefn->format.video.nFrameHeight,
8432 portDefn->format.video.nFrameWidth,
8433 portDefn->format.video.nStride,
8434 portDefn->format.video.nSliceHeight);
8435}
8436
8437void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8438{
8439 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8440 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8441 extra->eType = OMX_ExtraDataNone;
8442 extra->nDataSize = 0;
8443 extra->data[0] = 0;
8444
8445 print_debug_extradata(extra);
8446}
8447
8448OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8449{
8450 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8451 if (index >= drv_ctx.ip_buf.actualcount)
8452 {
8453 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8454 return OMX_ErrorInsufficientResources;
8455 }
8456 if (m_desc_buffer_ptr == NULL)
8457 {
8458 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8459 calloc( (sizeof(desc_buffer_hdr)),
8460 drv_ctx.ip_buf.actualcount);
8461 if (m_desc_buffer_ptr == NULL)
8462 {
8463 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8464 return OMX_ErrorInsufficientResources;
8465 }
8466 }
8467
8468 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8469 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8470 {
8471 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8472 return OMX_ErrorInsufficientResources;
8473 }
8474
8475 return eRet;
8476}
8477
8478void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8479{
8480 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries);
8481 if (m_demux_entries < 8192)
8482 {
8483 m_demux_offsets[m_demux_entries++] = address_offset;
8484 }
8485 return;
8486}
8487
8488void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8489{
8490 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8491 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8492 OMX_U32 index = 0;
8493
8494 m_demux_entries = 0;
8495
8496 while (index < bytes_to_parse)
8497 {
8498 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8499 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8500 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8501 (buf[index+2] == 0x01)) )
8502 {
8503 //Found start code, insert address offset
8504 insert_demux_addr_offset(index);
8505 if (buf[index+2] == 0x01) // 3 byte start code
8506 index += 3;
8507 else //4 byte start code
8508 index += 4;
8509 }
8510 else
8511 index++;
8512 }
8513 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries);
8514 return;
8515}
8516
8517OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8518{
8519 //fix this, handle 3 byte start code, vc1 terminator entry
8520 OMX_U8 *p_demux_data = NULL;
8521 OMX_U32 desc_data = 0;
8522 OMX_U32 start_addr = 0;
8523 OMX_U32 nal_size = 0;
8524 OMX_U32 suffix_byte = 0;
8525 OMX_U32 demux_index = 0;
8526 OMX_U32 buffer_index = 0;
8527
8528 if (m_desc_buffer_ptr == NULL)
8529 {
8530 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8531 return OMX_ErrorBadParameter;
8532 }
8533
8534 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8535 if (buffer_index > drv_ctx.ip_buf.actualcount)
8536 {
8537 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index);
8538 return OMX_ErrorBadParameter;
8539 }
8540
8541 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8542
8543 if ( ((OMX_U8*)p_demux_data == NULL) ||
8544 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8545 {
8546 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8547 return OMX_ErrorBadParameter;
8548 }
8549 else
8550 {
8551 for (; demux_index < m_demux_entries; demux_index++)
8552 {
8553 desc_data = 0;
8554 start_addr = m_demux_offsets[demux_index];
8555 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8556 {
8557 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8558 }
8559 else
8560 {
8561 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8562 }
8563 if (demux_index < (m_demux_entries - 1))
8564 {
8565 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8566 }
8567 else
8568 {
8569 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8570 }
8571 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)",
8572 start_addr,
8573 suffix_byte,
8574 nal_size,
8575 demux_index);
8576 desc_data = (start_addr >> 3) << 1;
8577 desc_data |= (start_addr & 7) << 21;
8578 desc_data |= suffix_byte << 24;
8579
8580 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8581 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8582 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8583 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8584
8585 p_demux_data += 16;
8586 }
8587 if (codec_type_parse == CODEC_TYPE_VC1)
8588 {
8589 DEBUG_PRINT_LOW("VC1 terminator entry");
8590 desc_data = 0;
8591 desc_data = 0x82 << 24;
8592 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8593 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8594 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8595 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8596 p_demux_data += 16;
8597 m_demux_entries++;
8598 }
8599 //Add zero word to indicate end of descriptors
8600 memset(p_demux_data, 0, sizeof(OMX_U32));
8601
8602 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8603 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size);
8604 }
8605 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8606 m_demux_entries = 0;
8607 DEBUG_PRINT_LOW("Demux table complete!");
8608 return OMX_ErrorNone;
8609}
8610
8611#if 0
8612OMX_ERRORTYPE omx_vdec::createDivxDrmContext( OMX_PTR drmHandle )
8613{
8614 OMX_ERRORTYPE err = OMX_ErrorNone;
8615 if( drmHandle == NULL ) {
8616 DEBUG_PRINT_HIGH("\n This clip is not DRM encrypted");
8617 iDivXDrmDecrypt = NULL;
8618 return err;
8619 }
8620
8621 iDivXDrmDecrypt = DivXDrmDecrypt::Create( drmHandle );
8622 if (iDivXDrmDecrypt) {
8623 DEBUG_PRINT_LOW("\nCreated DIVX DRM, now calling Init");
8624 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8625 if(err!=OMX_ErrorNone) {
8626 DEBUG_PRINT_ERROR("\nERROR:iDivXDrmDecrypt->Init %d", err);
8627 delete iDivXDrmDecrypt;
8628 iDivXDrmDecrypt = NULL;
8629 }
8630 }
8631 else {
8632 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8633 return OMX_ErrorUndefined;
8634 }
8635 return err;
8636}
8637#endif
8638