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