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