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