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