blob: d816b65dba200bfebd3c76ec23bf52ec1d858558 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -08002Copyright (c) 2010 - 2013, The Linux Foundation. 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.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 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>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080051#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070052
53#ifndef _ANDROID_
54#include <sys/ioctl.h>
55#include <sys/mman.h>
56#endif //_ANDROID_
57
58#ifdef _ANDROID_
59#include <cutils/properties.h>
60#undef USE_EGL_IMAGE_GPU
61#endif
62
63#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
64#include <gralloc_priv.h>
65#endif
66
67#if defined (_ANDROID_ICS_)
68#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070069#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070070#endif
71
72#ifdef _ANDROID_
73#include "DivXDrmDecrypt.h"
74#endif //_ANDROID_
75
76#ifdef USE_EGL_IMAGE_GPU
77#include <EGL/egl.h>
78#include <EGL/eglQCOM.h>
79#define EGL_BUFFER_HANDLE_QCOM 0x4F00
80#define EGL_BUFFER_OFFSET_QCOM 0x4F01
81#endif
82
83#ifdef INPUT_BUFFER_LOG
84#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
85#define INPUT_BUFFER_FILE_NAME_LEN 30
86FILE *inputBufferFile1;
87char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
88#endif
89#ifdef OUTPUT_BUFFER_LOG
90FILE *outputBufferFile1;
91char outputfilename [] = "/data/output.yuv";
92#endif
93#ifdef OUTPUT_EXTRADATA_LOG
94FILE *outputExtradataFile;
95char ouputextradatafilename [] = "/data/extradata";
96#endif
97
98#define DEFAULT_FPS 30
99#define MAX_INPUT_ERROR DEFAULT_FPS
100#define MAX_SUPPORTED_FPS 120
101
102#define VC1_SP_MP_START_CODE 0xC5000000
103#define VC1_SP_MP_START_CODE_MASK 0xFF000000
104#define VC1_AP_SEQ_START_CODE 0x0F010000
105#define VC1_STRUCT_C_PROFILE_MASK 0xF0
106#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
107#define VC1_SIMPLE_PROFILE 0
108#define VC1_MAIN_PROFILE 1
109#define VC1_ADVANCE_PROFILE 3
110#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
111#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
112#define VC1_STRUCT_C_LEN 4
113#define VC1_STRUCT_C_POS 8
114#define VC1_STRUCT_A_POS 12
115#define VC1_STRUCT_B_POS 24
116#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700117#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700118
119#define MEM_DEVICE "/dev/ion"
120#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
121
122#ifdef _ANDROID_
123 extern "C"{
124 #include<utils/Log.h>
125 }
126#endif//_ANDROID_
127
Vinay Kalia53fa6832012-10-11 17:55:30 -0700128#define SZ_4K 0x1000
129#define SZ_1M 0x100000
130
Shalaj Jain273b3e02012-06-22 19:08:03 -0700131#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
132#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 -0700133#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
134
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800135#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700136void* async_message_thread (void *input)
137{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
Praneeth Paladugu32284302013-02-14 22:53:06 -0800141 struct v4l2_buffer v4l2_buf;
142 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700143 struct v4l2_event dqevent;
144 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
145 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
146 pfd.fd = omx->drv_ctx.video_driver_fd;
147 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
148 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
149 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
150 while (1)
151 {
152 rc = poll(&pfd, 1, POLL_TIMEOUT);
153 if (!rc) {
154 DEBUG_PRINT_ERROR("Poll timedout\n");
155 break;
156 } else if (rc < 0) {
157 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
158 break;
159 }
160 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
161 struct vdec_msginfo vdec_msg;
162 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
163 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
164 v4l2_buf.length = omx->drv_ctx.num_planes;
165 v4l2_buf.m.planes = plane;
166 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
167 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
168 vdec_msg.status_code=VDEC_S_SUCCESS;
169 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
170 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
171 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
Eric (Quicee1674a2012-12-21 15:29:08 -0800172 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
173 (uint64_t)v4l2_buf.timestamp.tv_usec;
Vinay Kalia592e4b42012-12-19 15:55:47 -0800174 if (vdec_msg.msgdata.output_frame.len) {
175 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
176 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
177 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
178 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
179 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700180 if (omx->async_message_process(input,&vdec_msg) < 0) {
181 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
182 break;
183 }
184 }
185 }
186 if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
187 struct vdec_msginfo vdec_msg;
188 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
189 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
190 v4l2_buf.length = 1;
191 v4l2_buf.m.planes = plane;
192 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
193 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
194 vdec_msg.status_code=VDEC_S_SUCCESS;
195 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
196 if (omx->async_message_process(input,&vdec_msg) < 0) {
197 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
198 break;
199 }
200 }
201 }
202 if (pfd.revents & POLLPRI){
203 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700204 if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700205 struct vdec_msginfo vdec_msg;
206 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
207 vdec_msg.status_code=VDEC_S_SUCCESS;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700208 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
209 if (omx->async_message_process(input,&vdec_msg) < 0) {
210 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
211 break;
212 }
213 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) {
214 struct vdec_msginfo vdec_msg;
215 vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
216 vdec_msg.status_code=VDEC_S_SUCCESS;
217 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700218 if (omx->async_message_process(input,&vdec_msg) < 0) {
219 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
220 break;
221 }
222 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
223 struct vdec_msginfo vdec_msg;
224 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
225 vdec_msg.status_code=VDEC_S_SUCCESS;
226 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
227 if (omx->async_message_process(input,&vdec_msg) < 0) {
228 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
229 break;
230 }
231 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
232 vdec_msg.status_code=VDEC_S_SUCCESS;
233 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
234 if (omx->async_message_process(input,&vdec_msg) < 0) {
235 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
236 break;
237 }
238 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
239 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
240 break;
241 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
242 struct vdec_msginfo vdec_msg;
243 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
244 vdec_msg.status_code=VDEC_S_SUCCESS;
245 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
246 if (omx->async_message_process(input,&vdec_msg) < 0) {
247 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
248 break;
249 }
250 } else {
251 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
252 continue;
253 }
254 }
255 }
256 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
257 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700258}
259
260void* message_thread(void *input)
261{
262 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
263 unsigned char id;
264 int n;
265
266 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
267 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
268 while (1)
269 {
270
271 n = read(omx->m_pipe_in, &id, 1);
272
273 if(0 == n)
274 {
275 break;
276 }
277
278 if (1 == n)
279 {
280 omx->process_event_cb(omx, id);
281 }
282 if ((n < 0) && (errno != EINTR))
283 {
284 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
285 break;
286 }
287 }
288 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
289 return 0;
290}
291
292void post_message(omx_vdec *omx, unsigned char id)
293{
294 int ret_value;
295 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
296 ret_value = write(omx->m_pipe_out, &id, 1);
297 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
298}
299
300// omx_cmd_queue destructor
301omx_vdec::omx_cmd_queue::~omx_cmd_queue()
302{
303 // Nothing to do
304}
305
306// omx cmd queue constructor
307omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
308{
309 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
310}
311
312// omx cmd queue insert
313bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
314{
315 bool ret = true;
316 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
317 {
318 m_q[m_write].id = id;
319 m_q[m_write].param1 = p1;
320 m_q[m_write].param2 = p2;
321 m_write++;
322 m_size ++;
323 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
324 {
325 m_write = 0;
326 }
327 }
328 else
329 {
330 ret = false;
331 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
332 }
333 return ret;
334}
335
336// omx cmd queue pop
337bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
338{
339 bool ret = true;
340 if (m_size > 0)
341 {
342 *id = m_q[m_read].id;
343 *p1 = m_q[m_read].param1;
344 *p2 = m_q[m_read].param2;
345 // Move the read pointer ahead
346 ++m_read;
347 --m_size;
348 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
349 {
350 m_read = 0;
351 }
352 }
353 else
354 {
355 ret = false;
356 }
357 return ret;
358}
359
360// Retrieve the first mesg type in the queue
361unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
362{
363 return m_q[m_read].id;
364}
365
366#ifdef _ANDROID_
367omx_vdec::ts_arr_list::ts_arr_list()
368{
369 //initialize timestamps array
370 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
371}
372omx_vdec::ts_arr_list::~ts_arr_list()
373{
374 //free m_ts_arr_list?
375}
376
377bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
378{
379 bool ret = true;
380 bool duplicate_ts = false;
381 int idx = 0;
382
383 //insert at the first available empty location
384 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
385 {
386 if (!m_ts_arr_list[idx].valid)
387 {
388 //found invalid or empty entry, save timestamp
389 m_ts_arr_list[idx].valid = true;
390 m_ts_arr_list[idx].timestamp = ts;
391 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
392 ts, idx);
393 break;
394 }
395 }
396
397 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
398 {
399 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
400 ret = false;
401 }
402 return ret;
403}
404
405bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
406{
407 bool ret = true;
408 int min_idx = -1;
409 OMX_TICKS min_ts = 0;
410 int idx = 0;
411
412 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
413 {
414
415 if (m_ts_arr_list[idx].valid)
416 {
417 //found valid entry, save index
418 if (min_idx < 0)
419 {
420 //first valid entry
421 min_ts = m_ts_arr_list[idx].timestamp;
422 min_idx = idx;
423 }
424 else if (m_ts_arr_list[idx].timestamp < min_ts)
425 {
426 min_ts = m_ts_arr_list[idx].timestamp;
427 min_idx = idx;
428 }
429 }
430
431 }
432
433 if (min_idx < 0)
434 {
435 //no valid entries found
436 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
437 ts = 0;
438 ret = false;
439 }
440 else
441 {
442 ts = m_ts_arr_list[min_idx].timestamp;
443 m_ts_arr_list[min_idx].valid = false;
444 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
445 ts, min_idx);
446 }
447
448 return ret;
449
450}
451
452
453bool omx_vdec::ts_arr_list::reset_ts_list()
454{
455 bool ret = true;
456 int idx = 0;
457
458 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
459 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
460 {
461 m_ts_arr_list[idx].valid = false;
462 }
463 return ret;
464}
465#endif
466
467// factory function executed by the core to create instances
468void *get_omx_component_factory_fn(void)
469{
470 return (new omx_vdec);
471}
472
473#ifdef _ANDROID_
474#ifdef USE_ION
475VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
476 struct ion_handle *handle, int ionMapfd)
477{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700478// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700479}
480#else
481VideoHeap::VideoHeap(int fd, size_t size, void* base)
482{
483 // dup file descriptor, map once, use pmem
484 init(dup(fd), base, size, 0 , MEM_DEVICE);
485}
486#endif
487#endif // _ANDROID_
488/* ======================================================================
489FUNCTION
490 omx_vdec::omx_vdec
491
492DESCRIPTION
493 Constructor
494
495PARAMETERS
496 None
497
498RETURN VALUE
499 None.
500========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800501omx_vdec::omx_vdec(): m_error_propogated(false),
502 m_state(OMX_StateInvalid),
503 m_app_data(NULL),
504 m_inp_mem_ptr(NULL),
505 m_out_mem_ptr(NULL),
506 m_inp_err_count(0),
507 input_flush_progress (false),
508 output_flush_progress (false),
509 input_use_buffer (false),
510 output_use_buffer (false),
511 ouput_egl_buffers(false),
512 m_use_output_pmem(OMX_FALSE),
513 m_out_mem_region_smi(OMX_FALSE),
514 m_out_pvt_entry_pmem(OMX_FALSE),
515 pending_input_buffers(0),
516 pending_output_buffers(0),
517 m_out_bm_count(0),
518 m_inp_bm_count(0),
519 m_inp_bPopulated(OMX_FALSE),
520 m_out_bPopulated(OMX_FALSE),
521 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700522#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800523 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700524#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800525 m_inp_bEnabled(OMX_TRUE),
526 m_out_bEnabled(OMX_TRUE),
527 m_in_alloc_cnt(0),
528 m_platform_list(NULL),
529 m_platform_entry(NULL),
530 m_pmem_info(NULL),
531 arbitrary_bytes (true),
532 psource_frame (NULL),
533 pdest_frame (NULL),
534 m_inp_heap_ptr (NULL),
535 m_phdr_pmem_ptr(NULL),
536 m_heap_inp_bm_count (0),
537 codec_type_parse ((codec_type)0),
538 first_frame_meta (true),
539 frame_count (0),
540 nal_count (0),
541 nal_length(0),
542 look_ahead_nal (false),
543 first_frame(0),
544 first_buffer(NULL),
545 first_frame_size (0),
546 m_device_file_ptr(NULL),
547 m_vc1_profile((vc1_profile_type)0),
548 h264_last_au_ts(LLONG_MAX),
549 h264_last_au_flags(0),
550 prev_ts(LLONG_MAX),
551 rst_prev_ts(true),
552 frm_int(0),
553 in_reconfig(false),
554 m_display_id(NULL),
555 h264_parser(NULL),
556 client_extradata(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700557#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800558 m_enable_android_native_buffers(OMX_FALSE),
559 m_use_android_native_buffers(OMX_FALSE),
560 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700561#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800562 m_desc_buffer_ptr(NULL),
563 secure_mode(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700564{
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 }
Shalaj Jain286b0062013-02-21 20:35:48 -0800577 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700578 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);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800584 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700585 }
586
Shalaj Jain286b0062013-02-21 20:35:48 -0800587 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700588 property_get("vidc.dec.debug.concealedmb", property_value, "0");
589 m_debug_concealedmb = atoi(property_value);
590 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
591
592#endif
593 memset(&m_cmp,0,sizeof(m_cmp));
594 memset(&m_cb,0,sizeof(m_cb));
595 memset (&drv_ctx,0,sizeof(drv_ctx));
596 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
597 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700598 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
599 m_demux_entries = 0;
600#ifdef _ANDROID_ICS_
601 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
602#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700603 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700604 drv_ctx.timestamp_adjust = false;
605 drv_ctx.video_driver_fd = -1;
606 m_vendor_config.pData = NULL;
607 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800608 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700609 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800610 streaming[CAPTURE_PORT] =
611 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700612#ifdef _ANDROID_
613 char extradata_value[PROPERTY_VALUE_MAX] = {0};
614 property_get("vidc.dec.debug.extradata", extradata_value, "0");
615 m_debug_extradata = atoi(extradata_value);
616 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
617#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800618 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
619 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700620}
621
Vinay Kalia85793762012-06-14 19:12:34 -0700622static const int event_type[] = {
623 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
624 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
625 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700626 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
627 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700628};
629
630static OMX_ERRORTYPE subscribe_to_events(int fd)
631{
632 OMX_ERRORTYPE eRet = OMX_ErrorNone;
633 struct v4l2_event_subscription sub;
634 int array_sz = sizeof(event_type)/sizeof(int);
635 int i,rc;
636 if (fd < 0) {
637 printf("Invalid input: %d\n", fd);
638 return OMX_ErrorBadParameter;
639 }
640
641 for (i = 0; i < array_sz; ++i) {
642 memset(&sub, 0, sizeof(sub));
643 sub.type = event_type[i];
644 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
645 if (rc) {
646 printf("Failed to subscribe event: 0x%x\n", sub.type);
647 break;
648 }
649 }
650 if (i < array_sz) {
651 for (--i; i >=0 ; i--) {
652 memset(&sub, 0, sizeof(sub));
653 sub.type = event_type[i];
654 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
655 if (rc)
656 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
657 }
658 eRet = OMX_ErrorNotImplemented;
659 }
660 return eRet;
661}
662
663
664static OMX_ERRORTYPE unsubscribe_to_events(int fd)
665{
666 OMX_ERRORTYPE eRet = OMX_ErrorNone;
667 struct v4l2_event_subscription sub;
668 int array_sz = sizeof(event_type)/sizeof(int);
669 int i,rc;
670 if (fd < 0) {
671 printf("Invalid input: %d\n", fd);
672 return OMX_ErrorBadParameter;
673 }
674
675 for (i = 0; i < array_sz; ++i) {
676 memset(&sub, 0, sizeof(sub));
677 sub.type = event_type[i];
678 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
679 if (rc) {
680 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
681 break;
682 }
683 }
684 return eRet;
685}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700686
687/* ======================================================================
688FUNCTION
689 omx_vdec::~omx_vdec
690
691DESCRIPTION
692 Destructor
693
694PARAMETERS
695 None
696
697RETURN VALUE
698 None.
699========================================================================== */
700omx_vdec::~omx_vdec()
701{
702 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700703 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700704 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
705 if(m_pipe_in) close(m_pipe_in);
706 if(m_pipe_out) close(m_pipe_out);
707 m_pipe_in = -1;
708 m_pipe_out = -1;
709 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
710 pthread_join(msg_thread_id,NULL);
711 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700712 dec.cmd = V4L2_DEC_CMD_STOP;
713 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
714 {
715 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
716 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700717 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700718 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700719 close(drv_ctx.video_driver_fd);
720 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800721 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700722 sem_destroy(&m_cmd_lock);
723 if (perf_flag)
724 {
725 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
726 dec_time.end();
727 }
728 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
729}
730
Vinay Kaliafeef7032012-09-25 19:23:33 -0700731int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
732 struct v4l2_requestbuffers bufreq;
733 int rc = 0;
734 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
735 bufreq.memory = V4L2_MEMORY_USERPTR;
736 bufreq.count = 0;
737 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
738 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
739 }
740 return rc;
741}
742
Shalaj Jain273b3e02012-06-22 19:08:03 -0700743/* ======================================================================
744FUNCTION
745 omx_vdec::OMXCntrlProcessMsgCb
746
747DESCRIPTION
748 IL Client callbacks are generated through this routine. The decoder
749 provides the thread context for this routine.
750
751PARAMETERS
752 ctxt -- Context information related to the self.
753 id -- Event identifier. This could be any of the following:
754 1. Command completion event
755 2. Buffer done callback event
756 3. Frame done callback event
757
758RETURN VALUE
759 None.
760
761========================================================================== */
762void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
763{
Shalaj Jain286b0062013-02-21 20:35:48 -0800764 signed p1; // Parameter - 1
765 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700766 unsigned ident;
767 unsigned qsize=0; // qsize
768 omx_vdec *pThis = (omx_vdec *) ctxt;
769
770 if(!pThis)
771 {
772 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
773 __func__);
774 return;
775 }
776
777 // Protect the shared queue data structure
778 do
779 {
780 /*Read the message id's from the queue*/
781 pthread_mutex_lock(&pThis->m_lock);
782 qsize = pThis->m_cmd_q.m_size;
783 if(qsize)
784 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800785 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700786 }
787
788 if (qsize == 0 && pThis->m_state != OMX_StatePause)
789 {
790 qsize = pThis->m_ftb_q.m_size;
791 if (qsize)
792 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800793 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700794 }
795 }
796
797 if (qsize == 0 && pThis->m_state != OMX_StatePause)
798 {
799 qsize = pThis->m_etb_q.m_size;
800 if (qsize)
801 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800802 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803 }
804 }
805 pthread_mutex_unlock(&pThis->m_lock);
806
807 /*process message if we have one*/
808 if(qsize > 0)
809 {
810 id = ident;
811 switch (id)
812 {
813 case OMX_COMPONENT_GENERATE_EVENT:
814 if (pThis->m_cb.EventHandler)
815 {
816 switch (p1)
817 {
818 case OMX_CommandStateSet:
819 pThis->m_state = (OMX_STATETYPE) p2;
820 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
821 pThis->m_state);
822 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
823 OMX_EventCmdComplete, p1, p2, NULL);
824 break;
825
826 case OMX_EventError:
827 if(p2 == OMX_StateInvalid)
828 {
829 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
830 pThis->m_state = (OMX_STATETYPE) p2;
831 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
832 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
833 }
834 else if (p2 == OMX_ErrorHardware)
835 {
836 pThis->omx_report_error();
837 }
838 else
839 {
840 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800841 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700842 }
843 break;
844
845 case OMX_CommandPortDisable:
846 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
847 if (BITMASK_PRESENT(&pThis->m_flags,
848 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
849 {
850 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
851 break;
852 }
853 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
854 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700855 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700856 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700857 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
858 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
859 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700860 pThis->in_reconfig = false;
861 if(eRet != OMX_ErrorNone)
862 {
863 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
864 pThis->omx_report_error();
865 break;
866 }
867 }
868 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
869 OMX_EventCmdComplete, p1, p2, NULL );
870 break;
871 case OMX_CommandPortEnable:
872 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
873 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
874 OMX_EventCmdComplete, p1, p2, NULL );
875 break;
876
877 default:
878 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
879 OMX_EventCmdComplete, p1, p2, NULL );
880 break;
881
882 }
883 }
884 else
885 {
886 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
887 }
888 break;
889 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
890 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
891 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
892 {
893 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
894 pThis->omx_report_error ();
895 }
896 break;
897 case OMX_COMPONENT_GENERATE_ETB:
898 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
899 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
900 {
901 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
902 pThis->omx_report_error ();
903 }
904 break;
905
906 case OMX_COMPONENT_GENERATE_FTB:
907 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
908 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
909 {
910 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
911 pThis->omx_report_error ();
912 }
913 break;
914
915 case OMX_COMPONENT_GENERATE_COMMAND:
916 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
917 (OMX_U32)p2,(OMX_PTR)NULL);
918 break;
919
920 case OMX_COMPONENT_GENERATE_EBD:
921
922 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
923 {
924 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
925 pThis->omx_report_error ();
926 }
927 else
928 {
929 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
930 {
931 pThis->m_inp_err_count++;
932 pThis->time_stamp_dts.remove_time_stamp(
933 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
934 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
935 ?true:false);
936 }
937 else
938 {
939 pThis->m_inp_err_count = 0;
940 }
941 if ( pThis->empty_buffer_done(&pThis->m_cmp,
942 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
943 {
944 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
945 pThis->omx_report_error ();
946 }
947 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
948 {
949 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
950 pThis->omx_report_error ();
951 }
952 }
953 break;
954 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
955 {
956 int64_t *timestamp = (int64_t *)p1;
957 if (p1)
958 {
959 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
960 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
961 ?true:false);
962 free(timestamp);
963 }
964 }
965 break;
966 case OMX_COMPONENT_GENERATE_FBD:
967 if (p2 != VDEC_S_SUCCESS)
968 {
969 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
970 pThis->omx_report_error ();
971 }
972 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
973 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
974 {
975 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
976 pThis->omx_report_error ();
977 }
978 break;
979
980 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
981 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
982 if (!pThis->input_flush_progress)
983 {
984 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
985 }
986 else
987 {
988 pThis->execute_input_flush();
989 if (pThis->m_cb.EventHandler)
990 {
991 if (p2 != VDEC_S_SUCCESS)
992 {
993 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
994 pThis->omx_report_error ();
995 }
996 else
997 {
998 /*Check if we need generate event for Flush done*/
999 if(BITMASK_PRESENT(&pThis->m_flags,
1000 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1001 {
1002 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1003 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1004 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1005 OMX_EventCmdComplete,OMX_CommandFlush,
1006 OMX_CORE_INPUT_PORT_INDEX,NULL );
1007 }
1008 if (BITMASK_PRESENT(&pThis->m_flags,
1009 OMX_COMPONENT_IDLE_PENDING))
1010 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001011 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001012 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1013 pThis->omx_report_error ();
1014 } else {
1015 pThis->streaming[OUTPUT_PORT] = false;
1016 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001017 if (!pThis->output_flush_progress)
1018 {
Vinay Kalia22046272012-09-28 20:16:05 -07001019 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001020 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001021 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001022 }
1023 }
1024 }
1025 }
1026 else
1027 {
1028 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1029 }
1030 }
1031 break;
1032
1033 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1034 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1035 if (!pThis->output_flush_progress)
1036 {
1037 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1038 }
1039 else
1040 {
1041 pThis->execute_output_flush();
1042 if (pThis->m_cb.EventHandler)
1043 {
1044 if (p2 != VDEC_S_SUCCESS)
1045 {
1046 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1047 pThis->omx_report_error ();
1048 }
1049 else
1050 {
1051 /*Check if we need generate event for Flush done*/
1052 if(BITMASK_PRESENT(&pThis->m_flags,
1053 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1054 {
1055 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1056 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1057 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1058 OMX_EventCmdComplete,OMX_CommandFlush,
1059 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1060 }
1061 if(BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1063 {
1064 DEBUG_PRINT_LOW("\n Internal flush complete");
1065 BITMASK_CLEAR (&pThis->m_flags,
1066 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1067 if (BITMASK_PRESENT(&pThis->m_flags,
1068 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1069 {
1070 pThis->post_event(OMX_CommandPortDisable,
1071 OMX_CORE_OUTPUT_PORT_INDEX,
1072 OMX_COMPONENT_GENERATE_EVENT);
1073 BITMASK_CLEAR (&pThis->m_flags,
1074 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1075
1076 }
1077 }
1078
1079 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1080 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001081 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001082 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1083 pThis->omx_report_error ();
1084 break;
1085 }
1086 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001087 if (!pThis->input_flush_progress)
1088 {
Vinay Kalia22046272012-09-28 20:16:05 -07001089 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001090 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001091 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001092 }
1093 }
1094 }
1095 }
1096 else
1097 {
1098 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1099 }
1100 }
1101 break;
1102
1103 case OMX_COMPONENT_GENERATE_START_DONE:
1104 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1105
1106 if (pThis->m_cb.EventHandler)
1107 {
1108 if (p2 != VDEC_S_SUCCESS)
1109 {
1110 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1111 pThis->omx_report_error ();
1112 }
1113 else
1114 {
1115 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1116 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1117 {
1118 DEBUG_PRINT_LOW("\n Move to executing");
1119 // Send the callback now
1120 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1121 pThis->m_state = OMX_StateExecuting;
1122 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1123 OMX_EventCmdComplete,OMX_CommandStateSet,
1124 OMX_StateExecuting, NULL);
1125 }
1126 else if (BITMASK_PRESENT(&pThis->m_flags,
1127 OMX_COMPONENT_PAUSE_PENDING))
1128 {
1129 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1130 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1131 {
1132 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1133 pThis->omx_report_error ();
1134 }
1135 }
1136 }
1137 }
1138 else
1139 {
1140 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1141 }
1142 break;
1143
1144 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1145 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1146 if (pThis->m_cb.EventHandler)
1147 {
1148 if (p2 != VDEC_S_SUCCESS)
1149 {
1150 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1151 pThis->omx_report_error ();
1152 }
1153 else
1154 {
1155 pThis->complete_pending_buffer_done_cbs();
1156 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1157 {
1158 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1159 //Send the callback now
1160 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1161 pThis->m_state = OMX_StatePause;
1162 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1163 OMX_EventCmdComplete,OMX_CommandStateSet,
1164 OMX_StatePause, NULL);
1165 }
1166 }
1167 }
1168 else
1169 {
1170 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1171 }
1172
1173 break;
1174
1175 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1176 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1177 if (pThis->m_cb.EventHandler)
1178 {
1179 if (p2 != VDEC_S_SUCCESS)
1180 {
1181 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1182 pThis->omx_report_error ();
1183 }
1184 else
1185 {
1186 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1187 {
1188 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1189 // Send the callback now
1190 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1191 pThis->m_state = OMX_StateExecuting;
1192 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1193 OMX_EventCmdComplete,OMX_CommandStateSet,
1194 OMX_StateExecuting,NULL);
1195 }
1196 }
1197 }
1198 else
1199 {
1200 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1201 }
1202
1203 break;
1204
1205 case OMX_COMPONENT_GENERATE_STOP_DONE:
1206 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1207 if (pThis->m_cb.EventHandler)
1208 {
1209 if (p2 != VDEC_S_SUCCESS)
1210 {
1211 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1212 pThis->omx_report_error ();
1213 }
1214 else
1215 {
1216 pThis->complete_pending_buffer_done_cbs();
1217 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1218 {
1219 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1220 // Send the callback now
1221 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1222 pThis->m_state = OMX_StateIdle;
1223 DEBUG_PRINT_LOW("\n Move to Idle State");
1224 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1225 OMX_EventCmdComplete,OMX_CommandStateSet,
1226 OMX_StateIdle,NULL);
1227 }
1228 }
1229 }
1230 else
1231 {
1232 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1233 }
1234
1235 break;
1236
1237 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1238 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001239
Vinay Kalia592e4b42012-12-19 15:55:47 -08001240 if (p2 == OMX_IndexParamPortDefinition) {
1241 pThis->in_reconfig = true;
1242 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001243 if (pThis->m_cb.EventHandler) {
1244 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001246 } else {
1247 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1248 }
1249
1250 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001251 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001252 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1253 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1254 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1255 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1256 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1257 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1258 else //unsupported interlace format; raise a error
1259 event = OMX_EventError;
1260 if (pThis->m_cb.EventHandler) {
1261 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1262 event, format, 0, NULL );
1263 } else {
1264 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001265 }
1266 }
1267 break;
1268
1269 case OMX_COMPONENT_GENERATE_EOS_DONE:
1270 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1271 if (pThis->m_cb.EventHandler) {
1272 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1273 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1274 } else {
1275 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1276 }
1277 pThis->prev_ts = LLONG_MAX;
1278 pThis->rst_prev_ts = true;
1279 break;
1280
1281 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1282 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1283 pThis->omx_report_error ();
1284 break;
1285 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1286 {
1287 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1288 if (pThis->m_cb.EventHandler) {
1289 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1290 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1291 } else {
1292 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1293 }
1294 }
1295 default:
1296 break;
1297 }
1298 }
1299 pthread_mutex_lock(&pThis->m_lock);
1300 qsize = pThis->m_cmd_q.m_size;
1301 if (pThis->m_state != OMX_StatePause)
1302 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1303 pthread_mutex_unlock(&pThis->m_lock);
1304 }
1305 while(qsize>0);
1306
1307}
1308
Vinay Kalia592e4b42012-12-19 15:55:47 -08001309void omx_vdec::update_resolution(int width, int height)
1310{
1311 drv_ctx.video_resolution.frame_height = height;
1312 drv_ctx.video_resolution.frame_width = width;
1313 drv_ctx.video_resolution.scan_lines = height;
1314 drv_ctx.video_resolution.stride = width;
1315 rectangle.nLeft = 0;
1316 rectangle.nTop = 0;
1317 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1318 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1319}
1320
Shalaj Jain273b3e02012-06-22 19:08:03 -07001321/* ======================================================================
1322FUNCTION
1323 omx_vdec::ComponentInit
1324
1325DESCRIPTION
1326 Initialize the component.
1327
1328PARAMETERS
1329 ctxt -- Context information related to the self.
1330 id -- Event identifier. This could be any of the following:
1331 1. Command completion event
1332 2. Buffer done callback event
1333 3. Frame done callback event
1334
1335RETURN VALUE
1336 None.
1337
1338========================================================================== */
1339OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1340{
1341
1342 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001343 struct v4l2_fmtdesc fdesc;
1344 struct v4l2_format fmt;
1345 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001346 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001347 unsigned int alignment = 0,buffer_size = 0;
1348 int fds[2];
1349 int r,ret=0;
1350 bool codec_ambiguous = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001351 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001352 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1353 struct v4l2_control control;
1354 secure_mode = true;
1355 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001356 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001357 }
1358
Shalaj Jain273b3e02012-06-22 19:08:03 -07001359 drv_ctx.video_driver_fd = open("/dev/video32", O_RDWR);
1360
1361 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1362 drv_ctx.video_driver_fd, errno);
1363
1364 if(drv_ctx.video_driver_fd == 0){
1365 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1366 }
1367
1368 if(drv_ctx.video_driver_fd < 0)
1369 {
1370 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1371 return OMX_ErrorInsufficientResources;
1372 }
1373 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1374 drv_ctx.frame_rate.fps_denominator = 1;
1375
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001376 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1377 if(ret < 0) {
1378 close(drv_ctx.video_driver_fd);
1379 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1380 return OMX_ErrorInsufficientResources;
1381 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001382
1383#ifdef INPUT_BUFFER_LOG
1384 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1385#endif
1386#ifdef OUTPUT_BUFFER_LOG
1387 outputBufferFile1 = fopen (outputfilename, "ab");
1388#endif
1389#ifdef OUTPUT_EXTRADATA_LOG
1390 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1391#endif
1392
1393 // Copy the role information which provides the decoder kind
1394 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001395
Shalaj Jain273b3e02012-06-22 19:08:03 -07001396 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1397 OMX_MAX_STRINGNAME_SIZE))
1398 {
1399 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1400 OMX_MAX_STRINGNAME_SIZE);
1401 drv_ctx.timestamp_adjust = true;
1402 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1403 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001404 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001405 /*Initialize Start Code for MPEG4*/
1406 codec_type_parse = CODEC_TYPE_MPEG4;
1407 m_frame_parser.init_start_codes (codec_type_parse);
1408#ifdef INPUT_BUFFER_LOG
1409 strcat(inputfilename, "m4v");
1410#endif
1411 }
1412 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1413 OMX_MAX_STRINGNAME_SIZE))
1414 {
1415 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1416 OMX_MAX_STRINGNAME_SIZE);
1417 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001418 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001419 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1420 /*Initialize Start Code for MPEG2*/
1421 codec_type_parse = CODEC_TYPE_MPEG2;
1422 m_frame_parser.init_start_codes (codec_type_parse);
1423#ifdef INPUT_BUFFER_LOG
1424 strcat(inputfilename, "mpg");
1425#endif
1426 }
1427 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1428 OMX_MAX_STRINGNAME_SIZE))
1429 {
1430 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1431 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1432 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1433 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001434 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001435 codec_type_parse = CODEC_TYPE_H263;
1436 m_frame_parser.init_start_codes (codec_type_parse);
1437#ifdef INPUT_BUFFER_LOG
1438 strcat(inputfilename, "263");
1439#endif
1440 }
1441 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1442 OMX_MAX_STRINGNAME_SIZE))
1443 {
1444 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1445 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1446 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1447 output_capability = V4L2_PIX_FMT_DIVX_311;
1448 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1449 codec_type_parse = CODEC_TYPE_DIVX;
1450 m_frame_parser.init_start_codes (codec_type_parse);
1451
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001452 eRet = createDivxDrmContext();
1453 if (eRet != OMX_ErrorNone) {
1454 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1455 return eRet;
1456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457 }
1458 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1459 OMX_MAX_STRINGNAME_SIZE))
1460 {
1461 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1462 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1463 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1464 output_capability = V4L2_PIX_FMT_DIVX;
1465 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1466 codec_type_parse = CODEC_TYPE_DIVX;
1467 codec_ambiguous = true;
1468 m_frame_parser.init_start_codes (codec_type_parse);
1469
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001470 eRet = createDivxDrmContext();
1471 if (eRet != OMX_ErrorNone) {
1472 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1473 return eRet;
1474 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001475 }
1476 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1477 OMX_MAX_STRINGNAME_SIZE))
1478 {
1479 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1480 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1481 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1482 output_capability = V4L2_PIX_FMT_DIVX;
1483 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1484 codec_type_parse = CODEC_TYPE_DIVX;
1485 codec_ambiguous = true;
1486 m_frame_parser.init_start_codes (codec_type_parse);
1487
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001488 eRet = createDivxDrmContext();
1489 if (eRet != OMX_ErrorNone) {
1490 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1491 return eRet;
1492 }
1493
Shalaj Jain273b3e02012-06-22 19:08:03 -07001494 }
1495 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1496 OMX_MAX_STRINGNAME_SIZE))
1497 {
1498 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1499 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1500 output_capability=V4L2_PIX_FMT_H264;
1501 eCompressionFormat = OMX_VIDEO_CodingAVC;
1502 codec_type_parse = CODEC_TYPE_H264;
1503 m_frame_parser.init_start_codes (codec_type_parse);
1504 m_frame_parser.init_nal_length(nal_length);
1505#ifdef INPUT_BUFFER_LOG
1506 strcat(inputfilename, "264");
1507#endif
1508 }
1509 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1510 OMX_MAX_STRINGNAME_SIZE))
1511 {
1512 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1513 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1514 eCompressionFormat = OMX_VIDEO_CodingWMV;
1515 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001516 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001517 m_frame_parser.init_start_codes (codec_type_parse);
1518#ifdef INPUT_BUFFER_LOG
1519 strcat(inputfilename, "vc1");
1520#endif
1521 }
1522 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1523 OMX_MAX_STRINGNAME_SIZE))
1524 {
1525 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1526 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1527 eCompressionFormat = OMX_VIDEO_CodingWMV;
1528 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001529 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001530 m_frame_parser.init_start_codes (codec_type_parse);
1531#ifdef INPUT_BUFFER_LOG
1532 strcat(inputfilename, "vc1");
1533#endif
1534 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001535 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1536 OMX_MAX_STRINGNAME_SIZE))
1537 {
1538 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1539 output_capability=V4L2_PIX_FMT_VP8;
1540 eCompressionFormat = OMX_VIDEO_CodingVPX;
1541 codec_type_parse = CODEC_TYPE_VP8;
1542 arbitrary_bytes = false;
1543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001544 else
1545 {
1546 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1547 eRet = OMX_ErrorInvalidComponentName;
1548 }
1549#ifdef INPUT_BUFFER_LOG
1550 inputBufferFile1 = fopen (inputfilename, "ab");
1551#endif
1552 if (eRet == OMX_ErrorNone)
1553 {
1554
Vinay Kaliada4f4422013-01-09 10:45:03 -08001555 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1556 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1557 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1558 if (!client_buffers.set_color_format(dest_color_format)) {
1559 DEBUG_PRINT_ERROR("\n Setting color format failed");
1560 eRet = OMX_ErrorInsufficientResources;
1561 }
1562
Shalaj Jain273b3e02012-06-22 19:08:03 -07001563 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001564 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001565 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001566 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1567 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001568 }
1569
1570 struct v4l2_capability cap;
1571 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1572 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001573 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001574 /*TODO: How to handle this case */
1575 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001576 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001577 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1578 cap.bus_info, cap.version, cap.capabilities);
1579 }
1580 ret=0;
1581 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1582 fdesc.index=0;
1583 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001584 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001585 fdesc.pixelformat, fdesc.flags);
1586 fdesc.index++;
1587 }
1588 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1589 fdesc.index=0;
1590 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1591
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001592 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001593 fdesc.pixelformat, fdesc.flags);
1594 fdesc.index++;
1595 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001596 update_resolution(320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001597 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1598 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1599 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1600 fmt.fmt.pix_mp.pixelformat = output_capability;
1601 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1602 if (ret) {
1603 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001604 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001606 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001607 if (codec_ambiguous) {
1608 if (output_capability == V4L2_PIX_FMT_DIVX) {
1609 struct v4l2_control divx_ctrl;
1610
1611 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001612 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001613 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001614 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001615 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001616 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001617 }
1618
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001619 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001620 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001621 if (ret) {
1622 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1623 }
1624 } else {
1625 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1626 }
1627 }
1628
1629 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1630 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1631 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001632 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001633 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1634 if (ret) {
1635 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001636 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001638 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001639 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001640 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1641 control.value = 1;
1642 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1643 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1644 if (ret) {
1645 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1646 close(drv_ctx.video_driver_fd);
1647 return OMX_ErrorInsufficientResources;
1648 }
1649 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001650
1651 /*Get the Buffer requirements for input and output ports*/
1652 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1653 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001654 if (secure_mode) {
1655 drv_ctx.op_buf.alignment=SZ_1M;
1656 drv_ctx.ip_buf.alignment=SZ_1M;
1657 } else {
1658 drv_ctx.op_buf.alignment=SZ_4K;
1659 drv_ctx.ip_buf.alignment=SZ_4K;
1660 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001661 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1662 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001663 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1664 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1665 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1666 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001667 drv_ctx.idr_only_decoding = 0;
1668
Vinay Kalia5713bb32013-01-16 18:39:59 -08001669 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001670#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001671 if (eRet == OMX_ErrorNone && !secure_mode)
1672 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001674 eRet=get_buffer_req(&drv_ctx.ip_buf);
1675 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1676 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001677 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1678 {
1679 if (m_frame_parser.mutils == NULL)
1680 {
1681 m_frame_parser.mutils = new H264_Utils();
1682
1683 if (m_frame_parser.mutils == NULL)
1684 {
1685 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1686 eRet = OMX_ErrorInsufficientResources;
1687 }
1688 else
1689 {
1690 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1691 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1692 h264_scratch.nFilledLen = 0;
1693 h264_scratch.nOffset = 0;
1694
1695 if (h264_scratch.pBuffer == NULL)
1696 {
1697 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1698 return OMX_ErrorInsufficientResources;
1699 }
1700 m_frame_parser.mutils->initialize_frame_checking_environment();
1701 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1702 }
1703 }
1704
1705 h264_parser = new h264_stream_parser();
1706 if (!h264_parser)
1707 {
1708 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1709 eRet = OMX_ErrorInsufficientResources;
1710 }
1711 }
1712
1713 if(pipe(fds))
1714 {
1715 DEBUG_PRINT_ERROR("pipe creation failed\n");
1716 eRet = OMX_ErrorInsufficientResources;
1717 }
1718 else
1719 {
1720 int temp1[2];
1721 if(fds[0] == 0 || fds[1] == 0)
1722 {
1723 if (pipe (temp1))
1724 {
1725 DEBUG_PRINT_ERROR("pipe creation failed\n");
1726 return OMX_ErrorInsufficientResources;
1727 }
1728 //close (fds[0]);
1729 //close (fds[1]);
1730 fds[0] = temp1 [0];
1731 fds[1] = temp1 [1];
1732 }
1733 m_pipe_in = fds[0];
1734 m_pipe_out = fds[1];
1735 r = pthread_create(&msg_thread_id,0,message_thread,this);
1736
1737 if(r < 0)
1738 {
1739 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1740 eRet = OMX_ErrorInsufficientResources;
1741 }
1742 }
1743 }
1744
1745 if (eRet != OMX_ErrorNone)
1746 {
1747 DEBUG_PRINT_ERROR("\n Component Init Failed");
1748 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1749 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1750 NULL);
1751 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1752 close (drv_ctx.video_driver_fd);
1753 drv_ctx.video_driver_fd = -1;
1754 }
1755 else
1756 {
1757 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001759 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1760 return eRet;
1761}
1762
1763/* ======================================================================
1764FUNCTION
1765 omx_vdec::GetComponentVersion
1766
1767DESCRIPTION
1768 Returns the component version.
1769
1770PARAMETERS
1771 TBD.
1772
1773RETURN VALUE
1774 OMX_ErrorNone.
1775
1776========================================================================== */
1777OMX_ERRORTYPE omx_vdec::get_component_version
1778 (
1779 OMX_IN OMX_HANDLETYPE hComp,
1780 OMX_OUT OMX_STRING componentName,
1781 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1782 OMX_OUT OMX_VERSIONTYPE* specVersion,
1783 OMX_OUT OMX_UUIDTYPE* componentUUID
1784 )
1785{
1786 if(m_state == OMX_StateInvalid)
1787 {
1788 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1789 return OMX_ErrorInvalidState;
1790 }
1791 /* TBD -- Return the proper version */
1792 if (specVersion)
1793 {
1794 specVersion->nVersion = OMX_SPEC_VERSION;
1795 }
1796 return OMX_ErrorNone;
1797}
1798/* ======================================================================
1799FUNCTION
1800 omx_vdec::SendCommand
1801
1802DESCRIPTION
1803 Returns zero if all the buffers released..
1804
1805PARAMETERS
1806 None.
1807
1808RETURN VALUE
1809 true/false
1810
1811========================================================================== */
1812OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1813 OMX_IN OMX_COMMANDTYPE cmd,
1814 OMX_IN OMX_U32 param1,
1815 OMX_IN OMX_PTR cmdData
1816 )
1817{
1818 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1819 if(m_state == OMX_StateInvalid)
1820 {
1821 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1822 return OMX_ErrorInvalidState;
1823 }
1824 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1825 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1826 {
1827 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001828 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001829 return OMX_ErrorBadPortIndex;
1830 }
1831 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1832 sem_wait(&m_cmd_lock);
1833 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1834 return OMX_ErrorNone;
1835}
1836
1837/* ======================================================================
1838FUNCTION
1839 omx_vdec::SendCommand
1840
1841DESCRIPTION
1842 Returns zero if all the buffers released..
1843
1844PARAMETERS
1845 None.
1846
1847RETURN VALUE
1848 true/false
1849
1850========================================================================== */
1851OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1852 OMX_IN OMX_COMMANDTYPE cmd,
1853 OMX_IN OMX_U32 param1,
1854 OMX_IN OMX_PTR cmdData
1855 )
1856{
1857 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1858 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1859 int bFlag = 1,sem_posted = 0,ret=0;
1860
1861 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1862 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1863 m_state, eState);
1864
1865 if(cmd == OMX_CommandStateSet)
1866 {
1867 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1868 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1869 /***************************/
1870 /* Current State is Loaded */
1871 /***************************/
1872 if(m_state == OMX_StateLoaded)
1873 {
1874 if(eState == OMX_StateIdle)
1875 {
1876 //if all buffers are allocated or all ports disabled
1877 if(allocate_done() ||
1878 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1879 {
1880 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1881 }
1882 else
1883 {
1884 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1885 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1886 // Skip the event notification
1887 bFlag = 0;
1888 }
1889 }
1890 /* Requesting transition from Loaded to Loaded */
1891 else if(eState == OMX_StateLoaded)
1892 {
1893 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1894 post_event(OMX_EventError,OMX_ErrorSameState,\
1895 OMX_COMPONENT_GENERATE_EVENT);
1896 eRet = OMX_ErrorSameState;
1897 }
1898 /* Requesting transition from Loaded to WaitForResources */
1899 else if(eState == OMX_StateWaitForResources)
1900 {
1901 /* Since error is None , we will post an event
1902 at the end of this function definition */
1903 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1904 }
1905 /* Requesting transition from Loaded to Executing */
1906 else if(eState == OMX_StateExecuting)
1907 {
1908 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1909 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1910 OMX_COMPONENT_GENERATE_EVENT);
1911 eRet = OMX_ErrorIncorrectStateTransition;
1912 }
1913 /* Requesting transition from Loaded to Pause */
1914 else if(eState == OMX_StatePause)
1915 {
1916 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1917 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1918 OMX_COMPONENT_GENERATE_EVENT);
1919 eRet = OMX_ErrorIncorrectStateTransition;
1920 }
1921 /* Requesting transition from Loaded to Invalid */
1922 else if(eState == OMX_StateInvalid)
1923 {
1924 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1925 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1926 eRet = OMX_ErrorInvalidState;
1927 }
1928 else
1929 {
1930 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1931 eState);
1932 eRet = OMX_ErrorBadParameter;
1933 }
1934 }
1935
1936 /***************************/
1937 /* Current State is IDLE */
1938 /***************************/
1939 else if(m_state == OMX_StateIdle)
1940 {
1941 if(eState == OMX_StateLoaded)
1942 {
1943 if(release_done())
1944 {
1945 /*
1946 Since error is None , we will post an event at the end
1947 of this function definition
1948 */
1949 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1950 }
1951 else
1952 {
1953 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1954 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1955 // Skip the event notification
1956 bFlag = 0;
1957 }
1958 }
1959 /* Requesting transition from Idle to Executing */
1960 else if(eState == OMX_StateExecuting)
1961 {
1962 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1963 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1964 bFlag = 1;
1965 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1966 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001967 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001968 }
1969 /* Requesting transition from Idle to Idle */
1970 else if(eState == OMX_StateIdle)
1971 {
1972 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1973 post_event(OMX_EventError,OMX_ErrorSameState,\
1974 OMX_COMPONENT_GENERATE_EVENT);
1975 eRet = OMX_ErrorSameState;
1976 }
1977 /* Requesting transition from Idle to WaitForResources */
1978 else if(eState == OMX_StateWaitForResources)
1979 {
1980 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1981 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1982 OMX_COMPONENT_GENERATE_EVENT);
1983 eRet = OMX_ErrorIncorrectStateTransition;
1984 }
1985 /* Requesting transition from Idle to Pause */
1986 else if(eState == OMX_StatePause)
1987 {
1988 /*To pause the Video core we need to start the driver*/
1989 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1990 NULL) < */0)
1991 {
1992 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1993 omx_report_error ();
1994 eRet = OMX_ErrorHardware;
1995 }
1996 else
1997 {
1998 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1999 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2000 bFlag = 0;
2001 }
2002 }
2003 /* Requesting transition from Idle to Invalid */
2004 else if(eState == OMX_StateInvalid)
2005 {
2006 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2007 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2008 eRet = OMX_ErrorInvalidState;
2009 }
2010 else
2011 {
2012 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2013 eRet = OMX_ErrorBadParameter;
2014 }
2015 }
2016
2017 /******************************/
2018 /* Current State is Executing */
2019 /******************************/
2020 else if(m_state == OMX_StateExecuting)
2021 {
2022 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2023 /* Requesting transition from Executing to Idle */
2024 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002025 {
2026 /* Since error is None , we will post an event
2027 at the end of this function definition
2028 */
2029 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002030 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002031 if(!sem_posted)
2032 {
2033 sem_posted = 1;
2034 sem_post (&m_cmd_lock);
2035 execute_omx_flush(OMX_ALL);
2036 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002037 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002038 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002039 /* Requesting transition from Executing to Paused */
2040 else if(eState == OMX_StatePause)
2041 {
2042 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002043 m_state = OMX_StatePause;
2044 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002045 }
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");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002092 m_state = OMX_StateExecuting;
2093 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002094 }
2095 /* Requesting transition from Pause to Idle */
2096 else if(eState == OMX_StateIdle)
2097 {
2098 /* Since error is None , we will post an event
2099 at the end of this function definition */
2100 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2101 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2102 if(!sem_posted)
2103 {
2104 sem_posted = 1;
2105 sem_post (&m_cmd_lock);
2106 execute_omx_flush(OMX_ALL);
2107 }
2108 bFlag = 0;
2109 }
2110 /* Requesting transition from Pause to loaded */
2111 else if(eState == OMX_StateLoaded)
2112 {
2113 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2114 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2115 OMX_COMPONENT_GENERATE_EVENT);
2116 eRet = OMX_ErrorIncorrectStateTransition;
2117 }
2118 /* Requesting transition from Pause to WaitForResources */
2119 else if(eState == OMX_StateWaitForResources)
2120 {
2121 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2122 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2123 OMX_COMPONENT_GENERATE_EVENT);
2124 eRet = OMX_ErrorIncorrectStateTransition;
2125 }
2126 /* Requesting transition from Pause to Pause */
2127 else if(eState == OMX_StatePause)
2128 {
2129 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2130 post_event(OMX_EventError,OMX_ErrorSameState,\
2131 OMX_COMPONENT_GENERATE_EVENT);
2132 eRet = OMX_ErrorSameState;
2133 }
2134 /* Requesting transition from Pause to Invalid */
2135 else if(eState == OMX_StateInvalid)
2136 {
2137 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2138 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2139 eRet = OMX_ErrorInvalidState;
2140 }
2141 else
2142 {
2143 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2144 eRet = OMX_ErrorBadParameter;
2145 }
2146 }
2147 /***************************/
2148 /* Current State is WaitForResources */
2149 /***************************/
2150 else if(m_state == OMX_StateWaitForResources)
2151 {
2152 /* Requesting transition from WaitForResources to Loaded */
2153 if(eState == OMX_StateLoaded)
2154 {
2155 /* Since error is None , we will post an event
2156 at the end of this function definition */
2157 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2158 }
2159 /* Requesting transition from WaitForResources to WaitForResources */
2160 else if (eState == OMX_StateWaitForResources)
2161 {
2162 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2163 post_event(OMX_EventError,OMX_ErrorSameState,
2164 OMX_COMPONENT_GENERATE_EVENT);
2165 eRet = OMX_ErrorSameState;
2166 }
2167 /* Requesting transition from WaitForResources to Executing */
2168 else if(eState == OMX_StateExecuting)
2169 {
2170 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2171 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2172 OMX_COMPONENT_GENERATE_EVENT);
2173 eRet = OMX_ErrorIncorrectStateTransition;
2174 }
2175 /* Requesting transition from WaitForResources to Pause */
2176 else if(eState == OMX_StatePause)
2177 {
2178 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2179 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2180 OMX_COMPONENT_GENERATE_EVENT);
2181 eRet = OMX_ErrorIncorrectStateTransition;
2182 }
2183 /* Requesting transition from WaitForResources to Invalid */
2184 else if(eState == OMX_StateInvalid)
2185 {
2186 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2187 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2188 eRet = OMX_ErrorInvalidState;
2189 }
2190 /* Requesting transition from WaitForResources to Loaded -
2191 is NOT tested by Khronos TS */
2192
2193 }
2194 else
2195 {
2196 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2197 eRet = OMX_ErrorBadParameter;
2198 }
2199 }
2200 /********************************/
2201 /* Current State is Invalid */
2202 /*******************************/
2203 else if(m_state == OMX_StateInvalid)
2204 {
2205 /* State Transition from Inavlid to any state */
2206 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2207 || OMX_StateIdle || OMX_StateExecuting
2208 || OMX_StatePause || OMX_StateInvalid))
2209 {
2210 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2211 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2212 OMX_COMPONENT_GENERATE_EVENT);
2213 eRet = OMX_ErrorInvalidState;
2214 }
2215 }
2216 else if (cmd == OMX_CommandFlush)
2217 {
2218 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002219 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002220 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2221 {
2222 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2223 }
2224 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2225 {
2226 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2227 }
2228 if (!sem_posted){
2229 sem_posted = 1;
2230 DEBUG_PRINT_LOW("\n Set the Semaphore");
2231 sem_post (&m_cmd_lock);
2232 execute_omx_flush(param1);
2233 }
2234 bFlag = 0;
2235 }
2236 else if ( cmd == OMX_CommandPortEnable)
2237 {
2238 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002239 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002240 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2241 {
2242 m_inp_bEnabled = OMX_TRUE;
2243
2244 if( (m_state == OMX_StateLoaded &&
2245 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2246 || allocate_input_done())
2247 {
2248 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2249 OMX_COMPONENT_GENERATE_EVENT);
2250 }
2251 else
2252 {
2253 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2254 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2255 // Skip the event notification
2256 bFlag = 0;
2257 }
2258 }
2259 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2260 {
2261 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2262 m_out_bEnabled = OMX_TRUE;
2263
2264 if( (m_state == OMX_StateLoaded &&
2265 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2266 || (allocate_output_done()))
2267 {
2268 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2269 OMX_COMPONENT_GENERATE_EVENT);
2270
2271 }
2272 else
2273 {
2274 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2275 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2276 // Skip the event notification
2277 bFlag = 0;
2278 }
2279 }
2280 }
2281 else if (cmd == OMX_CommandPortDisable)
2282 {
2283 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002284 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002285 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2286 {
2287 m_inp_bEnabled = OMX_FALSE;
2288 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2289 && release_input_done())
2290 {
2291 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2292 OMX_COMPONENT_GENERATE_EVENT);
2293 }
2294 else
2295 {
2296 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2297 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2298 {
2299 if(!sem_posted)
2300 {
2301 sem_posted = 1;
2302 sem_post (&m_cmd_lock);
2303 }
2304 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2305 }
2306
2307 // Skip the event notification
2308 bFlag = 0;
2309 }
2310 }
2311 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2312 {
2313 m_out_bEnabled = OMX_FALSE;
2314 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2315 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2316 && release_output_done())
2317 {
2318 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2319 OMX_COMPONENT_GENERATE_EVENT);
2320 }
2321 else
2322 {
2323 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2324 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2325 {
2326 if (!sem_posted)
2327 {
2328 sem_posted = 1;
2329 sem_post (&m_cmd_lock);
2330 }
2331 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2332 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2333 }
2334 // Skip the event notification
2335 bFlag = 0;
2336
2337 }
2338 }
2339 }
2340 else
2341 {
2342 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2343 eRet = OMX_ErrorNotImplemented;
2344 }
2345 if(eRet == OMX_ErrorNone && bFlag)
2346 {
2347 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2348 }
2349 if(!sem_posted)
2350 {
2351 sem_post(&m_cmd_lock);
2352 }
2353
2354 return eRet;
2355}
2356
2357/* ======================================================================
2358FUNCTION
2359 omx_vdec::ExecuteOmxFlush
2360
2361DESCRIPTION
2362 Executes the OMX flush.
2363
2364PARAMETERS
2365 flushtype - input flush(1)/output flush(0)/ both.
2366
2367RETURN VALUE
2368 true/false
2369
2370========================================================================== */
2371bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2372{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002373 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002374 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002375 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002376 struct v4l2_decoder_cmd dec;
2377 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002378 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002379 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002380 switch (flushType)
2381 {
2382 case OMX_CORE_INPUT_PORT_INDEX:
2383 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002384 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002385 break;
2386 case OMX_CORE_OUTPUT_PORT_INDEX:
2387 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002388 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002389 break;
2390 default:
2391 input_flush_progress = true;
2392 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002393 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2394 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002395 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002396
2397 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002398 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002399 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400 bRet = false;
2401 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002402
Shalaj Jain273b3e02012-06-22 19:08:03 -07002403 return bRet;
2404}
2405/*=========================================================================
2406FUNCTION : execute_output_flush
2407
2408DESCRIPTION
2409 Executes the OMX flush at OUTPUT PORT.
2410
2411PARAMETERS
2412 None.
2413
2414RETURN VALUE
2415 true/false
2416==========================================================================*/
2417bool omx_vdec::execute_output_flush()
2418{
2419 unsigned p1 = 0; // Parameter - 1
2420 unsigned p2 = 0; // Parameter - 2
2421 unsigned ident = 0;
2422 bool bRet = true;
2423
2424 /*Generate FBD for all Buffers in the FTBq*/
2425 pthread_mutex_lock(&m_lock);
2426 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2427 while (m_ftb_q.m_size)
2428 {
2429 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2430 m_ftb_q.m_size,pending_output_buffers);
2431 m_ftb_q.pop_entry(&p1,&p2,&ident);
2432 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002433 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002434 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002435 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002436 }
2437 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2438 {
2439 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2440 }
2441 }
2442 pthread_mutex_unlock(&m_lock);
2443 output_flush_progress = false;
2444
2445 if (arbitrary_bytes)
2446 {
2447 prev_ts = LLONG_MAX;
2448 rst_prev_ts = true;
2449 }
2450 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2451 return bRet;
2452}
2453/*=========================================================================
2454FUNCTION : execute_input_flush
2455
2456DESCRIPTION
2457 Executes the OMX flush at INPUT PORT.
2458
2459PARAMETERS
2460 None.
2461
2462RETURN VALUE
2463 true/false
2464==========================================================================*/
2465bool omx_vdec::execute_input_flush()
2466{
2467 unsigned i =0;
2468 unsigned p1 = 0; // Parameter - 1
2469 unsigned p2 = 0; // Parameter - 2
2470 unsigned ident = 0;
2471 bool bRet = true;
2472
2473 /*Generate EBD for all Buffers in the ETBq*/
2474 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2475
2476 pthread_mutex_lock(&m_lock);
2477 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2478 while (m_etb_q.m_size)
2479 {
2480 m_etb_q.pop_entry(&p1,&p2,&ident);
2481
2482 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2483 {
2484 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2485 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2486 }
2487 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2488 {
2489 pending_input_buffers++;
2490 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2491 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2492 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2493 }
2494 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2495 {
2496 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2497 (OMX_BUFFERHEADERTYPE *)p1);
2498 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2499 }
2500 }
2501 time_stamp_dts.flush_timestamp();
2502 /*Check if Heap Buffers are to be flushed*/
2503 if (arbitrary_bytes)
2504 {
2505 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2506 h264_scratch.nFilledLen = 0;
2507 nal_count = 0;
2508 look_ahead_nal = false;
2509 frame_count = 0;
2510 h264_last_au_ts = LLONG_MAX;
2511 h264_last_au_flags = 0;
2512 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2513 m_demux_entries = 0;
2514 DEBUG_PRINT_LOW("\n Initialize parser");
2515 if (m_frame_parser.mutils)
2516 {
2517 m_frame_parser.mutils->initialize_frame_checking_environment();
2518 }
2519
2520 while (m_input_pending_q.m_size)
2521 {
2522 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2523 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2524 }
2525
2526 if (psource_frame)
2527 {
2528 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2529 psource_frame = NULL;
2530 }
2531
2532 if (pdest_frame)
2533 {
2534 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002535 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2536 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537 pdest_frame = NULL;
2538 }
2539 m_frame_parser.flush();
2540 }
2541 pthread_mutex_unlock(&m_lock);
2542 input_flush_progress = false;
2543 if (!arbitrary_bytes)
2544 {
2545 prev_ts = LLONG_MAX;
2546 rst_prev_ts = true;
2547 }
2548#ifdef _ANDROID_
2549 if (m_debug_timestamp)
2550 {
2551 m_timestamp_list.reset_ts_list();
2552 }
2553#endif
2554 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2555 return bRet;
2556}
2557
2558
2559/* ======================================================================
2560FUNCTION
2561 omx_vdec::SendCommandEvent
2562
2563DESCRIPTION
2564 Send the event to decoder pipe. This is needed to generate the callbacks
2565 in decoder thread context.
2566
2567PARAMETERS
2568 None.
2569
2570RETURN VALUE
2571 true/false
2572
2573========================================================================== */
2574bool omx_vdec::post_event(unsigned int p1,
2575 unsigned int p2,
2576 unsigned int id)
2577{
2578 bool bRet = false;
2579
2580
2581 pthread_mutex_lock(&m_lock);
2582
Vinay Kaliada4f4422013-01-09 10:45:03 -08002583 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002584 id == OMX_COMPONENT_GENERATE_FBD)
2585 {
2586 m_ftb_q.insert_entry(p1,p2,id);
2587 }
2588 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2589 id == OMX_COMPONENT_GENERATE_EBD ||
2590 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2591 {
2592 m_etb_q.insert_entry(p1,p2,id);
2593 }
2594 else
2595 {
2596 m_cmd_q.insert_entry(p1,p2,id);
2597 }
2598
2599 bRet = true;
2600 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2601 post_message(this, id);
2602
2603 pthread_mutex_unlock(&m_lock);
2604
2605 return bRet;
2606}
2607
2608OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2609{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002610 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002611 if(!profileLevelType)
2612 return OMX_ErrorBadParameter;
2613
2614 if(profileLevelType->nPortIndex == 0) {
2615 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2616 {
2617 if (profileLevelType->nProfileIndex == 0)
2618 {
2619 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2620 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2621
2622 }
2623 else if (profileLevelType->nProfileIndex == 1)
2624 {
2625 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2626 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2627 }
2628 else if(profileLevelType->nProfileIndex == 2)
2629 {
2630 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2631 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2632 }
2633 else
2634 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002635 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002636 profileLevelType->nProfileIndex);
2637 eRet = OMX_ErrorNoMore;
2638 }
2639 }
2640 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2641 {
2642 if (profileLevelType->nProfileIndex == 0)
2643 {
2644 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2645 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2646 }
2647 else
2648 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002649 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002650 eRet = OMX_ErrorNoMore;
2651 }
2652 }
2653 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2654 {
2655 if (profileLevelType->nProfileIndex == 0)
2656 {
2657 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2658 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2659 }
2660 else if(profileLevelType->nProfileIndex == 1)
2661 {
2662 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2663 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2664 }
2665 else
2666 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002667 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002668 eRet = OMX_ErrorNoMore;
2669 }
2670 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002671 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2672 {
2673 eRet = OMX_ErrorNoMore;
2674 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2676 {
2677 if (profileLevelType->nProfileIndex == 0)
2678 {
2679 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2680 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2681 }
2682 else if(profileLevelType->nProfileIndex == 1)
2683 {
2684 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2685 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2686 }
2687 else
2688 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002689 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002690 eRet = OMX_ErrorNoMore;
2691 }
2692 }
2693 }
2694 else
2695 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002696 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002697 eRet = OMX_ErrorBadPortIndex;
2698 }
2699 return eRet;
2700}
2701
2702/* ======================================================================
2703FUNCTION
2704 omx_vdec::GetParameter
2705
2706DESCRIPTION
2707 OMX Get Parameter method implementation
2708
2709PARAMETERS
2710 <TBD>.
2711
2712RETURN VALUE
2713 Error None if successful.
2714
2715========================================================================== */
2716OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2717 OMX_IN OMX_INDEXTYPE paramIndex,
2718 OMX_INOUT OMX_PTR paramData)
2719{
2720 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2721
2722 DEBUG_PRINT_LOW("get_parameter: \n");
2723 if(m_state == OMX_StateInvalid)
2724 {
2725 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2726 return OMX_ErrorInvalidState;
2727 }
2728 if(paramData == NULL)
2729 {
2730 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2731 return OMX_ErrorBadParameter;
2732 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002733 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002734 {
2735 case OMX_IndexParamPortDefinition:
2736 {
2737 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2738 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2739 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2740 eRet = update_portdef(portDefn);
2741 if (eRet == OMX_ErrorNone)
2742 m_port_def = *portDefn;
2743 break;
2744 }
2745 case OMX_IndexParamVideoInit:
2746 {
2747 OMX_PORT_PARAM_TYPE *portParamType =
2748 (OMX_PORT_PARAM_TYPE *) paramData;
2749 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2750
2751 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2752 portParamType->nSize = sizeof(portParamType);
2753 portParamType->nPorts = 2;
2754 portParamType->nStartPortNumber = 0;
2755 break;
2756 }
2757 case OMX_IndexParamVideoPortFormat:
2758 {
2759 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2760 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2761 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2762
2763 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2764 portFmt->nSize = sizeof(portFmt);
2765
2766 if (0 == portFmt->nPortIndex)
2767 {
2768 if (0 == portFmt->nIndex)
2769 {
2770 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2771 portFmt->eCompressionFormat = eCompressionFormat;
2772 }
2773 else
2774 {
2775 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2776 " NoMore compression formats\n");
2777 eRet = OMX_ErrorNoMore;
2778 }
2779 }
2780 else if (1 == portFmt->nPortIndex)
2781 {
2782 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2783
2784 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002785 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2786 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2787 else if (1 == portFmt->nIndex)
2788 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789 else
2790 {
2791 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2792 " NoMore Color formats\n");
2793 eRet = OMX_ErrorNoMore;
2794 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002795 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002796 }
2797 else
2798 {
2799 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2800 (int)portFmt->nPortIndex);
2801 eRet = OMX_ErrorBadPortIndex;
2802 }
2803 break;
2804 }
2805 /*Component should support this port definition*/
2806 case OMX_IndexParamAudioInit:
2807 {
2808 OMX_PORT_PARAM_TYPE *audioPortParamType =
2809 (OMX_PORT_PARAM_TYPE *) paramData;
2810 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2811 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2812 audioPortParamType->nSize = sizeof(audioPortParamType);
2813 audioPortParamType->nPorts = 0;
2814 audioPortParamType->nStartPortNumber = 0;
2815 break;
2816 }
2817 /*Component should support this port definition*/
2818 case OMX_IndexParamImageInit:
2819 {
2820 OMX_PORT_PARAM_TYPE *imagePortParamType =
2821 (OMX_PORT_PARAM_TYPE *) paramData;
2822 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2823 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2824 imagePortParamType->nSize = sizeof(imagePortParamType);
2825 imagePortParamType->nPorts = 0;
2826 imagePortParamType->nStartPortNumber = 0;
2827 break;
2828
2829 }
2830 /*Component should support this port definition*/
2831 case OMX_IndexParamOtherInit:
2832 {
2833 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2834 paramIndex);
2835 eRet =OMX_ErrorUnsupportedIndex;
2836 break;
2837 }
2838 case OMX_IndexParamStandardComponentRole:
2839 {
2840 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2841 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2842 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2843 comp_role->nSize = sizeof(*comp_role);
2844
2845 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2846 paramIndex);
2847 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2848 OMX_MAX_STRINGNAME_SIZE);
2849 break;
2850 }
2851 /* Added for parameter test */
2852 case OMX_IndexParamPriorityMgmt:
2853 {
2854
2855 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2856 (OMX_PRIORITYMGMTTYPE *) paramData;
2857 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2858 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2859 priorityMgmType->nSize = sizeof(priorityMgmType);
2860
2861 break;
2862 }
2863 /* Added for parameter test */
2864 case OMX_IndexParamCompBufferSupplier:
2865 {
2866 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2867 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2868 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2869
2870 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2871 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2872 if(0 == bufferSupplierType->nPortIndex)
2873 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2874 else if (1 == bufferSupplierType->nPortIndex)
2875 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2876 else
2877 eRet = OMX_ErrorBadPortIndex;
2878
2879
2880 break;
2881 }
2882 case OMX_IndexParamVideoAvc:
2883 {
2884 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2885 paramIndex);
2886 break;
2887 }
2888 case OMX_IndexParamVideoH263:
2889 {
2890 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2891 paramIndex);
2892 break;
2893 }
2894 case OMX_IndexParamVideoMpeg4:
2895 {
2896 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2897 paramIndex);
2898 break;
2899 }
2900 case OMX_IndexParamVideoMpeg2:
2901 {
2902 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2903 paramIndex);
2904 break;
2905 }
2906 case OMX_IndexParamVideoProfileLevelQuerySupported:
2907 {
2908 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2909 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2910 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2911 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2912 break;
2913 }
2914#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2915 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2916 {
2917 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2918 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2919 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2920
2921 if(secure_mode) {
2922 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302923 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002924 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08002925 nativeBuffersUsage->nUsage =
2926 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2927 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002928 }
2929 } else {
2930 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2931 eRet = OMX_ErrorBadParameter;
2932 }
2933 }
2934 break;
2935#endif
2936
2937 default:
2938 {
2939 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2940 eRet =OMX_ErrorUnsupportedIndex;
2941 }
2942
2943 }
2944
2945 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2946 drv_ctx.video_resolution.frame_width,
2947 drv_ctx.video_resolution.frame_height,
2948 drv_ctx.video_resolution.stride,
2949 drv_ctx.video_resolution.scan_lines);
2950
2951 return eRet;
2952}
2953
2954#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2955OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2956{
2957 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2958 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2959 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2960
2961 if((params == NULL) ||
2962 (params->nativeBuffer == NULL) ||
2963 (params->nativeBuffer->handle == NULL) ||
2964 !m_enable_android_native_buffers)
2965 return OMX_ErrorBadParameter;
2966 m_use_android_native_buffers = OMX_TRUE;
2967 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2968 private_handle_t *handle = (private_handle_t *)nBuf->handle;
2969 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
2970 OMX_U8 *buffer = NULL;
2971 if(!secure_mode) {
2972 buffer = (OMX_U8*)mmap(0, handle->size,
2973 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
2974 if(buffer == MAP_FAILED) {
2975 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2976 return OMX_ErrorInsufficientResources;
2977 }
2978 }
2979 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2980 } else {
2981 eRet = OMX_ErrorBadParameter;
2982 }
2983 return eRet;
2984}
2985#endif
2986/* ======================================================================
2987FUNCTION
2988 omx_vdec::Setparameter
2989
2990DESCRIPTION
2991 OMX Set Parameter method implementation.
2992
2993PARAMETERS
2994 <TBD>.
2995
2996RETURN VALUE
2997 OMX Error None if successful.
2998
2999========================================================================== */
3000OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3001 OMX_IN OMX_INDEXTYPE paramIndex,
3002 OMX_IN OMX_PTR paramData)
3003{
3004 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003005 int ret=0;
3006 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003007 if(m_state == OMX_StateInvalid)
3008 {
3009 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3010 return OMX_ErrorInvalidState;
3011 }
3012 if(paramData == NULL)
3013 {
3014 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3015 return OMX_ErrorBadParameter;
3016 }
3017 if((m_state != OMX_StateLoaded) &&
3018 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3019 (m_out_bEnabled == OMX_TRUE) &&
3020 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3021 (m_inp_bEnabled == OMX_TRUE)) {
3022 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3023 return OMX_ErrorIncorrectStateOperation;
3024 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003025 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003026 {
3027 case OMX_IndexParamPortDefinition:
3028 {
3029 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3030 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3031 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3032 //been called.
3033 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3034 (int)portDefn->format.video.nFrameHeight,
3035 (int)portDefn->format.video.nFrameWidth);
3036 if(OMX_DirOutput == portDefn->eDir)
3037 {
3038 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3039 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003040 unsigned int buffer_size;
3041 if (!client_buffers.get_buffer_req(buffer_size)) {
3042 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003043 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003044 } else {
3045 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3046 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3047 {
3048 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3049 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3050 eRet = set_buffer_req(&drv_ctx.op_buf);
3051 if (eRet == OMX_ErrorNone)
3052 m_port_def = *portDefn;
3053 }
3054 else
3055 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003056 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003057 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3058 portDefn->nBufferCountActual, portDefn->nBufferSize);
3059 eRet = OMX_ErrorBadParameter;
3060 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003061 }
3062 }
3063 else if(OMX_DirInput == portDefn->eDir)
3064 {
3065 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3066 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3067 {
3068 // Frame rate only should be set if this is a "known value" or to
3069 // activate ts prediction logic (arbitrary mode only) sending input
3070 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003071 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003072 portDefn->format.video.xFramerate >> 16);
3073 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3074 drv_ctx.frame_rate.fps_denominator);
3075 if(!drv_ctx.frame_rate.fps_numerator)
3076 {
3077 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3078 drv_ctx.frame_rate.fps_numerator = 30;
3079 }
3080 if(drv_ctx.frame_rate.fps_denominator)
3081 drv_ctx.frame_rate.fps_numerator = (int)
3082 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3083 drv_ctx.frame_rate.fps_denominator = 1;
3084 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3085 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003086 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087 frm_int, drv_ctx.frame_rate.fps_numerator /
3088 (float)drv_ctx.frame_rate.fps_denominator);
3089 }
3090 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3091 if(drv_ctx.video_resolution.frame_height !=
3092 portDefn->format.video.nFrameHeight ||
3093 drv_ctx.video_resolution.frame_width !=
3094 portDefn->format.video.nFrameWidth)
3095 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003096 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003097 portDefn->format.video.nFrameWidth,
3098 portDefn->format.video.nFrameHeight);
3099 if (portDefn->format.video.nFrameHeight != 0x0 &&
3100 portDefn->format.video.nFrameWidth != 0x0)
3101 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003102 update_resolution(portDefn->format.video.nFrameWidth,
3103 portDefn->format.video.nFrameHeight);
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003104 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3105 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3106 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3107 fmt.fmt.pix_mp.pixelformat = output_capability;
3108 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);
3109 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003110 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003111 {
3112 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3113 eRet = OMX_ErrorUnsupportedSetting;
3114 }
3115 else
3116 eRet = get_buffer_req(&drv_ctx.op_buf);
3117 }
3118 }
3119 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003120 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003121 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003122 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003123 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003124 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3125 (~(buffer_prop->alignment - 1));
3126 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003127 }
3128 else
3129 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003130 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003131 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3132 portDefn->nBufferCountActual, portDefn->nBufferSize);
3133 eRet = OMX_ErrorBadParameter;
3134 }
3135 }
3136 else if (portDefn->eDir == OMX_DirMax)
3137 {
3138 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3139 (int)portDefn->nPortIndex);
3140 eRet = OMX_ErrorBadPortIndex;
3141 }
3142 }
3143 break;
3144 case OMX_IndexParamVideoPortFormat:
3145 {
3146 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3147 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3148 int ret=0;
3149 struct v4l2_format fmt;
3150 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3151 portFmt->eColorFormat);
3152
3153 if(1 == portFmt->nPortIndex)
3154 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003155 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3156 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3157 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3158 fmt.fmt.pix_mp.pixelformat = capture_capability;
3159 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003160 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3161 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003162 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003163 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003164 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003165 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003166 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3167 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3168 else
3169 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003170
Vinay Kaliada4f4422013-01-09 10:45:03 -08003171 if(eRet == OMX_ErrorNone)
3172 {
3173 drv_ctx.output_format = op_format;
3174 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3175 if(ret)
3176 {
3177 DEBUG_PRINT_ERROR("\n Set output format failed");
3178 eRet = OMX_ErrorUnsupportedSetting;
3179 /*TODO: How to handle this case */
3180 }
3181 else
3182 {
3183 eRet = get_buffer_req(&drv_ctx.op_buf);
3184 }
3185 }
3186 if (eRet == OMX_ErrorNone){
3187 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3188 DEBUG_PRINT_ERROR("\n Set color format failed");
3189 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003190 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003191 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003192 }
3193 }
3194 break;
3195
3196 case OMX_QcomIndexPortDefn:
3197 {
3198 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3199 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003200 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003201 portFmt->nFramePackingFormat);
3202
3203 /* Input port */
3204 if (portFmt->nPortIndex == 0)
3205 {
3206 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3207 {
3208 if(secure_mode) {
3209 arbitrary_bytes = false;
3210 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3211 eRet = OMX_ErrorUnsupportedSetting;
3212 } else {
3213 arbitrary_bytes = true;
3214 }
3215 }
3216 else if (portFmt->nFramePackingFormat ==
3217 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3218 {
3219 arbitrary_bytes = false;
3220 }
3221 else
3222 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003223 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003224 portFmt->nFramePackingFormat);
3225 eRet = OMX_ErrorUnsupportedSetting;
3226 }
3227 }
3228 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3229 {
3230 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3231 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3232 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3233 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3234 {
3235 m_out_mem_region_smi = OMX_TRUE;
3236 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3237 {
3238 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3239 m_use_output_pmem = OMX_TRUE;
3240 }
3241 }
3242 }
3243 }
3244 break;
3245
3246 case OMX_IndexParamStandardComponentRole:
3247 {
3248 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3249 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3250 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3251 comp_role->cRole);
3252
3253 if((m_state == OMX_StateLoaded)&&
3254 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3255 {
3256 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3257 }
3258 else
3259 {
3260 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3261 return OMX_ErrorIncorrectStateOperation;
3262 }
3263
3264 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3265 {
3266 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3267 {
3268 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3269 }
3270 else
3271 {
3272 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3273 eRet =OMX_ErrorUnsupportedSetting;
3274 }
3275 }
3276 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3277 {
3278 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3279 {
3280 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3281 }
3282 else
3283 {
3284 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3285 eRet = OMX_ErrorUnsupportedSetting;
3286 }
3287 }
3288 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3289 {
3290 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3291 {
3292 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3293 }
3294 else
3295 {
3296 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3297 eRet =OMX_ErrorUnsupportedSetting;
3298 }
3299 }
3300 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3301 {
3302 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3303 {
3304 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3305 }
3306 else
3307 {
3308 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3309 eRet = OMX_ErrorUnsupportedSetting;
3310 }
3311 }
3312 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3313 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3314 )
3315 {
3316 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3317 {
3318 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3319 }
3320 else
3321 {
3322 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3323 eRet =OMX_ErrorUnsupportedSetting;
3324 }
3325 }
3326 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3327 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3328 )
3329 {
3330 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3331 {
3332 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3333 }
3334 else
3335 {
3336 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3337 eRet =OMX_ErrorUnsupportedSetting;
3338 }
3339 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003340 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3341 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003342 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3343 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003344 {
3345 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3346 }
3347 else
3348 {
3349 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3350 eRet = OMX_ErrorUnsupportedSetting;
3351 }
3352 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003353 else
3354 {
3355 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3356 eRet = OMX_ErrorInvalidComponentName;
3357 }
3358 break;
3359 }
3360
3361 case OMX_IndexParamPriorityMgmt:
3362 {
3363 if(m_state != OMX_StateLoaded)
3364 {
3365 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3366 return OMX_ErrorIncorrectStateOperation;
3367 }
3368 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003369 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003370 priorityMgmtype->nGroupID);
3371
Shalaj Jainaf08f302013-03-18 13:15:35 -07003372 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003373 priorityMgmtype->nGroupPriority);
3374
3375 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3376 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3377
3378 break;
3379 }
3380
3381 case OMX_IndexParamCompBufferSupplier:
3382 {
3383 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3384 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3385 bufferSupplierType->eBufferSupplier);
3386 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3387 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3388
3389 else
3390
3391 eRet = OMX_ErrorBadPortIndex;
3392
3393 break;
3394
3395 }
3396 case OMX_IndexParamVideoAvc:
3397 {
3398 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3399 paramIndex);
3400 break;
3401 }
3402 case OMX_IndexParamVideoH263:
3403 {
3404 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3405 paramIndex);
3406 break;
3407 }
3408 case OMX_IndexParamVideoMpeg4:
3409 {
3410 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3411 paramIndex);
3412 break;
3413 }
3414 case OMX_IndexParamVideoMpeg2:
3415 {
3416 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3417 paramIndex);
3418 break;
3419 }
3420 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3421 {
3422 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3423 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003424 struct v4l2_control control;
3425 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003426 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3427 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003428 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3429 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3430 }
3431 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3432 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003433 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003434 }
3435 else
3436 eRet = OMX_ErrorBadParameter;
3437 if (eRet == OMX_ErrorNone)
3438 {
3439 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3440 control.value = pic_order;
3441 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3442 if(rc)
3443 {
3444 DEBUG_PRINT_ERROR("\n Set picture order failed");
3445 eRet = OMX_ErrorUnsupportedSetting;
3446 }
3447 }
3448 break;
3449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003450 case OMX_QcomIndexParamConcealMBMapExtraData:
3451 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003452 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003453 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3454 else {
3455 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3456 eRet = OMX_ErrorUnsupportedSetting;
3457 }
3458 break;
3459 case OMX_QcomIndexParamFrameInfoExtraData:
3460 {
3461 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003462 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003463 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3464 else {
3465 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3466 eRet = OMX_ErrorUnsupportedSetting;
3467 }
3468 break;
3469 }
3470 case OMX_QcomIndexParamInterlaceExtraData:
3471 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003472 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003473 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3474 else {
3475 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3476 eRet = OMX_ErrorUnsupportedSetting;
3477 }
3478 break;
3479 case OMX_QcomIndexParamH264TimeInfo:
3480 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003481 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003482 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3483 else {
3484 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3485 eRet = OMX_ErrorUnsupportedSetting;
3486 }
3487 break;
3488 case OMX_QcomIndexParamVideoDivx:
3489 {
3490 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003491 }
3492 break;
3493 case OMX_QcomIndexPlatformPvt:
3494 {
3495 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3496 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3497 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3498 {
3499 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3500 eRet = OMX_ErrorUnsupportedSetting;
3501 }
3502 else
3503 {
3504 m_out_pvt_entry_pmem = OMX_TRUE;
3505 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3506 {
3507 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3508 m_use_output_pmem = OMX_TRUE;
3509 }
3510 }
3511
3512 }
3513 break;
3514 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3515 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003516 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3517 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3518 struct v4l2_control control;
3519 int rc;
3520 drv_ctx.idr_only_decoding = 1;
3521 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3522 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3523 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3524 if(rc)
3525 {
3526 DEBUG_PRINT_ERROR("\n Set picture order failed");
3527 eRet = OMX_ErrorUnsupportedSetting;
3528 } else {
3529 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3530 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3531 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3532 if(rc)
3533 {
3534 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3535 eRet = OMX_ErrorUnsupportedSetting;
3536 }
3537 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003538 }
3539 break;
3540
3541 case OMX_QcomIndexParamIndexExtraDataType:
3542 {
3543 if(!secure_mode) {
3544 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3545 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3546 (extradataIndexType->bEnabled == OMX_TRUE) &&
3547 (extradataIndexType->nPortIndex == 1))
3548 {
3549 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003550 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003551
Shalaj Jain273b3e02012-06-22 19:08:03 -07003552 }
3553 }
3554 }
3555 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003556 case OMX_QcomIndexParamEnableSmoothStreaming:
3557 {
3558 struct v4l2_control control;
3559 struct v4l2_format fmt;
3560 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3561 control.value = 1;
3562 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3563 if(rc < 0) {
3564 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3565 eRet = OMX_ErrorHardware;
3566 }
3567 }
3568 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003569#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3570 /* Need to allow following two set_parameters even in Idle
3571 * state. This is ANDROID architecture which is not in sync
3572 * with openmax standard. */
3573 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3574 {
3575 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3576 if(enableNativeBuffers) {
3577 m_enable_android_native_buffers = enableNativeBuffers->enable;
3578 }
3579 }
3580 break;
3581 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3582 {
3583 eRet = use_android_native_buffer(hComp, paramData);
3584 }
3585 break;
3586#endif
3587 case OMX_QcomIndexParamEnableTimeStampReorder:
3588 {
3589 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003590 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003591 if (reorder->bEnable == OMX_TRUE) {
3592 frm_int =0;
3593 time_stamp_dts.set_timestamp_reorder_mode(true);
3594 }
3595 else
3596 time_stamp_dts.set_timestamp_reorder_mode(false);
3597 } else {
3598 time_stamp_dts.set_timestamp_reorder_mode(false);
3599 if (reorder->bEnable == OMX_TRUE)
3600 {
3601 eRet = OMX_ErrorUnsupportedSetting;
3602 }
3603 }
3604 }
3605 break;
3606 default:
3607 {
3608 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3609 eRet = OMX_ErrorUnsupportedIndex;
3610 }
3611 }
3612 return eRet;
3613}
3614
3615/* ======================================================================
3616FUNCTION
3617 omx_vdec::GetConfig
3618
3619DESCRIPTION
3620 OMX Get Config Method implementation.
3621
3622PARAMETERS
3623 <TBD>.
3624
3625RETURN VALUE
3626 OMX Error None if successful.
3627
3628========================================================================== */
3629OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3630 OMX_IN OMX_INDEXTYPE configIndex,
3631 OMX_INOUT OMX_PTR configData)
3632{
3633 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3634
3635 if (m_state == OMX_StateInvalid)
3636 {
3637 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3638 return OMX_ErrorInvalidState;
3639 }
3640
Shalaj Jain286b0062013-02-21 20:35:48 -08003641 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003642 {
3643 case OMX_QcomIndexConfigInterlaced:
3644 {
3645 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3646 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3647 if (configFmt->nPortIndex == 1)
3648 {
3649 if (configFmt->nIndex == 0)
3650 {
3651 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3652 }
3653 else if (configFmt->nIndex == 1)
3654 {
3655 configFmt->eInterlaceType =
3656 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3657 }
3658 else if (configFmt->nIndex == 2)
3659 {
3660 configFmt->eInterlaceType =
3661 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3662 }
3663 else
3664 {
3665 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3666 " NoMore Interlaced formats\n");
3667 eRet = OMX_ErrorNoMore;
3668 }
3669
3670 }
3671 else
3672 {
3673 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3674 (int)configFmt->nPortIndex);
3675 eRet = OMX_ErrorBadPortIndex;
3676 }
3677 break;
3678 }
3679 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3680 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003681 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3682 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003683 decoderinstances->nNumOfInstances = 16;
3684 /*TODO: How to handle this case */
3685 break;
3686 }
3687 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3688 {
3689 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3690 {
3691 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3692 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3693 h264_parser->get_frame_pack_data(configFmt);
3694 }
3695 else
3696 {
3697 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3698 }
3699 break;
3700 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003701 case OMX_IndexConfigCommonOutputCrop:
3702 {
3703 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3704 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3705 break;
3706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003707 default:
3708 {
3709 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3710 eRet = OMX_ErrorBadParameter;
3711 }
3712
3713 }
3714
3715 return eRet;
3716}
3717
3718/* ======================================================================
3719FUNCTION
3720 omx_vdec::SetConfig
3721
3722DESCRIPTION
3723 OMX Set Config method implementation
3724
3725PARAMETERS
3726 <TBD>.
3727
3728RETURN VALUE
3729 OMX Error None if successful.
3730========================================================================== */
3731OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3732 OMX_IN OMX_INDEXTYPE configIndex,
3733 OMX_IN OMX_PTR configData)
3734{
3735 if(m_state == OMX_StateInvalid)
3736 {
3737 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3738 return OMX_ErrorInvalidState;
3739 }
3740
3741 OMX_ERRORTYPE ret = OMX_ErrorNone;
3742 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3743
3744 DEBUG_PRINT_LOW("\n Set Config Called");
3745
3746 if (m_state == OMX_StateExecuting)
3747 {
3748 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3749 return ret;
3750 }
3751
Shalaj Jain286b0062013-02-21 20:35:48 -08003752 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003753 {
3754 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3755 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3756 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3757 {
3758 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3759 OMX_U32 extra_size;
3760 // Parsing done here for the AVC atom is definitely not generic
3761 // Currently this piece of code is working, but certainly
3762 // not tested with all .mp4 files.
3763 // Incase of failure, we might need to revisit this
3764 // for a generic piece of code.
3765
3766 // Retrieve size of NAL length field
3767 // byte #4 contains the size of NAL lenght field
3768 nal_length = (config->pData[4] & 0x03) + 1;
3769
3770 extra_size = 0;
3771 if (nal_length > 2)
3772 {
3773 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3774 extra_size = (nal_length - 2) * 2;
3775 }
3776
3777 // SPS starts from byte #6
3778 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3779 OMX_U8 *pDestBuf;
3780 m_vendor_config.nPortIndex = config->nPortIndex;
3781
3782 // minus 6 --> SPS starts from byte #6
3783 // minus 1 --> picture param set byte to be ignored from avcatom
3784 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3785 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3786 OMX_U32 len;
3787 OMX_U8 index = 0;
3788 // case where SPS+PPS is sent as part of set_config
3789 pDestBuf = m_vendor_config.pData;
3790
Shalaj Jainaf08f302013-03-18 13:15:35 -07003791 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003792 m_vendor_config.nPortIndex,
3793 m_vendor_config.nDataSize,
3794 m_vendor_config.pData);
3795 while (index < 2)
3796 {
3797 uint8 *psize;
3798 len = *pSrcBuf;
3799 len = len << 8;
3800 len |= *(pSrcBuf + 1);
3801 psize = (uint8 *) & len;
3802 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003803 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003804 {
3805 pDestBuf[i] = psize[nal_length - 1 - i];
3806 }
3807 //memcpy(pDestBuf,pSrcBuf,(len+2));
3808 pDestBuf += len + nal_length;
3809 pSrcBuf += len + 2;
3810 index++;
3811 pSrcBuf++; // skip picture param set
3812 len = 0;
3813 }
3814 }
3815 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3816 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3817 {
3818 m_vendor_config.nPortIndex = config->nPortIndex;
3819 m_vendor_config.nDataSize = config->nDataSize;
3820 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3821 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3822 }
3823 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3824 {
3825 if(m_vendor_config.pData)
3826 {
3827 free(m_vendor_config.pData);
3828 m_vendor_config.pData = NULL;
3829 m_vendor_config.nDataSize = 0;
3830 }
3831
3832 if (((*((OMX_U32 *) config->pData)) &
3833 VC1_SP_MP_START_CODE_MASK) ==
3834 VC1_SP_MP_START_CODE)
3835 {
3836 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3837 m_vendor_config.nPortIndex = config->nPortIndex;
3838 m_vendor_config.nDataSize = config->nDataSize;
3839 m_vendor_config.pData =
3840 (OMX_U8 *) malloc(config->nDataSize);
3841 memcpy(m_vendor_config.pData, config->pData,
3842 config->nDataSize);
3843 m_vc1_profile = VC1_SP_MP_RCV;
3844 }
3845 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3846 {
3847 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3848 m_vendor_config.nPortIndex = config->nPortIndex;
3849 m_vendor_config.nDataSize = config->nDataSize;
3850 m_vendor_config.pData =
3851 (OMX_U8 *) malloc((config->nDataSize));
3852 memcpy(m_vendor_config.pData, config->pData,
3853 config->nDataSize);
3854 m_vc1_profile = VC1_AP;
3855 }
3856 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3857 {
3858 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3859 m_vendor_config.nPortIndex = config->nPortIndex;
3860 m_vendor_config.nDataSize = config->nDataSize;
3861 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3862 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3863 m_vc1_profile = VC1_SP_MP_RCV;
3864 }
3865 else
3866 {
3867 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3868 }
3869 }
3870 return ret;
3871 }
3872 else if (configIndex == OMX_IndexConfigVideoNalSize)
3873 {
3874
3875 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3876 nal_length = pNal->nNaluBytes;
3877 m_frame_parser.init_nal_length(nal_length);
3878 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3879 return ret;
3880 }
3881
3882 return OMX_ErrorNotImplemented;
3883}
3884
3885/* ======================================================================
3886FUNCTION
3887 omx_vdec::GetExtensionIndex
3888
3889DESCRIPTION
3890 OMX GetExtensionIndex method implementaion. <TBD>
3891
3892PARAMETERS
3893 <TBD>.
3894
3895RETURN VALUE
3896 OMX Error None if everything successful.
3897
3898========================================================================== */
3899OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3900 OMX_IN OMX_STRING paramName,
3901 OMX_OUT OMX_INDEXTYPE* indexType)
3902{
3903 if(m_state == OMX_StateInvalid)
3904 {
3905 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3906 return OMX_ErrorInvalidState;
3907 }
3908 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3909 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3910 }
3911 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3912 {
3913 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3914 }
3915#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3916 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3917 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3918 }
3919 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3920 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3921 }
3922 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3923 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3924 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3925 }
3926 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3927 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3928 }
3929#endif
3930 else {
3931 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3932 return OMX_ErrorNotImplemented;
3933 }
3934 return OMX_ErrorNone;
3935}
3936
3937/* ======================================================================
3938FUNCTION
3939 omx_vdec::GetState
3940
3941DESCRIPTION
3942 Returns the state information back to the caller.<TBD>
3943
3944PARAMETERS
3945 <TBD>.
3946
3947RETURN VALUE
3948 Error None if everything is successful.
3949========================================================================== */
3950OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
3951 OMX_OUT OMX_STATETYPE* state)
3952{
3953 *state = m_state;
3954 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3955 return OMX_ErrorNone;
3956}
3957
3958/* ======================================================================
3959FUNCTION
3960 omx_vdec::ComponentTunnelRequest
3961
3962DESCRIPTION
3963 OMX Component Tunnel Request method implementation. <TBD>
3964
3965PARAMETERS
3966 None.
3967
3968RETURN VALUE
3969 OMX Error None if everything successful.
3970
3971========================================================================== */
3972OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
3973 OMX_IN OMX_U32 port,
3974 OMX_IN OMX_HANDLETYPE peerComponent,
3975 OMX_IN OMX_U32 peerPort,
3976 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
3977{
3978 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3979 return OMX_ErrorNotImplemented;
3980}
3981
3982/* ======================================================================
3983FUNCTION
3984 omx_vdec::UseOutputBuffer
3985
3986DESCRIPTION
3987 Helper function for Use buffer in the input pin
3988
3989PARAMETERS
3990 None.
3991
3992RETURN VALUE
3993 true/false
3994
3995========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003996OMX_ERRORTYPE omx_vdec::allocate_extradata()
3997{
3998#ifdef USE_ION
3999 if (drv_ctx.extradata_info.buffer_size) {
4000 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4001 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4002 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4003 free_ion_memory(&drv_ctx.extradata_info.ion);
4004 }
4005 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4006 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4007 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4008 &drv_ctx.extradata_info.ion.ion_alloc_data,
4009 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4010 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4011 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4012 return OMX_ErrorInsufficientResources;
4013 }
4014 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4015 drv_ctx.extradata_info.size,
4016 PROT_READ|PROT_WRITE, MAP_SHARED,
4017 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4018 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4019 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4020 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4021 free_ion_memory(&drv_ctx.extradata_info.ion);
4022 return OMX_ErrorInsufficientResources;
4023 }
4024 }
4025#endif
4026 return OMX_ErrorNone;
4027}
4028
4029void omx_vdec::free_extradata() {
4030#ifdef USE_ION
4031 if (drv_ctx.extradata_info.uaddr) {
4032 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4033 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4034 free_ion_memory(&drv_ctx.extradata_info.ion);
4035 }
4036 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4037#endif
4038}
4039
Shalaj Jain273b3e02012-06-22 19:08:03 -07004040OMX_ERRORTYPE omx_vdec::use_output_buffer(
4041 OMX_IN OMX_HANDLETYPE hComp,
4042 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4043 OMX_IN OMX_U32 port,
4044 OMX_IN OMX_PTR appData,
4045 OMX_IN OMX_U32 bytes,
4046 OMX_IN OMX_U8* buffer)
4047{
4048 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4049 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4050 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004051 struct vdec_setbuffer_cmd setbuffers;
4052 OMX_PTR privateAppData = NULL;
4053 private_handle_t *handle = NULL;
4054 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004055 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004056 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4057 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004058
Shalaj Jain273b3e02012-06-22 19:08:03 -07004059 if (!m_out_mem_ptr) {
4060 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4061 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004062 if (eRet == OMX_ErrorNone)
4063 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004064 }
4065
4066 if (eRet == OMX_ErrorNone) {
4067 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4068 if(BITMASK_ABSENT(&m_out_bm_count,i))
4069 {
4070 break;
4071 }
4072 }
4073 }
4074
4075 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004076 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004077 eRet = OMX_ErrorInsufficientResources;
4078 }
4079
4080 if (eRet == OMX_ErrorNone) {
4081#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4082 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004083 if (m_use_android_native_buffers) {
4084 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4085 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4086 handle = (private_handle_t *)nBuf->handle;
4087 privateAppData = params->pAppPrivate;
4088 } else {
4089 handle = (private_handle_t *)buff;
4090 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004091 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004092
4093 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4094 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4095 " expected %u, got %lu",
4096 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4097 return OMX_ErrorBadParameter;
4098 }
4099
4100 if (!m_use_android_native_buffers) {
4101 if (!secure_mode) {
4102 buff = (OMX_U8*)mmap(0, handle->size,
4103 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4104 if (buff == MAP_FAILED) {
4105 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4106 return OMX_ErrorInsufficientResources;
4107 }
4108 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004109 }
4110#if defined(_ANDROID_ICS_)
4111 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004112 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004113#endif
4114 if(!handle) {
4115 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4116 return OMX_ErrorBadParameter;
4117 }
4118 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4119 drv_ctx.ptr_outputbuffer[i].offset = 0;
4120 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4121 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4122 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4123 } else
4124#endif
4125
4126 if (!ouput_egl_buffers && !m_use_output_pmem) {
4127#ifdef USE_ION
4128 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4129 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4130 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004131 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004132 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004133 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 -07004134 return OMX_ErrorInsufficientResources;
4135 }
4136 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4137 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4138#else
4139 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4140 open (MEM_DEVICE,O_RDWR);
4141
4142 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004143 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 -07004144 return OMX_ErrorInsufficientResources;
4145 }
4146
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004147 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004148 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4149 {
4150 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4151 open (MEM_DEVICE,O_RDWR);
4152 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004153 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 -07004154 return OMX_ErrorInsufficientResources;
4155 }
4156 }
4157
4158 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4159 drv_ctx.op_buf.buffer_size,
4160 drv_ctx.op_buf.alignment))
4161 {
4162 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4163 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4164 return OMX_ErrorInsufficientResources;
4165 }
4166#endif
4167 if(!secure_mode) {
4168 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4169 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4170 PROT_READ|PROT_WRITE, MAP_SHARED,
4171 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4172 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4173 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4174#ifdef USE_ION
4175 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4176#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004177 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004178 return OMX_ErrorInsufficientResources;
4179 }
4180 }
4181 drv_ctx.ptr_outputbuffer[i].offset = 0;
4182 privateAppData = appData;
4183 }
4184 else {
4185
4186 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4187 if (!appData || !bytes ) {
4188 if(!secure_mode && !buffer) {
4189 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4190 return OMX_ErrorBadParameter;
4191 }
4192 }
4193
4194 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4195 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4196 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4197 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4198 !pmem_list->nEntries ||
4199 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4200 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4201 return OMX_ErrorBadParameter;
4202 }
4203 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4204 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004205 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004206 pmem_info->pmem_fd);
4207 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4208 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4209 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4210 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4211 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4212 privateAppData = appData;
4213 }
4214 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4215 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4216
4217 *bufferHdr = (m_out_mem_ptr + i );
4218 if(secure_mode)
4219 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4220 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4221 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4222 sizeof (vdec_bufferpayload));
4223
Shalaj Jain286b0062013-02-21 20:35:48 -08004224 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4225 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4226 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004227
4228 buf.index = i;
4229 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4230 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004231 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004232 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4233 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004234 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4235 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4236 plane[0].data_offset = 0;
4237 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4238 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4239 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4240 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4241#ifdef USE_ION
4242 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4243#endif
4244 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4245 plane[extra_idx].data_offset = 0;
4246 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4247 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4248 return OMX_ErrorBadParameter;
4249 }
4250 buf.m.planes = plane;
4251 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004252
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004253 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4254 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4255 /*TODO: How to handle this case */
4256 return OMX_ErrorInsufficientResources;
4257 }
4258
4259 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4260 enum v4l2_buf_type buf_type;
4261 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4262 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4263 return OMX_ErrorInsufficientResources;
4264 } else {
4265 streaming[CAPTURE_PORT] = true;
4266 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4267 }
4268 }
4269
Shalaj Jain273b3e02012-06-22 19:08:03 -07004270 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004271 if (m_enable_android_native_buffers) {
4272 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4273 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4274 } else {
4275 (*bufferHdr)->pBuffer = buff;
4276 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004277 (*bufferHdr)->pAppPrivate = privateAppData;
4278 BITMASK_SET(&m_out_bm_count,i);
4279 }
4280 return eRet;
4281}
4282
4283/* ======================================================================
4284FUNCTION
4285 omx_vdec::use_input_heap_buffers
4286
4287DESCRIPTION
4288 OMX Use Buffer Heap allocation method implementation.
4289
4290PARAMETERS
4291 <TBD>.
4292
4293RETURN VALUE
4294 OMX Error None , if everything successful.
4295
4296========================================================================== */
4297OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4298 OMX_IN OMX_HANDLETYPE hComp,
4299 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4300 OMX_IN OMX_U32 port,
4301 OMX_IN OMX_PTR appData,
4302 OMX_IN OMX_U32 bytes,
4303 OMX_IN OMX_U8* buffer)
4304{
4305 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4306 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4307 if(!m_inp_heap_ptr)
4308 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4309 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4310 drv_ctx.ip_buf.actualcount);
4311 if(!m_phdr_pmem_ptr)
4312 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4313 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4314 drv_ctx.ip_buf.actualcount);
4315 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4316 {
4317 DEBUG_PRINT_ERROR("Insufficent memory");
4318 eRet = OMX_ErrorInsufficientResources;
4319 }
4320 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4321 {
4322 input_use_buffer = true;
4323 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4324 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4325 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4326 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4327 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4328 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4329 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4330 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4331 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
Shalaj Jain286b0062013-02-21 20:35:48 -08004332 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4333 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004334 {
4335 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4336 return OMX_ErrorInsufficientResources;
4337 }
4338 m_in_alloc_cnt++;
4339 }
4340 else
4341 {
4342 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4343 eRet = OMX_ErrorInsufficientResources;
4344 }
4345 return eRet;
4346}
4347
4348/* ======================================================================
4349FUNCTION
4350 omx_vdec::UseBuffer
4351
4352DESCRIPTION
4353 OMX Use Buffer method implementation.
4354
4355PARAMETERS
4356 <TBD>.
4357
4358RETURN VALUE
4359 OMX Error None , if everything successful.
4360
4361========================================================================== */
4362OMX_ERRORTYPE omx_vdec::use_buffer(
4363 OMX_IN OMX_HANDLETYPE hComp,
4364 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4365 OMX_IN OMX_U32 port,
4366 OMX_IN OMX_PTR appData,
4367 OMX_IN OMX_U32 bytes,
4368 OMX_IN OMX_U8* buffer)
4369{
4370 OMX_ERRORTYPE error = OMX_ErrorNone;
4371 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004372
4373 if (bufferHdr == NULL || bytes == 0)
4374 {
4375 if(!secure_mode && buffer == NULL) {
4376 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4377 return OMX_ErrorBadParameter;
4378 }
4379 }
4380 if(m_state == OMX_StateInvalid)
4381 {
4382 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4383 return OMX_ErrorInvalidState;
4384 }
4385 if(port == OMX_CORE_INPUT_PORT_INDEX)
4386 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4387 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4388 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4389 else
4390 {
4391 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4392 error = OMX_ErrorBadPortIndex;
4393 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004394 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004395 if(error == OMX_ErrorNone)
4396 {
4397 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4398 {
4399 // Send the callback now
4400 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4401 post_event(OMX_CommandStateSet,OMX_StateIdle,
4402 OMX_COMPONENT_GENERATE_EVENT);
4403 }
4404 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4405 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4406 {
4407 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4408 post_event(OMX_CommandPortEnable,
4409 OMX_CORE_INPUT_PORT_INDEX,
4410 OMX_COMPONENT_GENERATE_EVENT);
4411 }
4412 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4413 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4414 {
4415 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4416 post_event(OMX_CommandPortEnable,
4417 OMX_CORE_OUTPUT_PORT_INDEX,
4418 OMX_COMPONENT_GENERATE_EVENT);
4419 }
4420 }
4421 return error;
4422}
4423
4424OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4425 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4426{
4427 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4428 {
4429 if(m_inp_heap_ptr[bufferindex].pBuffer)
4430 free(m_inp_heap_ptr[bufferindex].pBuffer);
4431 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4432 }
4433 if (pmem_bufferHdr)
4434 free_input_buffer(pmem_bufferHdr);
4435 return OMX_ErrorNone;
4436}
4437
4438OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4439{
4440 unsigned int index = 0;
4441 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4442 {
4443 return OMX_ErrorBadParameter;
4444 }
4445
4446 index = bufferHdr - m_inp_mem_ptr;
4447 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4448
4449 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4450 {
4451 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4452 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4453 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004454 struct vdec_setbuffer_cmd setbuffers;
4455 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4456 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4457 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004458 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4459 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Shalaj Jainaf08f302013-03-18 13:15:35 -07004460 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004461 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4462 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4463 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4464 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4465 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4466 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4467 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4468 {
4469 free(m_desc_buffer_ptr[index].buf_addr);
4470 m_desc_buffer_ptr[index].buf_addr = NULL;
4471 m_desc_buffer_ptr[index].desc_data_size = 0;
4472 }
4473#ifdef USE_ION
4474 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4475#endif
4476 }
4477 }
4478
4479 return OMX_ErrorNone;
4480}
4481
4482OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4483{
4484 unsigned int index = 0;
4485
4486 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4487 {
4488 return OMX_ErrorBadParameter;
4489 }
4490
4491 index = bufferHdr - m_out_mem_ptr;
4492 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4493
4494 if (index < drv_ctx.op_buf.actualcount
4495 && drv_ctx.ptr_outputbuffer)
4496 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004497 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004498 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4499
Shalaj Jain273b3e02012-06-22 19:08:03 -07004500 struct vdec_setbuffer_cmd setbuffers;
4501 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4502 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4503 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004504#ifdef _ANDROID_
4505 if(m_enable_android_native_buffers) {
4506 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4507 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4508 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4509 }
4510 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4511 } else {
4512#endif
4513 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4514 {
4515 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4516 drv_ctx.ptr_outputbuffer[0].pmem_fd);
Shalaj Jainaf08f302013-03-18 13:15:35 -07004517 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004518 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004519 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4520 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004521 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004522 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4523 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4524#ifdef USE_ION
4525 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4526#endif
4527 }
4528#ifdef _ANDROID_
4529 }
4530#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004531 if (release_output_done()) {
4532 free_extradata();
4533 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004534 }
4535
4536 return OMX_ErrorNone;
4537
4538}
4539
4540OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4541 OMX_BUFFERHEADERTYPE **bufferHdr,
4542 OMX_U32 port,
4543 OMX_PTR appData,
4544 OMX_U32 bytes)
4545{
4546 OMX_BUFFERHEADERTYPE *input = NULL;
4547 unsigned char *buf_addr = NULL;
4548 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4549 unsigned i = 0;
4550
4551 /* Sanity Check*/
4552 if (bufferHdr == NULL)
4553 {
4554 return OMX_ErrorBadParameter;
4555 }
4556
4557 if (m_inp_heap_ptr == NULL)
4558 {
4559 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4560 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4561 drv_ctx.ip_buf.actualcount);
4562 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4563 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4564 drv_ctx.ip_buf.actualcount);
4565
4566 if (m_inp_heap_ptr == NULL)
4567 {
4568 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4569 return OMX_ErrorInsufficientResources;
4570 }
4571 }
4572
4573 /*Find a Free index*/
4574 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4575 {
4576 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4577 {
4578 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4579 break;
4580 }
4581 }
4582
4583 if (i < drv_ctx.ip_buf.actualcount)
4584 {
4585 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4586
4587 if (buf_addr == NULL)
4588 {
4589 return OMX_ErrorInsufficientResources;
4590 }
4591
4592 *bufferHdr = (m_inp_heap_ptr + i);
4593 input = *bufferHdr;
4594 BITMASK_SET(&m_heap_inp_bm_count,i);
4595
4596 input->pBuffer = (OMX_U8 *)buf_addr;
4597 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4598 input->nVersion.nVersion = OMX_SPEC_VERSION;
4599 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4600 input->pAppPrivate = appData;
4601 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4602 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4603 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004604 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004605 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004606 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4607 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004608 {
4609 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4610 return OMX_ErrorInsufficientResources;
4611 }
4612 }
4613 else
4614 {
4615 return OMX_ErrorBadParameter;
4616 }
4617
4618 return eRet;
4619
4620}
4621
4622
4623/* ======================================================================
4624FUNCTION
4625 omx_vdec::AllocateInputBuffer
4626
4627DESCRIPTION
4628 Helper function for allocate buffer in the input pin
4629
4630PARAMETERS
4631 None.
4632
4633RETURN VALUE
4634 true/false
4635
4636========================================================================== */
4637OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4638 OMX_IN OMX_HANDLETYPE hComp,
4639 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4640 OMX_IN OMX_U32 port,
4641 OMX_IN OMX_PTR appData,
4642 OMX_IN OMX_U32 bytes)
4643{
4644
4645 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4646 struct vdec_setbuffer_cmd setbuffers;
4647 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648 unsigned i = 0;
4649 unsigned char *buf_addr = NULL;
4650 int pmem_fd = -1;
4651
4652 if(bytes != drv_ctx.ip_buf.buffer_size)
4653 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004654 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655 bytes, drv_ctx.ip_buf.buffer_size);
4656 return OMX_ErrorBadParameter;
4657 }
4658
4659 if(!m_inp_mem_ptr)
4660 {
4661 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4662 drv_ctx.ip_buf.actualcount,
4663 drv_ctx.ip_buf.buffer_size);
4664
4665 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4666 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4667
4668 if (m_inp_mem_ptr == NULL)
4669 {
4670 return OMX_ErrorInsufficientResources;
4671 }
4672
4673 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4674 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4675
4676 if (drv_ctx.ptr_inputbuffer == NULL)
4677 {
4678 return OMX_ErrorInsufficientResources;
4679 }
4680#ifdef USE_ION
4681 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4682 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4683
4684 if (drv_ctx.ip_buf_ion_info == NULL)
4685 {
4686 return OMX_ErrorInsufficientResources;
4687 }
4688#endif
4689
4690 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4691 {
4692 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4693#ifdef USE_ION
4694 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4695#endif
4696 }
4697 }
4698
4699 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4700 {
4701 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4702 {
4703 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4704 break;
4705 }
4706 }
4707
4708 if(i < drv_ctx.ip_buf.actualcount)
4709 {
4710 struct v4l2_buffer buf;
4711 struct v4l2_plane plane;
4712 int rc;
4713 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4714#ifdef USE_ION
4715 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4716 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4717 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004718 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004719 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4720 return OMX_ErrorInsufficientResources;
4721 }
4722 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4723#else
4724 pmem_fd = open (MEM_DEVICE,O_RDWR);
4725
4726 if (pmem_fd < 0)
4727 {
4728 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4729 return OMX_ErrorInsufficientResources;
4730 }
4731
4732 if (pmem_fd == 0)
4733 {
4734 pmem_fd = open (MEM_DEVICE,O_RDWR);
4735
4736 if (pmem_fd < 0)
4737 {
4738 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4739 return OMX_ErrorInsufficientResources;
4740 }
4741 }
4742
4743 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4744 drv_ctx.ip_buf.alignment))
4745 {
4746 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4747 close(pmem_fd);
4748 return OMX_ErrorInsufficientResources;
4749 }
4750#endif
4751 if (!secure_mode) {
4752 buf_addr = (unsigned char *)mmap(NULL,
4753 drv_ctx.ip_buf.buffer_size,
4754 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4755
4756 if (buf_addr == MAP_FAILED)
4757 {
4758 close(pmem_fd);
4759#ifdef USE_ION
4760 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4761#endif
4762 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4763 return OMX_ErrorInsufficientResources;
4764 }
4765 }
4766 *bufferHdr = (m_inp_mem_ptr + i);
4767 if (secure_mode)
4768 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4769 else
4770 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4771 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4772 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4773 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4774 drv_ctx.ptr_inputbuffer [i].offset = 0;
4775
4776
4777 buf.index = i;
4778 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4779 buf.memory = V4L2_MEMORY_USERPTR;
4780 plane.bytesused = 0;
4781 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4782 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4783 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4784 plane.reserved[1] = 0;
4785 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4786 buf.m.planes = &plane;
4787 buf.length = 1;
4788
Shalaj Jainaf08f302013-03-18 13:15:35 -07004789 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4790 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004791
4792 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4793
4794 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004795 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004796 /*TODO: How to handle this case */
4797 return OMX_ErrorInsufficientResources;
4798 }
4799
4800 input = *bufferHdr;
4801 BITMASK_SET(&m_inp_bm_count,i);
4802 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4803 if (secure_mode)
4804 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4805 else
4806 input->pBuffer = (OMX_U8 *)buf_addr;
4807 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4808 input->nVersion.nVersion = OMX_SPEC_VERSION;
4809 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4810 input->pAppPrivate = appData;
4811 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4812 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4813
4814 if (drv_ctx.disable_dmx)
4815 {
4816 eRet = allocate_desc_buffer(i);
4817 }
4818 }
4819 else
4820 {
4821 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4822 eRet = OMX_ErrorInsufficientResources;
4823 }
4824 return eRet;
4825}
4826
4827
4828/* ======================================================================
4829FUNCTION
4830 omx_vdec::AllocateOutputBuffer
4831
4832DESCRIPTION
4833 Helper fn for AllocateBuffer in the output pin
4834
4835PARAMETERS
4836 <TBD>.
4837
4838RETURN VALUE
4839 OMX Error None if everything went well.
4840
4841========================================================================== */
4842OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4843 OMX_IN OMX_HANDLETYPE hComp,
4844 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4845 OMX_IN OMX_U32 port,
4846 OMX_IN OMX_PTR appData,
4847 OMX_IN OMX_U32 bytes)
4848{
4849 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4850 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4851 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004852 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004853 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004854#ifdef USE_ION
4855 int ion_device_fd =-1;
4856 struct ion_allocation_data ion_alloc_data;
4857 struct ion_fd_data fd_ion_data;
4858#endif
4859 if(!m_out_mem_ptr)
4860 {
4861 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4862 drv_ctx.op_buf.actualcount,
4863 drv_ctx.op_buf.buffer_size);
4864 int nBufHdrSize = 0;
4865 int nPlatformEntrySize = 0;
4866 int nPlatformListSize = 0;
4867 int nPMEMInfoSize = 0;
4868 int pmem_fd = -1;
4869 unsigned char *pmem_baseaddress = NULL;
4870
4871 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4872 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4873 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4874
4875 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4876 drv_ctx.op_buf.actualcount);
4877 nBufHdrSize = drv_ctx.op_buf.actualcount *
4878 sizeof(OMX_BUFFERHEADERTYPE);
4879
4880 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4881 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4882 nPlatformListSize = drv_ctx.op_buf.actualcount *
4883 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4884 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4885 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4886
4887 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4888 sizeof(OMX_BUFFERHEADERTYPE),
4889 nPMEMInfoSize,
4890 nPlatformListSize);
4891 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4892 drv_ctx.op_buf.actualcount);
4893#ifdef USE_ION
4894 ion_device_fd = alloc_map_ion_memory(
4895 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4896 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004897 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004898 if (ion_device_fd < 0) {
4899 return OMX_ErrorInsufficientResources;
4900 }
4901 pmem_fd = fd_ion_data.fd;
4902#else
4903 pmem_fd = open (MEM_DEVICE,O_RDWR);
4904
4905 if (pmem_fd < 0)
4906 {
4907 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4908 drv_ctx.op_buf.buffer_size);
4909 return OMX_ErrorInsufficientResources;
4910 }
4911
4912 if(pmem_fd == 0)
4913 {
4914 pmem_fd = open (MEM_DEVICE,O_RDWR);
4915
4916 if (pmem_fd < 0)
4917 {
4918 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4919 drv_ctx.op_buf.buffer_size);
4920 return OMX_ErrorInsufficientResources;
4921 }
4922 }
4923
4924 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4925 drv_ctx.op_buf.actualcount,
4926 drv_ctx.op_buf.alignment))
4927 {
4928 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4929 close(pmem_fd);
4930 return OMX_ErrorInsufficientResources;
4931 }
4932#endif
4933 if (!secure_mode) {
4934 pmem_baseaddress = (unsigned char *)mmap(NULL,
4935 (drv_ctx.op_buf.buffer_size *
4936 drv_ctx.op_buf.actualcount),
4937 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4938 if (pmem_baseaddress == MAP_FAILED)
4939 {
4940 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4941 drv_ctx.op_buf.buffer_size);
4942 close(pmem_fd);
4943#ifdef USE_ION
4944 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4945#endif
4946 return OMX_ErrorInsufficientResources;
4947 }
4948 }
4949 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4950 // Alloc mem for platform specific info
4951 char *pPtr=NULL;
4952 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4953 nPMEMInfoSize,1);
4954 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4955 calloc (sizeof(struct vdec_bufferpayload),
4956 drv_ctx.op_buf.actualcount);
4957 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4958 calloc (sizeof (struct vdec_output_frameinfo),
4959 drv_ctx.op_buf.actualcount);
4960#ifdef USE_ION
4961 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4962 calloc (sizeof(struct vdec_ion),
4963 drv_ctx.op_buf.actualcount);
4964#endif
4965
4966 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4967 && drv_ctx.ptr_respbuffer)
4968 {
4969 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4970 (drv_ctx.op_buf.buffer_size *
4971 drv_ctx.op_buf.actualcount);
4972 bufHdr = m_out_mem_ptr;
4973 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4974 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4975 (((char *) m_platform_list) + nPlatformListSize);
4976 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4977 (((char *) m_platform_entry) + nPlatformEntrySize);
4978 pPlatformList = m_platform_list;
4979 pPlatformEntry = m_platform_entry;
4980 pPMEMInfo = m_pmem_info;
4981
4982 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4983
4984 // Settting the entire storage nicely
4985 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4986 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4987 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
4988 {
4989 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4990 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4991 // Set the values when we determine the right HxW param
4992 bufHdr->nAllocLen = bytes;
4993 bufHdr->nFilledLen = 0;
4994 bufHdr->pAppPrivate = appData;
4995 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4996 // Platform specific PMEM Information
4997 // Initialize the Platform Entry
4998 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4999 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5000 pPlatformEntry->entry = pPMEMInfo;
5001 // Initialize the Platform List
5002 pPlatformList->nEntries = 1;
5003 pPlatformList->entryList = pPlatformEntry;
5004 // Keep pBuffer NULL till vdec is opened
5005 bufHdr->pBuffer = NULL;
5006 bufHdr->nOffset = 0;
5007
5008 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5009 pPMEMInfo->pmem_fd = 0;
5010 bufHdr->pPlatformPrivate = pPlatformList;
5011
5012 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005013 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005014#ifdef USE_ION
5015 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5016 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5017 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5018#endif
5019
5020 /*Create a mapping between buffers*/
5021 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5022 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5023 &drv_ctx.ptr_outputbuffer[i];
5024 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5025 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5026 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5027
5028 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5029 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5030 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5031 // Move the buffer and buffer header pointers
5032 bufHdr++;
5033 pPMEMInfo++;
5034 pPlatformEntry++;
5035 pPlatformList++;
5036 }
5037 }
5038 else
5039 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005040 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005041 m_out_mem_ptr, pPtr);
5042 if(m_out_mem_ptr)
5043 {
5044 free(m_out_mem_ptr);
5045 m_out_mem_ptr = NULL;
5046 }
5047 if(pPtr)
5048 {
5049 free(pPtr);
5050 pPtr = NULL;
5051 }
5052 if(drv_ctx.ptr_outputbuffer)
5053 {
5054 free(drv_ctx.ptr_outputbuffer);
5055 drv_ctx.ptr_outputbuffer = NULL;
5056 }
5057 if(drv_ctx.ptr_respbuffer)
5058 {
5059 free(drv_ctx.ptr_respbuffer);
5060 drv_ctx.ptr_respbuffer = NULL;
5061 }
5062#ifdef USE_ION
5063 if (drv_ctx.op_buf_ion_info) {
5064 DEBUG_PRINT_LOW("\n Free o/p ion context");
5065 free(drv_ctx.op_buf_ion_info);
5066 drv_ctx.op_buf_ion_info = NULL;
5067 }
5068#endif
5069 eRet = OMX_ErrorInsufficientResources;
5070 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005071 if (eRet == OMX_ErrorNone)
5072 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005073 }
5074
5075 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5076 {
5077 if(BITMASK_ABSENT(&m_out_bm_count,i))
5078 {
5079 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5080 break;
5081 }
5082 }
5083
5084 if (eRet == OMX_ErrorNone)
5085 {
5086 if(i < drv_ctx.op_buf.actualcount)
5087 {
5088 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005089 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005090 int rc;
5091 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5092
5093 drv_ctx.ptr_outputbuffer[i].buffer_len =
5094 drv_ctx.op_buf.buffer_size;
5095
5096 *bufferHdr = (m_out_mem_ptr + i );
5097 if (secure_mode) {
5098 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5099 }
5100 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5101
5102 buf.index = i;
5103 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5104 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005105 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005106 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5107 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005108#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005109 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005110#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005111 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5112 plane[0].data_offset = 0;
5113 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5114 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5115 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5116 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5117#ifdef USE_ION
5118 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5119#endif
5120 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5121 plane[extra_idx].data_offset = 0;
5122 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5123 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5124 return OMX_ErrorBadParameter;
5125 }
5126 buf.m.planes = plane;
5127 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005128 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005129 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5130 if (rc) {
5131 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005132 return OMX_ErrorInsufficientResources;
5133 }
5134
5135 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5136 enum v4l2_buf_type buf_type;
5137 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5138 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5139 if (rc) {
5140 return OMX_ErrorInsufficientResources;
5141 } else {
5142 streaming[CAPTURE_PORT] = true;
5143 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5144 }
5145 }
5146
5147 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5148 (*bufferHdr)->pAppPrivate = appData;
5149 BITMASK_SET(&m_out_bm_count,i);
5150 }
5151 else
5152 {
5153 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5154 eRet = OMX_ErrorInsufficientResources;
5155 }
5156 }
5157
5158 return eRet;
5159}
5160
5161
5162// AllocateBuffer -- API Call
5163/* ======================================================================
5164FUNCTION
5165 omx_vdec::AllocateBuffer
5166
5167DESCRIPTION
5168 Returns zero if all the buffers released..
5169
5170PARAMETERS
5171 None.
5172
5173RETURN VALUE
5174 true/false
5175
5176========================================================================== */
5177OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5178 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5179 OMX_IN OMX_U32 port,
5180 OMX_IN OMX_PTR appData,
5181 OMX_IN OMX_U32 bytes)
5182{
5183 unsigned i = 0;
5184 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5185
5186 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5187 if(m_state == OMX_StateInvalid)
5188 {
5189 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5190 return OMX_ErrorInvalidState;
5191 }
5192
5193 if(port == OMX_CORE_INPUT_PORT_INDEX)
5194 {
5195 if (arbitrary_bytes)
5196 {
5197 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5198 }
5199 else
5200 {
5201 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5202 }
5203 }
5204 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5205 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005206 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5207 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208 }
5209 else
5210 {
5211 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5212 eRet = OMX_ErrorBadPortIndex;
5213 }
5214 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5215 if(eRet == OMX_ErrorNone)
5216 {
5217 if(allocate_done()){
5218 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5219 {
5220 // Send the callback now
5221 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5222 post_event(OMX_CommandStateSet,OMX_StateIdle,
5223 OMX_COMPONENT_GENERATE_EVENT);
5224 }
5225 }
5226 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5227 {
5228 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5229 {
5230 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5231 post_event(OMX_CommandPortEnable,
5232 OMX_CORE_INPUT_PORT_INDEX,
5233 OMX_COMPONENT_GENERATE_EVENT);
5234 }
5235 }
5236 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5237 {
5238 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5239 {
5240 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5241 post_event(OMX_CommandPortEnable,
5242 OMX_CORE_OUTPUT_PORT_INDEX,
5243 OMX_COMPONENT_GENERATE_EVENT);
5244 }
5245 }
5246 }
5247 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5248 return eRet;
5249}
5250
5251// Free Buffer - API call
5252/* ======================================================================
5253FUNCTION
5254 omx_vdec::FreeBuffer
5255
5256DESCRIPTION
5257
5258PARAMETERS
5259 None.
5260
5261RETURN VALUE
5262 true/false
5263
5264========================================================================== */
5265OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5266 OMX_IN OMX_U32 port,
5267 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5268{
5269 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5270 unsigned int nPortIndex;
5271 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5272
5273 if(m_state == OMX_StateIdle &&
5274 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5275 {
5276 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5277 }
5278 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5279 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5280 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005281 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005282 }
5283 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5284 {
5285 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5286 post_event(OMX_EventError,
5287 OMX_ErrorPortUnpopulated,
5288 OMX_COMPONENT_GENERATE_EVENT);
5289
5290 return OMX_ErrorIncorrectStateOperation;
5291 }
5292 else if (m_state != OMX_StateInvalid)
5293 {
5294 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5295 post_event(OMX_EventError,
5296 OMX_ErrorPortUnpopulated,
5297 OMX_COMPONENT_GENERATE_EVENT);
5298 }
5299
5300 if(port == OMX_CORE_INPUT_PORT_INDEX)
5301 {
5302 /*Check if arbitrary bytes*/
5303 if(!arbitrary_bytes && !input_use_buffer)
5304 nPortIndex = buffer - m_inp_mem_ptr;
5305 else
5306 nPortIndex = buffer - m_inp_heap_ptr;
5307
5308 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5309 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5310 {
5311 // Clear the bit associated with it.
5312 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5313 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5314 if (input_use_buffer == true)
5315 {
5316
5317 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5318 if(m_phdr_pmem_ptr)
5319 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5320 }
5321 else
5322 {
5323 if (arbitrary_bytes)
5324 {
5325 if(m_phdr_pmem_ptr)
5326 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5327 else
5328 free_input_buffer(nPortIndex,NULL);
5329 }
5330 else
5331 free_input_buffer(buffer);
5332 }
5333 m_inp_bPopulated = OMX_FALSE;
5334 /*Free the Buffer Header*/
5335 if (release_input_done())
5336 {
5337 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5338 free_input_buffer_header();
5339 }
5340 }
5341 else
5342 {
5343 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5344 eRet = OMX_ErrorBadPortIndex;
5345 }
5346
5347 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5348 && release_input_done())
5349 {
5350 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5351 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5352 post_event(OMX_CommandPortDisable,
5353 OMX_CORE_INPUT_PORT_INDEX,
5354 OMX_COMPONENT_GENERATE_EVENT);
5355 }
5356 }
5357 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5358 {
5359 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005360 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005361 if(nPortIndex < drv_ctx.op_buf.actualcount)
5362 {
5363 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5364 // Clear the bit associated with it.
5365 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5366 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005367 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005368
5369 if (release_output_done())
5370 {
5371 free_output_buffer_header();
5372 }
5373 }
5374 else
5375 {
5376 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5377 eRet = OMX_ErrorBadPortIndex;
5378 }
5379 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5380 && release_output_done())
5381 {
5382 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5383
5384 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5385 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5386#ifdef _ANDROID_ICS_
5387 if (m_enable_android_native_buffers)
5388 {
5389 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5390 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5391 }
5392#endif
5393
5394 post_event(OMX_CommandPortDisable,
5395 OMX_CORE_OUTPUT_PORT_INDEX,
5396 OMX_COMPONENT_GENERATE_EVENT);
5397 }
5398 }
5399 else
5400 {
5401 eRet = OMX_ErrorBadPortIndex;
5402 }
5403 if((eRet == OMX_ErrorNone) &&
5404 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5405 {
5406 if(release_done())
5407 {
5408 // Send the callback now
5409 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5410 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5411 OMX_COMPONENT_GENERATE_EVENT);
5412 }
5413 }
5414 return eRet;
5415}
5416
5417
5418/* ======================================================================
5419FUNCTION
5420 omx_vdec::EmptyThisBuffer
5421
5422DESCRIPTION
5423 This routine is used to push the encoded video frames to
5424 the video decoder.
5425
5426PARAMETERS
5427 None.
5428
5429RETURN VALUE
5430 OMX Error None if everything went successful.
5431
5432========================================================================== */
5433OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5434 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5435{
5436 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5437 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5438
5439 if(m_state == OMX_StateInvalid)
5440 {
5441 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5442 return OMX_ErrorInvalidState;
5443 }
5444
5445 if (buffer == NULL)
5446 {
5447 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5448 return OMX_ErrorBadParameter;
5449 }
5450
5451 if (!m_inp_bEnabled)
5452 {
5453 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5454 return OMX_ErrorIncorrectStateOperation;
5455 }
5456
5457 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5458 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005459 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460 return OMX_ErrorBadPortIndex;
5461 }
5462
5463#ifdef _ANDROID_
5464 if(iDivXDrmDecrypt)
5465 {
5466 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5467 if(drmErr != OMX_ErrorNone) {
5468 // this error can be ignored
5469 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5470 }
5471 }
5472#endif //_ANDROID_
5473 if (perf_flag)
5474 {
5475 if (!latency)
5476 {
5477 dec_time.stop();
5478 latency = dec_time.processing_time_us();
5479 dec_time.start();
5480 }
5481 }
5482
5483 if (arbitrary_bytes)
5484 {
5485 nBufferIndex = buffer - m_inp_heap_ptr;
5486 }
5487 else
5488 {
5489 if (input_use_buffer == true)
5490 {
5491 nBufferIndex = buffer - m_inp_heap_ptr;
5492 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5493 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5494 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5495 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005496 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5498 }
5499 else{
5500 nBufferIndex = buffer - m_inp_mem_ptr;
5501 }
5502 }
5503
5504 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5505 {
5506 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5507 return OMX_ErrorBadParameter;
5508 }
5509
5510 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5511 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5512 if (arbitrary_bytes)
5513 {
5514 post_event ((unsigned)hComp,(unsigned)buffer,
5515 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5516 }
5517 else
5518 {
5519 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5520 set_frame_rate(buffer->nTimeStamp);
5521 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5522 }
5523 return OMX_ErrorNone;
5524}
5525
5526/* ======================================================================
5527FUNCTION
5528 omx_vdec::empty_this_buffer_proxy
5529
5530DESCRIPTION
5531 This routine is used to push the encoded video frames to
5532 the video decoder.
5533
5534PARAMETERS
5535 None.
5536
5537RETURN VALUE
5538 OMX Error None if everything went successful.
5539
5540========================================================================== */
5541OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5542 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5543{
5544 int push_cnt = 0,i=0;
5545 unsigned nPortIndex = 0;
5546 OMX_ERRORTYPE ret = OMX_ErrorNone;
5547 struct vdec_input_frameinfo frameinfo;
5548 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549 struct vdec_seqheader seq_header;
5550 bool port_setting_changed = true;
5551 bool not_coded_vop = false;
5552
5553 /*Should we generate a Aync error event*/
5554 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5555 {
5556 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5557 return OMX_ErrorBadParameter;
5558 }
5559
5560 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5561
5562 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5563 {
5564 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5565 nPortIndex);
5566 return OMX_ErrorBadParameter;
5567 }
5568
5569 pending_input_buffers++;
5570
5571 /* return zero length and not an EOS buffer */
5572 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5573 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5574 {
5575 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5576 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5577 OMX_COMPONENT_GENERATE_EBD);
5578 return OMX_ErrorNone;
5579 }
5580
5581
5582 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5583 mp4StreamType psBits;
5584 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5585 psBits.numBytes = buffer->nFilledLen;
5586 mp4_headerparser.parseHeader(&psBits);
5587 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5588 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5589 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005590 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591 buffer->nFilledLen,frame_count);
5592 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5593 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5594 not_coded_vop = false;
5595 buffer->nFilledLen = 0;
5596 }
5597 }
5598 }
5599
5600 if(input_flush_progress == true
5601
5602 || not_coded_vop
5603
5604 )
5605 {
5606 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5607 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5608 OMX_COMPONENT_GENERATE_EBD);
5609 return OMX_ErrorNone;
5610 }
5611
5612 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5613
5614 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5615 {
5616 return OMX_ErrorBadParameter;
5617 }
5618
5619 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5620 /*for use buffer we need to memcpy the data*/
5621 temp_buffer->buffer_len = buffer->nFilledLen;
5622
5623 if (input_use_buffer)
5624 {
5625 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5626 {
5627 if(arbitrary_bytes)
5628 {
5629 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5630 }
5631 else
5632 {
5633 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5634 buffer->nFilledLen);
5635 }
5636 }
5637 else
5638 {
5639 return OMX_ErrorBadParameter;
5640 }
5641
5642 }
5643
5644 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5645 frameinfo.client_data = (void *) buffer;
5646 frameinfo.datalen = temp_buffer->buffer_len;
5647 frameinfo.flags = 0;
5648 frameinfo.offset = buffer->nOffset;
5649 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5650 frameinfo.pmem_offset = temp_buffer->offset;
5651 frameinfo.timestamp = buffer->nTimeStamp;
5652 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5653 {
5654 DEBUG_PRINT_LOW("ETB: dmx enabled");
5655 if (m_demux_entries == 0)
5656 {
5657 extract_demux_addr_offsets(buffer);
5658 }
5659
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005660 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005661 handle_demux_data(buffer);
5662 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5663 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5664 }
5665 else
5666 {
5667 frameinfo.desc_addr = NULL;
5668 frameinfo.desc_size = 0;
5669 }
5670 if(!arbitrary_bytes)
5671 {
5672 frameinfo.flags |= buffer->nFlags;
5673 }
5674
5675#ifdef _ANDROID_
5676 if (m_debug_timestamp)
5677 {
5678 if(arbitrary_bytes)
5679 {
5680 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5681 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5682 }
5683 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5684 {
5685 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5686 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5687 }
5688 }
5689#endif
5690
5691#ifdef INPUT_BUFFER_LOG
5692 if (inputBufferFile1)
5693 {
5694 fwrite((const char *)temp_buffer->bufferaddr,
5695 temp_buffer->buffer_len,1,inputBufferFile1);
5696 }
5697#endif
5698
5699 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5700 {
5701 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5702 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5703 }
5704
5705 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5706 {
5707 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5708 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5709 h264_scratch.nFilledLen = 0;
5710 nal_count = 0;
5711 look_ahead_nal = false;
5712 frame_count = 0;
5713 if (m_frame_parser.mutils)
5714 m_frame_parser.mutils->initialize_frame_checking_environment();
5715 m_frame_parser.flush();
5716 h264_last_au_ts = LLONG_MAX;
5717 h264_last_au_flags = 0;
5718 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5719 m_demux_entries = 0;
5720 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005721 struct v4l2_buffer buf;
5722 struct v4l2_plane plane;
5723 memset( (void *)&buf, 0, sizeof(buf));
5724 memset( (void *)&plane, 0, sizeof(plane));
5725 int rc;
5726 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005727 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5728 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005729 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730 }
5731 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5732 buf.index = nPortIndex;
5733 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5734 buf.memory = V4L2_MEMORY_USERPTR;
5735 plane.bytesused = temp_buffer->buffer_len;
5736 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005737 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5738 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005739 plane.reserved[0] = temp_buffer->pmem_fd;
5740 plane.reserved[1] = temp_buffer->offset;
5741 plane.data_offset = 0;
5742 buf.m.planes = &plane;
5743 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005744 if (frameinfo.timestamp >= LLONG_MAX) {
5745 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5746 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005747 //assumption is that timestamp is in milliseconds
5748 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5749 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005750 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5751
Shalaj Jain273b3e02012-06-22 19:08:03 -07005752 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005753 if(rc)
5754 {
5755 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5756 return OMX_ErrorHardware;
5757 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005758 if(!streaming[OUTPUT_PORT])
5759 {
5760 enum v4l2_buf_type buf_type;
5761 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005762
Shalaj Jain273b3e02012-06-22 19:08:03 -07005763 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5764 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5765 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5766 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005767 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005769 } else{
5770 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005771 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772 }
5773}
5774 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5775 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5776 time_stamp_dts.insert_timestamp(buffer);
5777
5778 return ret;
5779}
5780
5781/* ======================================================================
5782FUNCTION
5783 omx_vdec::FillThisBuffer
5784
5785DESCRIPTION
5786 IL client uses this method to release the frame buffer
5787 after displaying them.
5788
5789PARAMETERS
5790 None.
5791
5792RETURN VALUE
5793 true/false
5794
5795========================================================================== */
5796OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5797 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5798{
5799
5800 if(m_state == OMX_StateInvalid)
5801 {
5802 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5803 return OMX_ErrorInvalidState;
5804 }
5805
5806 if (!m_out_bEnabled)
5807 {
5808 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5809 return OMX_ErrorIncorrectStateOperation;
5810 }
5811
Vinay Kaliada4f4422013-01-09 10:45:03 -08005812 if (buffer == NULL ||
5813 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005814 {
5815 return OMX_ErrorBadParameter;
5816 }
5817
5818 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5819 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005820 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821 return OMX_ErrorBadPortIndex;
5822 }
5823
5824 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005825 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005826 return OMX_ErrorNone;
5827}
5828/* ======================================================================
5829FUNCTION
5830 omx_vdec::fill_this_buffer_proxy
5831
5832DESCRIPTION
5833 IL client uses this method to release the frame buffer
5834 after displaying them.
5835
5836PARAMETERS
5837 None.
5838
5839RETURN VALUE
5840 true/false
5841
5842========================================================================== */
5843OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5844 OMX_IN OMX_HANDLETYPE hComp,
5845 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5846{
5847 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005848 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5849 unsigned nPortIndex = 0;
5850 struct vdec_fillbuffer_cmd fillbuffer;
5851 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5852 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5853
Vinay Kaliada4f4422013-01-09 10:45:03 -08005854 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855
Vinay Kaliada4f4422013-01-09 10:45:03 -08005856 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005857 return OMX_ErrorBadParameter;
5858
5859 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5860 bufferAdd, bufferAdd->pBuffer);
5861 /*Return back the output buffer to client*/
5862 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5863 {
5864 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5865 buffer->nFilledLen = 0;
5866 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5867 return OMX_ErrorNone;
5868 }
5869 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005870 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005871 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5872 if (ptr_respbuffer)
5873 {
5874 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5875 }
5876
5877 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5878 {
5879 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5880 buffer->nFilledLen = 0;
5881 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5882 pending_output_buffers--;
5883 return OMX_ErrorBadParameter;
5884 }
5885
Shalaj Jain286b0062013-02-21 20:35:48 -08005886 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005887 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08005888 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005889
5890#ifdef _ANDROID_ICS_
5891 if (m_enable_android_native_buffers)
5892 {
5893 // Acquire a write lock on this buffer.
5894 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5895 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5896 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5897 buffer->nFilledLen = 0;
5898 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5899 pending_output_buffers--;
5900 return OMX_ErrorInsufficientResources;
5901 } else {
5902 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5903 }
5904 }
5905#endif
5906 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08005907 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005908 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08005909 memset( (void *)&buf, 0, sizeof(buf));
5910 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005911 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005913 buf.index = nPortIndex;
5914 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5915 buf.memory = V4L2_MEMORY_USERPTR;
5916 plane[0].bytesused = buffer->nFilledLen;
5917 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005918 plane[0].m.userptr =
5919 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5920 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005921 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5922 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5923 plane[0].data_offset = 0;
5924 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5925 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5926 plane[extra_idx].bytesused = 0;
5927 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5928 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5929#ifdef USE_ION
5930 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5931#endif
5932 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5933 plane[extra_idx].data_offset = 0;
5934 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5935 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5936 return OMX_ErrorBadParameter;
5937 }
5938 buf.m.planes = plane;
5939 buf.length = drv_ctx.num_planes;
5940 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5941 if (rc) {
5942 /*TODO: How to handle this case */
5943 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5944 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005945//#ifdef _ANDROID_ICS_
5946 // if (m_enable_android_native_buffers)
5947 // {
5948 // Unlock the buffer
5949 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
5950 // DEBUG_PRINT_ERROR("Releasing genlock failed");
5951 // return OMX_ErrorInsufficientResources;
5952 /// } else {
5953 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
5954 // }
5955 // }
5956//#endif
5957 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
5958 // pending_output_buffers--;
5959 // return OMX_ErrorBadParameter;
5960 //}
5961 return OMX_ErrorNone;
5962}
5963
5964/* ======================================================================
5965FUNCTION
5966 omx_vdec::SetCallbacks
5967
5968DESCRIPTION
5969 Set the callbacks.
5970
5971PARAMETERS
5972 None.
5973
5974RETURN VALUE
5975 OMX Error None if everything successful.
5976
5977========================================================================== */
5978OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
5979 OMX_IN OMX_CALLBACKTYPE* callbacks,
5980 OMX_IN OMX_PTR appData)
5981{
5982
5983 m_cb = *callbacks;
5984 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5985 m_cb.EventHandler,m_cb.FillBufferDone);
5986 m_app_data = appData;
5987 return OMX_ErrorNotImplemented;
5988}
5989
5990/* ======================================================================
5991FUNCTION
5992 omx_vdec::ComponentDeInit
5993
5994DESCRIPTION
5995 Destroys the component and release memory allocated to the heap.
5996
5997PARAMETERS
5998 <TBD>.
5999
6000RETURN VALUE
6001 OMX Error None if everything successful.
6002
6003========================================================================== */
6004OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6005{
6006#ifdef _ANDROID_
6007 if(iDivXDrmDecrypt)
6008 {
6009 delete iDivXDrmDecrypt;
6010 iDivXDrmDecrypt=NULL;
6011 }
6012#endif //_ANDROID_
6013
Shalaj Jain286b0062013-02-21 20:35:48 -08006014 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015 if (OMX_StateLoaded != m_state)
6016 {
6017 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6018 m_state);
6019 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6020 }
6021 else
6022 {
6023 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6024 }
6025
6026 /*Check if the output buffers have to be cleaned up*/
6027 if(m_out_mem_ptr)
6028 {
6029 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006030 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006031 {
6032 free_output_buffer (&m_out_mem_ptr[i]);
6033#ifdef _ANDROID_ICS_
6034 if (m_enable_android_native_buffers)
6035 {
6036 if (native_buffer[i].inuse)
6037 {
6038 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6039 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6040 }
6041 native_buffer[i].inuse = false;
6042 }
6043 }
6044#endif
6045 }
6046#ifdef _ANDROID_ICS_
6047 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6048#endif
6049 }
6050
6051 /*Check if the input buffers have to be cleaned up*/
6052 if(m_inp_mem_ptr || m_inp_heap_ptr)
6053 {
6054 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006055 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006056 {
6057 if (m_inp_mem_ptr)
6058 free_input_buffer (i,&m_inp_mem_ptr[i]);
6059 else
6060 free_input_buffer (i,NULL);
6061 }
6062 }
6063 free_input_buffer_header();
6064 free_output_buffer_header();
6065 if(h264_scratch.pBuffer)
6066 {
6067 free(h264_scratch.pBuffer);
6068 h264_scratch.pBuffer = NULL;
6069 }
6070
6071 if (h264_parser)
6072 {
6073 delete h264_parser;
6074 h264_parser = NULL;
6075 }
6076
6077 if(m_platform_list)
6078 {
6079 free(m_platform_list);
6080 m_platform_list = NULL;
6081 }
6082 if(m_vendor_config.pData)
6083 {
6084 free(m_vendor_config.pData);
6085 m_vendor_config.pData = NULL;
6086 }
6087
6088 // Reset counters in mesg queues
6089 m_ftb_q.m_size=0;
6090 m_cmd_q.m_size=0;
6091 m_etb_q.m_size=0;
6092 m_ftb_q.m_read = m_ftb_q.m_write =0;
6093 m_cmd_q.m_read = m_cmd_q.m_write =0;
6094 m_etb_q.m_read = m_etb_q.m_write =0;
6095#ifdef _ANDROID_
6096 if (m_debug_timestamp)
6097 {
6098 m_timestamp_list.reset_ts_list();
6099 }
6100#endif
6101
6102 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6103 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6104 // NULL);
6105 DEBUG_PRINT_HIGH("\n Close the driver instance");
6106
6107#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006108 if (inputBufferFile1)
6109 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006110#endif
6111#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006112 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006113 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006114#endif
6115#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006116 if (outputExtradataFile)
6117 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118#endif
6119 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6120 return OMX_ErrorNone;
6121}
6122
6123/* ======================================================================
6124FUNCTION
6125 omx_vdec::UseEGLImage
6126
6127DESCRIPTION
6128 OMX Use EGL Image method implementation <TBD>.
6129
6130PARAMETERS
6131 <TBD>.
6132
6133RETURN VALUE
6134 Not Implemented error.
6135
6136========================================================================== */
6137OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6138 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6139 OMX_IN OMX_U32 port,
6140 OMX_IN OMX_PTR appData,
6141 OMX_IN void* eglImage)
6142{
6143 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6144 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6145 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6146
6147#ifdef USE_EGL_IMAGE_GPU
6148 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6149 EGLint fd = -1, offset = 0,pmemPtr = 0;
6150#else
6151 int fd = -1, offset = 0;
6152#endif
6153 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6154 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6155 DEBUG_PRINT_ERROR("\n ");
6156 }
6157#ifdef USE_EGL_IMAGE_GPU
6158 if(m_display_id == NULL) {
6159 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6160 return OMX_ErrorInsufficientResources;
6161 }
6162 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6163 eglGetProcAddress("eglQueryImageKHR");
6164 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6165 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6166 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6167#else //with OMX test app
6168 struct temp_egl {
6169 int pmem_fd;
6170 int offset;
6171 };
6172 struct temp_egl *temp_egl_id = NULL;
6173 void * pmemPtr = (void *) eglImage;
6174 temp_egl_id = (struct temp_egl *)eglImage;
6175 if (temp_egl_id != NULL)
6176 {
6177 fd = temp_egl_id->pmem_fd;
6178 offset = temp_egl_id->offset;
6179 }
6180#endif
6181 if (fd < 0) {
6182 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6183 return OMX_ErrorInsufficientResources;
6184 }
6185 pmem_info.pmem_fd = (OMX_U32) fd;
6186 pmem_info.offset = (OMX_U32) offset;
6187 pmem_entry.entry = (void *) &pmem_info;
6188 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6189 pmem_list.entryList = &pmem_entry;
6190 pmem_list.nEntries = 1;
6191 ouput_egl_buffers = true;
6192 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6193 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6194 (OMX_U8 *)pmemPtr)) {
6195 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6196 return OMX_ErrorInsufficientResources;
6197 }
6198 return OMX_ErrorNone;
6199}
6200
6201/* ======================================================================
6202FUNCTION
6203 omx_vdec::ComponentRoleEnum
6204
6205DESCRIPTION
6206 OMX Component Role Enum method implementation.
6207
6208PARAMETERS
6209 <TBD>.
6210
6211RETURN VALUE
6212 OMX Error None if everything is successful.
6213========================================================================== */
6214OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6215 OMX_OUT OMX_U8* role,
6216 OMX_IN OMX_U32 index)
6217{
6218 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6219
6220 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6221 {
6222 if((0 == index) && role)
6223 {
6224 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6225 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6226 }
6227 else
6228 {
6229 eRet = OMX_ErrorNoMore;
6230 }
6231 }
6232 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6233 {
6234 if((0 == index) && role)
6235 {
6236 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6237 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6238 }
6239 else
6240 {
6241 eRet = OMX_ErrorNoMore;
6242 }
6243 }
6244 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6245 {
6246 if((0 == index) && role)
6247 {
6248 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6249 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6250 }
6251 else
6252 {
6253 DEBUG_PRINT_LOW("\n No more roles \n");
6254 eRet = OMX_ErrorNoMore;
6255 }
6256 }
6257
6258 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6259 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6260 )
6261
6262 {
6263 if((0 == index) && role)
6264 {
6265 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6266 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6267 }
6268 else
6269 {
6270 DEBUG_PRINT_LOW("\n No more roles \n");
6271 eRet = OMX_ErrorNoMore;
6272 }
6273 }
6274 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6275 {
6276 if((0 == index) && role)
6277 {
6278 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6279 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6280 }
6281 else
6282 {
6283 DEBUG_PRINT_LOW("\n No more roles \n");
6284 eRet = OMX_ErrorNoMore;
6285 }
6286 }
6287 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6288 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6289 )
6290 {
6291 if((0 == index) && role)
6292 {
6293 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6294 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6295 }
6296 else
6297 {
6298 DEBUG_PRINT_LOW("\n No more roles \n");
6299 eRet = OMX_ErrorNoMore;
6300 }
6301 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006302 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6303 {
6304 if((0 == index) && role)
6305 {
6306 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6307 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6308 }
6309 else
6310 {
6311 DEBUG_PRINT_LOW("\n No more roles \n");
6312 eRet = OMX_ErrorNoMore;
6313 }
6314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006315 else
6316 {
6317 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6318 eRet = OMX_ErrorInvalidComponentName;
6319 }
6320 return eRet;
6321}
6322
6323
6324
6325
6326/* ======================================================================
6327FUNCTION
6328 omx_vdec::AllocateDone
6329
6330DESCRIPTION
6331 Checks if entire buffer pool is allocated by IL Client or not.
6332 Need this to move to IDLE state.
6333
6334PARAMETERS
6335 None.
6336
6337RETURN VALUE
6338 true/false.
6339
6340========================================================================== */
6341bool omx_vdec::allocate_done(void)
6342{
6343 bool bRet = false;
6344 bool bRet_In = false;
6345 bool bRet_Out = false;
6346
6347 bRet_In = allocate_input_done();
6348 bRet_Out = allocate_output_done();
6349
6350 if(bRet_In && bRet_Out)
6351 {
6352 bRet = true;
6353 }
6354
6355 return bRet;
6356}
6357/* ======================================================================
6358FUNCTION
6359 omx_vdec::AllocateInputDone
6360
6361DESCRIPTION
6362 Checks if I/P buffer pool is allocated by IL Client or not.
6363
6364PARAMETERS
6365 None.
6366
6367RETURN VALUE
6368 true/false.
6369
6370========================================================================== */
6371bool omx_vdec::allocate_input_done(void)
6372{
6373 bool bRet = false;
6374 unsigned i=0;
6375
6376 if (m_inp_mem_ptr == NULL)
6377 {
6378 return bRet;
6379 }
6380 if(m_inp_mem_ptr )
6381 {
6382 for(;i<drv_ctx.ip_buf.actualcount;i++)
6383 {
6384 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6385 {
6386 break;
6387 }
6388 }
6389 }
6390 if(i == drv_ctx.ip_buf.actualcount)
6391 {
6392 bRet = true;
6393 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6394 }
6395 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6396 {
6397 m_inp_bPopulated = OMX_TRUE;
6398 }
6399 return bRet;
6400}
6401/* ======================================================================
6402FUNCTION
6403 omx_vdec::AllocateOutputDone
6404
6405DESCRIPTION
6406 Checks if entire O/P buffer pool is allocated by IL Client or not.
6407
6408PARAMETERS
6409 None.
6410
6411RETURN VALUE
6412 true/false.
6413
6414========================================================================== */
6415bool omx_vdec::allocate_output_done(void)
6416{
6417 bool bRet = false;
6418 unsigned j=0;
6419
6420 if (m_out_mem_ptr == NULL)
6421 {
6422 return bRet;
6423 }
6424
6425 if (m_out_mem_ptr)
6426 {
6427 for(;j < drv_ctx.op_buf.actualcount;j++)
6428 {
6429 if(BITMASK_ABSENT(&m_out_bm_count,j))
6430 {
6431 break;
6432 }
6433 }
6434 }
6435
6436 if(j == drv_ctx.op_buf.actualcount)
6437 {
6438 bRet = true;
6439 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6440 if(m_out_bEnabled)
6441 m_out_bPopulated = OMX_TRUE;
6442 }
6443
6444 return bRet;
6445}
6446
6447/* ======================================================================
6448FUNCTION
6449 omx_vdec::ReleaseDone
6450
6451DESCRIPTION
6452 Checks if IL client has released all the buffers.
6453
6454PARAMETERS
6455 None.
6456
6457RETURN VALUE
6458 true/false
6459
6460========================================================================== */
6461bool omx_vdec::release_done(void)
6462{
6463 bool bRet = false;
6464
6465 if(release_input_done())
6466 {
6467 if(release_output_done())
6468 {
6469 bRet = true;
6470 }
6471 }
6472 return bRet;
6473}
6474
6475
6476/* ======================================================================
6477FUNCTION
6478 omx_vdec::ReleaseOutputDone
6479
6480DESCRIPTION
6481 Checks if IL client has released all the buffers.
6482
6483PARAMETERS
6484 None.
6485
6486RETURN VALUE
6487 true/false
6488
6489========================================================================== */
6490bool omx_vdec::release_output_done(void)
6491{
6492 bool bRet = false;
6493 unsigned i=0,j=0;
6494
6495 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6496 if(m_out_mem_ptr)
6497 {
6498 for(;j < drv_ctx.op_buf.actualcount ; j++)
6499 {
6500 if(BITMASK_PRESENT(&m_out_bm_count,j))
6501 {
6502 break;
6503 }
6504 }
6505 if(j == drv_ctx.op_buf.actualcount)
6506 {
6507 m_out_bm_count = 0;
6508 bRet = true;
6509 }
6510 }
6511 else
6512 {
6513 m_out_bm_count = 0;
6514 bRet = true;
6515 }
6516 return bRet;
6517}
6518/* ======================================================================
6519FUNCTION
6520 omx_vdec::ReleaseInputDone
6521
6522DESCRIPTION
6523 Checks if IL client has released all the buffers.
6524
6525PARAMETERS
6526 None.
6527
6528RETURN VALUE
6529 true/false
6530
6531========================================================================== */
6532bool omx_vdec::release_input_done(void)
6533{
6534 bool bRet = false;
6535 unsigned i=0,j=0;
6536
6537 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6538 if(m_inp_mem_ptr)
6539 {
6540 for(;j<drv_ctx.ip_buf.actualcount;j++)
6541 {
6542 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6543 {
6544 break;
6545 }
6546 }
6547 if(j==drv_ctx.ip_buf.actualcount)
6548 {
6549 bRet = true;
6550 }
6551 }
6552 else
6553 {
6554 bRet = true;
6555 }
6556 return bRet;
6557}
6558
6559OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6560 OMX_BUFFERHEADERTYPE * buffer)
6561{
6562 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6563 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6564 {
6565 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6566 return OMX_ErrorBadParameter;
6567 }
6568 else if (output_flush_progress)
6569 {
6570 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6571 buffer->nFilledLen = 0;
6572 buffer->nTimeStamp = 0;
6573 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6574 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6575 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6576 }
6577
6578 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6579 buffer, buffer->pBuffer);
6580 pending_output_buffers --;
6581
6582 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6583 {
6584 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6585 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006586 post_event((unsigned)NULL, (unsigned)NULL,
6587 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006588
6589 if (psource_frame)
6590 {
6591 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6592 psource_frame = NULL;
6593 }
6594 if (pdest_frame)
6595 {
6596 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006597 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6598 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006599 pdest_frame = NULL;
6600 }
6601 }
6602
6603 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6604#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006605 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006606 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006607 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006608 int stride = drv_ctx.video_resolution.stride;
6609 int scanlines = drv_ctx.video_resolution.scan_lines;
6610 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006611 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006612 int bytes_written = 0;
6613 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6614 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6615 temp += stride;
6616 }
6617 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006618 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006619 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6620 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6621 temp += stride_c;
6622 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006623 }
6624#endif
6625
6626 /* For use buffer we need to copy the data */
6627 if (!output_flush_progress)
6628 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006629 /* This is the error check for non-recoverable errros */
6630 if (buffer->nFilledLen > 0)
6631 time_stamp_dts.get_next_timestamp(buffer,
6632 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6633 ?true:false);
6634 else {
6635 m_inp_err_count++;
6636 time_stamp_dts.remove_time_stamp(
6637 buffer->nTimeStamp,
6638 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6639 ?true:false);
6640 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006641 if (m_debug_timestamp)
6642 {
6643 {
6644 OMX_TICKS expected_ts = 0;
6645 m_timestamp_list.pop_min_ts(expected_ts);
6646 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6647 buffer->nTimeStamp, expected_ts);
6648
6649 if (buffer->nTimeStamp != expected_ts)
6650 {
6651 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6652 }
6653 }
6654 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006655 }
6656 if (m_cb.FillBufferDone)
6657 {
6658 if (buffer->nFilledLen > 0)
6659 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006660 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006661 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6662 // Keep min timestamp interval to handle corrupted bit stream scenario
6663 set_frame_rate(buffer->nTimeStamp);
6664 else if (arbitrary_bytes)
6665 adjust_timestamp(buffer->nTimeStamp);
6666 if (perf_flag)
6667 {
6668 if (!proc_frms)
6669 {
6670 dec_time.stop();
6671 latency = dec_time.processing_time_us() - latency;
6672 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6673 dec_time.start();
6674 fps_metrics.start();
6675 }
6676 proc_frms++;
6677 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6678 {
6679 OMX_U64 proc_time = 0;
6680 fps_metrics.stop();
6681 proc_time = fps_metrics.processing_time_us();
6682 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6683 proc_frms, (float)proc_time / 1e6,
6684 (float)(1e6 * proc_frms) / proc_time);
6685 proc_frms = 0;
6686 }
6687 }
6688
6689#ifdef OUTPUT_EXTRADATA_LOG
6690 if (outputExtradataFile)
6691 {
6692
6693 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6694 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6695 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6696 buffer->nFilledLen + 3)&(~3));
6697 while(p_extra &&
6698 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6699 {
6700 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6701 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6702 if (p_extra->eType == OMX_ExtraDataNone)
6703 {
6704 break;
6705 }
6706 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6707 }
6708 }
6709#endif
6710 }
6711 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6712 prev_ts = LLONG_MAX;
6713 rst_prev_ts = true;
6714 }
6715
6716 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6717 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6718 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006719 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006720#ifdef _ANDROID_ICS_
6721 if (m_enable_android_native_buffers)
6722 {
6723 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6724 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6725 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6726 return OMX_ErrorInsufficientResources;
6727 }
6728 else {
6729 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6730 }
6731 }
6732 }
6733#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006734 OMX_BUFFERHEADERTYPE *il_buffer;
6735 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6736 if (il_buffer)
6737 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6738 else {
6739 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6740 return OMX_ErrorBadParameter;
6741 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006742 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006743 }
6744 else
6745 {
6746 return OMX_ErrorBadParameter;
6747 }
6748
6749 return OMX_ErrorNone;
6750}
6751
6752OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6753 OMX_BUFFERHEADERTYPE* buffer)
6754{
6755
6756 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6757 {
6758 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6759 return OMX_ErrorBadParameter;
6760 }
6761
6762 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6763 buffer, buffer->pBuffer);
6764 pending_input_buffers--;
6765
6766 if (arbitrary_bytes)
6767 {
6768 if (pdest_frame == NULL && input_flush_progress == false)
6769 {
6770 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6771 pdest_frame = buffer;
6772 buffer->nFilledLen = 0;
6773 buffer->nTimeStamp = LLONG_MAX;
6774 push_input_buffer (hComp);
6775 }
6776 else
6777 {
6778 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6779 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006780 if (!m_input_free_q.insert_entry((unsigned)buffer,
6781 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006782 {
6783 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6784 }
6785 }
6786 }
6787 else if(m_cb.EmptyBufferDone)
6788 {
6789 buffer->nFilledLen = 0;
6790 if (input_use_buffer == true){
6791 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6792 }
6793 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6794 }
6795 return OMX_ErrorNone;
6796}
6797
Shalaj Jain273b3e02012-06-22 19:08:03 -07006798int omx_vdec::async_message_process (void *context, void* message)
6799{
6800 omx_vdec* omx = NULL;
6801 struct vdec_msginfo *vdec_msg = NULL;
6802 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006803 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006804 struct vdec_output_frameinfo *output_respbuf = NULL;
6805 int rc=1;
6806 if (context == NULL || message == NULL)
6807 {
6808 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6809 return -1;
6810 }
6811 vdec_msg = (struct vdec_msginfo *)message;
6812
6813 omx = reinterpret_cast<omx_vdec*>(context);
6814
Shalaj Jain273b3e02012-06-22 19:08:03 -07006815 switch (vdec_msg->msgcode)
6816 {
6817
6818 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006819 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006820 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6821 break;
6822
6823 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006824 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006825 OMX_COMPONENT_GENERATE_START_DONE);
6826 break;
6827
6828 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006829 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006830 OMX_COMPONENT_GENERATE_STOP_DONE);
6831 break;
6832
6833 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006834 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006835 OMX_COMPONENT_GENERATE_RESUME_DONE);
6836 break;
6837
6838 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006839 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006840 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6841 break;
6842
6843 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006844 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006845 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6846 break;
6847 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006848 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006849 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6850 break;
6851 case VDEC_MSG_RESP_INPUT_FLUSHED:
6852 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6853
Shalaj Jain286b0062013-02-21 20:35:48 -08006854 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6855 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006856
6857 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6858 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6859 if (omxhdr == NULL ||
6860 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6861 {
6862 omxhdr = NULL;
6863 vdec_msg->status_code = VDEC_S_EFATAL;
6864 }
6865
6866 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6867 OMX_COMPONENT_GENERATE_EBD);
6868 break;
6869 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6870 int64_t *timestamp;
6871 timestamp = (int64_t *) malloc(sizeof(int64_t));
6872 if (timestamp) {
6873 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6874 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6875 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6876 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6877 vdec_msg->msgdata.output_frame.time_stamp);
6878 }
6879 break;
6880 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6881 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6882
6883 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6884 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6885 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6886 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6887 vdec_msg->msgdata.output_frame.pic_type);
6888
6889 if (omxhdr && omxhdr->pOutputPortPrivate &&
6890 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6891 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6892 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6893 {
6894 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6895 {
6896 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6897 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006898 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006899 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6900
6901 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6902 {
6903 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6904 //rc = -1;
6905 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006906 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6907 {
6908 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6909 }
Shalaj Jain286b0062013-02-21 20:35:48 -08006910 vdec_msg->msgdata.output_frame.bufferaddr =
6911 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6912 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6913 vdec_msg->msgdata.output_frame.framesize.left)
6914 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08006915 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6916 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6917 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6918 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6919 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6920 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6921 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
6922 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6923 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6924 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006925 output_respbuf = (struct vdec_output_frameinfo *)\
6926 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006927 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6928 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006929 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
6930 {
6931 output_respbuf->pic_type = PICTURE_TYPE_I;
6932 }
6933 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
6934 {
6935 output_respbuf->pic_type = PICTURE_TYPE_P;
6936 }
6937 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6938 output_respbuf->pic_type = PICTURE_TYPE_B;
6939 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006940
6941 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08006942 memcpy ( omxhdr->pBuffer, (void *)
6943 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6944 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6945 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006946 }
6947 else
6948 omxhdr->nFilledLen = 0;
6949 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6950 OMX_COMPONENT_GENERATE_FBD);
6951 }
6952 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08006953 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07006954 OMX_COMPONENT_GENERATE_EOS_DONE);
6955 else
Shalaj Jain286b0062013-02-21 20:35:48 -08006956 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07006957 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6958 break;
6959 case VDEC_MSG_EVT_CONFIG_CHANGED:
6960 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08006961 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6962 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006963 break;
6964 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
6965 {
6966 DEBUG_PRINT_HIGH("\n Port settings changed info");
6967 // get_buffer_req and populate port defn structure
6968 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07006969 struct v4l2_format fmt;
6970 int ret;
6971 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6972 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
Vinay Kalia592e4b42012-12-19 15:55:47 -08006973 omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006974 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
6975 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
Shalaj Jain273b3e02012-06-22 19:08:03 -07006976 omx->m_port_def.nPortIndex = 1;
6977 eRet = omx->update_portdef(&(omx->m_port_def));
Shalaj Jain286b0062013-02-21 20:35:48 -08006978 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Praneeth Paladuguea69de02012-10-30 11:40:17 -07006979 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006980 break;
6981 }
6982 default:
6983 break;
6984 }
6985 return rc;
6986}
6987
6988OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
6989 OMX_HANDLETYPE hComp,
6990 OMX_BUFFERHEADERTYPE *buffer
6991 )
6992{
6993 unsigned address,p2,id;
6994 DEBUG_PRINT_LOW("\n Empty this arbitrary");
6995
6996 if (buffer == NULL)
6997 {
6998 return OMX_ErrorBadParameter;
6999 }
7000 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007001 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7002 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007003
7004 /* return zero length and not an EOS buffer */
7005 /* return buffer if input flush in progress */
7006 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7007 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7008 {
7009 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7010 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7011 return OMX_ErrorNone;
7012 }
7013
7014 if (psource_frame == NULL)
7015 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007016 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007017 psource_frame = buffer;
7018 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7019 push_input_buffer (hComp);
7020 }
7021 else
7022 {
7023 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007024 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7025 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007026 {
7027 return OMX_ErrorBadParameter;
7028 }
7029 }
7030
7031
7032 return OMX_ErrorNone;
7033}
7034
7035OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7036{
7037 unsigned address,p2,id;
7038 OMX_ERRORTYPE ret = OMX_ErrorNone;
7039
7040 if (pdest_frame == NULL || psource_frame == NULL)
7041 {
7042 /*Check if we have a destination buffer*/
7043 if (pdest_frame == NULL)
7044 {
7045 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7046 if (m_input_free_q.m_size)
7047 {
7048 m_input_free_q.pop_entry(&address,&p2,&id);
7049 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7050 pdest_frame->nFilledLen = 0;
7051 pdest_frame->nTimeStamp = LLONG_MAX;
7052 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7053 }
7054 }
7055
7056 /*Check if we have a destination buffer*/
7057 if (psource_frame == NULL)
7058 {
7059 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7060 if (m_input_pending_q.m_size)
7061 {
7062 m_input_pending_q.pop_entry(&address,&p2,&id);
7063 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007064 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007065 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007066 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007067 psource_frame->nFlags,psource_frame->nFilledLen);
7068
7069 }
7070 }
7071
7072 }
7073
7074 while ((pdest_frame != NULL) && (psource_frame != NULL))
7075 {
7076 switch (codec_type_parse)
7077 {
7078 case CODEC_TYPE_MPEG4:
7079 case CODEC_TYPE_H263:
7080 case CODEC_TYPE_MPEG2:
7081 ret = push_input_sc_codec(hComp);
7082 break;
7083 case CODEC_TYPE_H264:
7084 ret = push_input_h264(hComp);
7085 break;
7086 case CODEC_TYPE_VC1:
7087 ret = push_input_vc1(hComp);
7088 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007089 default:
7090 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007091 }
7092 if (ret != OMX_ErrorNone)
7093 {
7094 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7095 omx_report_error ();
7096 break;
7097 }
7098 }
7099
7100 return ret;
7101}
7102
7103OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7104{
7105 OMX_U32 partial_frame = 1;
7106 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007107 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007108
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007109 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007110 psource_frame,psource_frame->nTimeStamp);
7111 if (m_frame_parser.parse_sc_frame(psource_frame,
7112 pdest_frame,&partial_frame) == -1)
7113 {
7114 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7115 return OMX_ErrorBadParameter;
7116 }
7117
7118 if (partial_frame == 0)
7119 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007120 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007121 pdest_frame->nFilledLen,psource_frame,frame_count);
7122
7123
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007124 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007125 /*First Parsed buffer will have only header Hence skip*/
7126 if (frame_count == 0)
7127 {
7128 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7129
7130 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7131 codec_type_parse == CODEC_TYPE_DIVX) {
7132 mp4StreamType psBits;
7133 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7134 psBits.numBytes = pdest_frame->nFilledLen;
7135 mp4_headerparser.parseHeader(&psBits);
7136 }
7137
7138 frame_count++;
7139 }
7140 else
7141 {
7142 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7143 if(pdest_frame->nFilledLen)
7144 {
7145 /*Push the frame to the Decoder*/
7146 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7147 {
7148 return OMX_ErrorBadParameter;
7149 }
7150 frame_count++;
7151 pdest_frame = NULL;
7152
7153 if (m_input_free_q.m_size)
7154 {
7155 m_input_free_q.pop_entry(&address,&p2,&id);
7156 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7157 pdest_frame->nFilledLen = 0;
7158 }
7159 }
7160 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7161 {
7162 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007163 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7164 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007165 pdest_frame = NULL;
7166 }
7167 }
7168 }
7169 else
7170 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007171 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007172 /*Check if Destination Buffer is full*/
7173 if (pdest_frame->nAllocLen ==
7174 pdest_frame->nFilledLen + pdest_frame->nOffset)
7175 {
7176 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7177 return OMX_ErrorStreamCorrupt;
7178 }
7179 }
7180
7181 if (psource_frame->nFilledLen == 0)
7182 {
7183 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7184 {
7185 if (pdest_frame)
7186 {
7187 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007188 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007189 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007190 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007191 pdest_frame->nFilledLen,frame_count++);
7192 /*Push the frame to the Decoder*/
7193 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7194 {
7195 return OMX_ErrorBadParameter;
7196 }
7197 frame_count++;
7198 pdest_frame = NULL;
7199 }
7200 else
7201 {
7202 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7203 generate_ebd = OMX_FALSE;
7204 }
7205 }
7206 if(generate_ebd)
7207 {
7208 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7209 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7210 psource_frame = NULL;
7211
7212 if (m_input_pending_q.m_size)
7213 {
7214 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7215 m_input_pending_q.pop_entry(&address,&p2,&id);
7216 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007217 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007218 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007219 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007220 psource_frame->nFlags,psource_frame->nFilledLen);
7221 }
7222 }
7223 }
7224 return OMX_ErrorNone;
7225}
7226
7227OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7228{
7229 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007230 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007231 OMX_BOOL isNewFrame = OMX_FALSE;
7232 OMX_BOOL generate_ebd = OMX_TRUE;
7233
7234 if (h264_scratch.pBuffer == NULL)
7235 {
7236 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7237 return OMX_ErrorBadParameter;
7238 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007239 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007240 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007241 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007242 if (h264_scratch.nFilledLen && look_ahead_nal)
7243 {
7244 look_ahead_nal = false;
7245 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7246 h264_scratch.nFilledLen)
7247 {
7248 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7249 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7250 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7251 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7252 h264_scratch.nFilledLen = 0;
7253 }
7254 else
7255 {
7256 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7257 return OMX_ErrorBadParameter;
7258 }
7259 }
7260 if (nal_length == 0)
7261 {
7262 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7263 if (m_frame_parser.parse_sc_frame(psource_frame,
7264 &h264_scratch,&partial_frame) == -1)
7265 {
7266 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7267 return OMX_ErrorBadParameter;
7268 }
7269 }
7270 else
7271 {
7272 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7273 if (m_frame_parser.parse_h264_nallength(psource_frame,
7274 &h264_scratch,&partial_frame) == -1)
7275 {
7276 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7277 return OMX_ErrorBadParameter;
7278 }
7279 }
7280
7281 if (partial_frame == 0)
7282 {
7283 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7284 {
7285 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7286 nal_count++;
7287 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7288 h264_scratch.nFlags = psource_frame->nFlags;
7289 }
7290 else
7291 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007292 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007293 if(h264_scratch.nFilledLen)
7294 {
7295 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7296 NALU_TYPE_SPS);
7297#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7298 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7299 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7300 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7301 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7302 // If timeinfo is present frame info from SEI is already processed
7303 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7304 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7305#endif
7306 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7307 nal_count++;
7308 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7309 pdest_frame->nTimeStamp = h264_last_au_ts;
7310 pdest_frame->nFlags = h264_last_au_flags;
7311#ifdef PANSCAN_HDLR
7312 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7313 h264_parser->update_panscan_data(h264_last_au_ts);
7314#endif
7315 }
7316 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7317 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7318 h264_last_au_ts = h264_scratch.nTimeStamp;
7319 h264_last_au_flags = h264_scratch.nFlags;
7320#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7321 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7322 {
7323 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7324 if (!VALID_TS(h264_last_au_ts))
7325 h264_last_au_ts = ts_in_sei;
7326 }
7327#endif
7328 } else
7329 h264_last_au_ts = LLONG_MAX;
7330 }
7331
7332 if (!isNewFrame)
7333 {
7334 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7335 h264_scratch.nFilledLen)
7336 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007337 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007338 h264_scratch.nFilledLen);
7339 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7340 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7341 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7342 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7343 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7344 h264_scratch.nFilledLen = 0;
7345 }
7346 else
7347 {
7348 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7349 return OMX_ErrorBadParameter;
7350 }
7351 }
7352 else
7353 {
7354 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007355 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007356 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007357 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007358 pdest_frame->nFilledLen,frame_count++);
7359
7360 if (pdest_frame->nFilledLen == 0)
7361 {
7362 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7363 look_ahead_nal = false;
7364 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7365 h264_scratch.nFilledLen)
7366 {
7367 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7368 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7369 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7370 h264_scratch.nFilledLen = 0;
7371 }
7372 else
7373 {
7374 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7375 return OMX_ErrorBadParameter;
7376 }
7377 }
7378 else
7379 {
7380 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7381 {
7382 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7383 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7384 }
7385 /*Push the frame to the Decoder*/
7386 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7387 {
7388 return OMX_ErrorBadParameter;
7389 }
7390 //frame_count++;
7391 pdest_frame = NULL;
7392 if (m_input_free_q.m_size)
7393 {
7394 m_input_free_q.pop_entry(&address,&p2,&id);
7395 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7396 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7397 pdest_frame->nFilledLen = 0;
7398 pdest_frame->nFlags = 0;
7399 pdest_frame->nTimeStamp = LLONG_MAX;
7400 }
7401 }
7402 }
7403 }
7404 }
7405 else
7406 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007407 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007408 /*Check if Destination Buffer is full*/
7409 if (h264_scratch.nAllocLen ==
7410 h264_scratch.nFilledLen + h264_scratch.nOffset)
7411 {
7412 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7413 return OMX_ErrorStreamCorrupt;
7414 }
7415 }
7416
7417 if (!psource_frame->nFilledLen)
7418 {
7419 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7420
7421 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7422 {
7423 if (pdest_frame)
7424 {
7425 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7426 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7427 h264_scratch.nFilledLen)
7428 {
7429 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7430 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7431 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7432 h264_scratch.nFilledLen = 0;
7433 }
7434 else
7435 {
7436 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7437 return OMX_ErrorBadParameter;
7438 }
7439 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7440 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7441
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007442 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007443 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7444 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7445#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7446 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7447 {
7448 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7449 if (!VALID_TS(pdest_frame->nTimeStamp))
7450 pdest_frame->nTimeStamp = ts_in_sei;
7451 }
7452#endif
7453 /*Push the frame to the Decoder*/
7454 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7455 {
7456 return OMX_ErrorBadParameter;
7457 }
7458 frame_count++;
7459 pdest_frame = NULL;
7460 }
7461 else
7462 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007463 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007464 pdest_frame,h264_scratch.nFilledLen);
7465 generate_ebd = OMX_FALSE;
7466 }
7467 }
7468 }
7469 if(generate_ebd && !psource_frame->nFilledLen)
7470 {
7471 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7472 psource_frame = NULL;
7473 if (m_input_pending_q.m_size)
7474 {
7475 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7476 m_input_pending_q.pop_entry(&address,&p2,&id);
7477 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007478 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007479 psource_frame->nFlags,psource_frame->nFilledLen);
7480 }
7481 }
7482 return OMX_ErrorNone;
7483}
7484
7485OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7486{
7487 OMX_U8 *buf, *pdest;
7488 OMX_U32 partial_frame = 1;
7489 OMX_U32 buf_len, dest_len;
7490
7491 if(first_frame == 0)
7492 {
7493 first_frame = 1;
7494 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7495 if(!m_vendor_config.pData)
7496 {
7497 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7498 buf = psource_frame->pBuffer;
7499 buf_len = psource_frame->nFilledLen;
7500
7501 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7502 VC1_SP_MP_START_CODE)
7503 {
7504 m_vc1_profile = VC1_SP_MP_RCV;
7505 }
7506 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7507 {
7508 m_vc1_profile = VC1_AP;
7509 }
7510 else
7511 {
7512 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7513 return OMX_ErrorStreamCorrupt;
7514 }
7515 }
7516 else
7517 {
7518 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7519 pdest_frame->nOffset;
7520 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7521 pdest_frame->nOffset);
7522
7523 if(dest_len < m_vendor_config.nDataSize)
7524 {
7525 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7526 return OMX_ErrorBadParameter;
7527 }
7528 else
7529 {
7530 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7531 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7532 }
7533 }
7534 }
7535
7536 switch(m_vc1_profile)
7537 {
7538 case VC1_AP:
7539 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7540 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7541 {
7542 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7543 return OMX_ErrorBadParameter;
7544 }
7545 break;
7546
7547 case VC1_SP_MP_RCV:
7548 default:
7549 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7550 return OMX_ErrorBadParameter;
7551 }
7552 return OMX_ErrorNone;
7553}
7554
David Ng38e2d232013-03-15 20:05:58 -07007555#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007556bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7557 OMX_U32 alignment)
7558{
7559 struct pmem_allocation allocation;
7560 allocation.size = buffer_size;
7561 allocation.align = clip2(alignment);
7562 if (allocation.align < 4096)
7563 {
7564 allocation.align = 4096;
7565 }
7566 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7567 {
7568 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7569 allocation.align, allocation.size);
7570 return false;
7571 }
7572 return true;
7573}
David Ng38e2d232013-03-15 20:05:58 -07007574#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007575#ifdef USE_ION
7576int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7577 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7578 struct ion_fd_data *fd_data, int flag)
7579{
7580 int fd = -EINVAL;
7581 int rc = -EINVAL;
7582 int ion_dev_flag;
7583 struct vdec_ion ion_buf_info;
7584 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7585 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7586 return -EINVAL;
7587 }
Arun Menon737de532012-09-14 14:48:18 -07007588 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007589 fd = open (MEM_DEVICE, ion_dev_flag);
7590 if (fd < 0) {
7591 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7592 return fd;
7593 }
Arun Menon737de532012-09-14 14:48:18 -07007594 alloc_data->flags = 0;
7595 if(!secure_mode && (flag & ION_FLAG_CACHED))
7596 {
7597 alloc_data->flags |= ION_FLAG_CACHED;
7598 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007599 alloc_data->len = buffer_size;
7600 alloc_data->align = clip2(alignment);
7601 if (alloc_data->align < 4096)
7602 {
7603 alloc_data->align = 4096;
7604 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007605 if ((secure_mode) && (flag & ION_SECURE))
7606 alloc_data->flags |= ION_SECURE;
7607
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007608 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7609 if (secure_mode)
7610 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007611 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7612 if (rc || !alloc_data->handle) {
7613 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7614 alloc_data->handle = NULL;
7615 close(fd);
7616 fd = -ENOMEM;
7617 return fd;
7618 }
7619 fd_data->handle = alloc_data->handle;
7620 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7621 if (rc) {
7622 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7623 ion_buf_info.ion_alloc_data = *alloc_data;
7624 ion_buf_info.ion_device_fd = fd;
7625 ion_buf_info.fd_ion_data = *fd_data;
7626 free_ion_memory(&ion_buf_info);
7627 fd_data->fd =-1;
7628 close(fd);
7629 fd = -ENOMEM;
7630 }
7631
7632 return fd;
7633}
7634
7635void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7636
7637 if(!buf_ion_info) {
7638 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7639 return;
7640 }
7641 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7642 &buf_ion_info->ion_alloc_data.handle)) {
7643 DEBUG_PRINT_ERROR("\n ION: free failed" );
7644 }
7645 close(buf_ion_info->ion_device_fd);
7646 buf_ion_info->ion_device_fd = -1;
7647 buf_ion_info->ion_alloc_data.handle = NULL;
7648 buf_ion_info->fd_ion_data.fd = -1;
7649}
7650#endif
7651void omx_vdec::free_output_buffer_header()
7652{
7653 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7654 output_use_buffer = false;
7655 ouput_egl_buffers = false;
7656
7657 if (m_out_mem_ptr)
7658 {
7659 free (m_out_mem_ptr);
7660 m_out_mem_ptr = NULL;
7661 }
7662
7663 if(m_platform_list)
7664 {
7665 free(m_platform_list);
7666 m_platform_list = NULL;
7667 }
7668
7669 if (drv_ctx.ptr_respbuffer)
7670 {
7671 free (drv_ctx.ptr_respbuffer);
7672 drv_ctx.ptr_respbuffer = NULL;
7673 }
7674 if (drv_ctx.ptr_outputbuffer)
7675 {
7676 free (drv_ctx.ptr_outputbuffer);
7677 drv_ctx.ptr_outputbuffer = NULL;
7678 }
7679#ifdef USE_ION
7680 if (drv_ctx.op_buf_ion_info) {
7681 DEBUG_PRINT_LOW("\n Free o/p ion context");
7682 free(drv_ctx.op_buf_ion_info);
7683 drv_ctx.op_buf_ion_info = NULL;
7684 }
7685#endif
7686}
7687
7688void omx_vdec::free_input_buffer_header()
7689{
7690 input_use_buffer = false;
7691 if (arbitrary_bytes)
7692 {
7693 if (m_frame_parser.mutils)
7694 {
7695 DEBUG_PRINT_LOW("\n Free utils parser");
7696 delete (m_frame_parser.mutils);
7697 m_frame_parser.mutils = NULL;
7698 }
7699
7700 if (m_inp_heap_ptr)
7701 {
7702 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7703 free (m_inp_heap_ptr);
7704 m_inp_heap_ptr = NULL;
7705 }
7706
7707 if (m_phdr_pmem_ptr)
7708 {
7709 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7710 free (m_phdr_pmem_ptr);
7711 m_phdr_pmem_ptr = NULL;
7712 }
7713 }
7714 if (m_inp_mem_ptr)
7715 {
7716 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7717 free (m_inp_mem_ptr);
7718 m_inp_mem_ptr = NULL;
7719 }
7720 if (drv_ctx.ptr_inputbuffer)
7721 {
7722 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7723 free (drv_ctx.ptr_inputbuffer);
7724 drv_ctx.ptr_inputbuffer = NULL;
7725 }
7726#ifdef USE_ION
7727 if (drv_ctx.ip_buf_ion_info) {
7728 DEBUG_PRINT_LOW("\n Free ion context");
7729 free(drv_ctx.ip_buf_ion_info);
7730 drv_ctx.ip_buf_ion_info = NULL;
7731 }
7732#endif
7733}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007734
7735int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007736{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007737 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007738 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007739 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007740
7741 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7742 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7743 v4l2_port = OUTPUT_PORT;
7744 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7745 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7746 v4l2_port = CAPTURE_PORT;
7747 } else if (port == OMX_ALL) {
7748 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7749 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7750
7751 if (!rc_input)
7752 return rc_input;
7753 else
7754 return rc_output;
7755 }
7756
7757 if (!streaming[v4l2_port]) {
7758 // already streamed off, warn and move on
7759 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7760 " which is already streamed off", v4l2_port);
7761 return 0;
7762 }
7763
7764 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7765
Shalaj Jain273b3e02012-06-22 19:08:03 -07007766 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7767 if (rc) {
7768 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007769 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007770 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007771 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007772 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007773
7774 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775}
7776
7777OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7778{
7779 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7780 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007781 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007782 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007783 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007784 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7785 buffer_prop->actualcount, buffer_prop->buffer_size);
7786 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007787 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007788 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7789 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7790 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7791 fmt.fmt.pix_mp.pixelformat = output_capability;
7792 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7793 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7794 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7795 fmt.fmt.pix_mp.pixelformat = capture_capability;
7796 }else {eRet = OMX_ErrorBadParameter;}
7797 if(eRet==OMX_ErrorNone){
7798 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7799 }
7800 if(ret)
7801 {
7802 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7803 /*TODO: How to handle this case */
7804 eRet = OMX_ErrorInsufficientResources;
7805 return eRet;
7806 }
7807 else
7808 {
7809 buffer_prop->actualcount = bufreq.count;
7810 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007811 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007812 }
7813 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7814 buffer_prop->actualcount, buffer_prop->buffer_size);
7815
7816 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7817 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7818
7819 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7820
Vinay Kalia592e4b42012-12-19 15:55:47 -08007821 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007822 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7823 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007824 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007825
7826 if(ret)
7827 {
7828 /*TODO: How to handle this case */
7829 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7830 eRet = OMX_ErrorInsufficientResources;
7831 }
7832 else
7833 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007834 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007835 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7836 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007837 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7838 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7839 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7840 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7841 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7842 return OMX_ErrorBadParameter;
7843 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007844 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7845 {
7846 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007847 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007848 }
7849 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7850 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007851 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007852 }
7853 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7854 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007855 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7856 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7857 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007858 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007859 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007860 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007861 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007862 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7863 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007864 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7865 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7866 drv_ctx.extradata_info.buffer_size = extra_data_size;
7867 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007868 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7869 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007870 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007871 if (in_reconfig) // BufReq will be set to driver when port is disabled
7872 buffer_prop->buffer_size = buf_size;
7873 else if (buf_size != buffer_prop->buffer_size)
7874 {
7875 buffer_prop->buffer_size = buf_size;
7876 eRet = set_buffer_req(buffer_prop);
7877 }
7878 }
7879 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7880 buffer_prop->actualcount, buffer_prop->buffer_size);
7881 return eRet;
7882}
7883
7884OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7885{
7886 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7887 unsigned buf_size = 0;
7888 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007889 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007890 int ret;
7891 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7892 buffer_prop->actualcount, buffer_prop->buffer_size);
7893 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7894 if (buf_size != buffer_prop->buffer_size)
7895 {
7896 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7897 buffer_prop->buffer_size, buf_size);
7898 eRet = OMX_ErrorBadParameter;
7899 }
7900 else
7901 {
7902 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7903 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007904
7905 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7906 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7907 fmt.fmt.pix_mp.pixelformat = output_capability;
7908 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7909 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7910 fmt.fmt.pix_mp.pixelformat = capture_capability;
7911 } else {eRet = OMX_ErrorBadParameter;}
7912
7913 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7914 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007915 {
7916 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007917 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007918 eRet = OMX_ErrorInsufficientResources;
7919 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007920
7921 bufreq.memory = V4L2_MEMORY_USERPTR;
7922 bufreq.count = buffer_prop->actualcount;
7923 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7924 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7925 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7926 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7927 } else {eRet = OMX_ErrorBadParameter;}
7928
7929 if (eRet==OMX_ErrorNone) {
7930 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7931 }
7932
7933 if (ret)
7934 {
7935 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7936 /*TODO: How to handle this case */
7937 eRet = OMX_ErrorInsufficientResources;
7938 } else if (bufreq.count < buffer_prop->actualcount) {
7939 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7940 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7941 buffer_prop->actualcount, bufreq.count);
7942 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007943 } else {
7944 if (!client_buffers.update_buffer_req()) {
7945 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7946 eRet = OMX_ErrorInsufficientResources;
7947 }
7948 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007949 }
7950 return eRet;
7951}
7952
Shalaj Jain273b3e02012-06-22 19:08:03 -07007953OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7954{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007955 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956 return eRet;
7957}
7958
7959OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7960{
7961 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7962 if (!portDefn)
7963 {
7964 return OMX_ErrorBadParameter;
7965 }
7966 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7967 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7968 portDefn->nSize = sizeof(portDefn);
7969 portDefn->eDomain = OMX_PortDomainVideo;
7970 if (drv_ctx.frame_rate.fps_denominator > 0)
7971 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7972 drv_ctx.frame_rate.fps_denominator;
7973 else {
7974 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7975 return OMX_ErrorBadParameter;
7976 }
7977 if (0 == portDefn->nPortIndex)
7978 {
7979 portDefn->eDir = OMX_DirInput;
7980 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7981 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7982 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7983 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7984 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7985 portDefn->bEnabled = m_inp_bEnabled;
7986 portDefn->bPopulated = m_inp_bPopulated;
7987 }
7988 else if (1 == portDefn->nPortIndex)
7989 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08007990 unsigned int buf_size = 0;
7991 if (!client_buffers.update_buffer_req()) {
7992 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7993 return OMX_ErrorHardware;
7994 }
7995 if (!client_buffers.get_buffer_req(buf_size)) {
7996 DEBUG_PRINT_ERROR("\n update buffer requirements");
7997 return OMX_ErrorHardware;
7998 }
7999 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008000 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008001 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8002 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008003 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8004 portDefn->bEnabled = m_out_bEnabled;
8005 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008006 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8007 DEBUG_PRINT_ERROR("\n Error in getting color format");
8008 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009 }
8010 }
8011 else
8012 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008013 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008014 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8015 (int)portDefn->nPortIndex);
8016 eRet = OMX_ErrorBadPortIndex;
8017 }
8018 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8019 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8020 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8021 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008022 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8023 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008024 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008025 portDefn->format.video.nStride,
8026 portDefn->format.video.nSliceHeight);
8027 return eRet;
8028
8029}
8030
8031OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8032{
8033 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8034 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8035 unsigned i= 0;
8036
8037 if(!m_out_mem_ptr) {
8038 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8039 int nBufHdrSize = 0;
8040 int nPlatformEntrySize = 0;
8041 int nPlatformListSize = 0;
8042 int nPMEMInfoSize = 0;
8043 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8044 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8045 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8046
8047 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8048 drv_ctx.op_buf.actualcount);
8049 nBufHdrSize = drv_ctx.op_buf.actualcount *
8050 sizeof(OMX_BUFFERHEADERTYPE);
8051
8052 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8053 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8054 nPlatformListSize = drv_ctx.op_buf.actualcount *
8055 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8056 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8057 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8058
8059 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8060 sizeof(OMX_BUFFERHEADERTYPE),
8061 nPMEMInfoSize,
8062 nPlatformListSize);
8063 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8064 m_out_bm_count);
8065 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8066 // Alloc mem for platform specific info
8067 char *pPtr=NULL;
8068 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8069 nPMEMInfoSize,1);
8070 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8071 calloc (sizeof(struct vdec_bufferpayload),
8072 drv_ctx.op_buf.actualcount);
8073 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8074 calloc (sizeof (struct vdec_output_frameinfo),
8075 drv_ctx.op_buf.actualcount);
8076#ifdef USE_ION
8077 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8078 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8079#endif
8080
8081 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8082 && drv_ctx.ptr_respbuffer)
8083 {
8084 bufHdr = m_out_mem_ptr;
8085 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8086 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8087 (((char *) m_platform_list) + nPlatformListSize);
8088 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8089 (((char *) m_platform_entry) + nPlatformEntrySize);
8090 pPlatformList = m_platform_list;
8091 pPlatformEntry = m_platform_entry;
8092 pPMEMInfo = m_pmem_info;
8093
8094 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8095
8096 // Settting the entire storage nicely
8097 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8098 m_out_mem_ptr,pPlatformEntry);
8099 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8100 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8101 {
8102 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8103 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8104 // Set the values when we determine the right HxW param
8105 bufHdr->nAllocLen = 0;
8106 bufHdr->nFilledLen = 0;
8107 bufHdr->pAppPrivate = NULL;
8108 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8109 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8110 pPlatformEntry->entry = pPMEMInfo;
8111 // Initialize the Platform List
8112 pPlatformList->nEntries = 1;
8113 pPlatformList->entryList = pPlatformEntry;
8114 // Keep pBuffer NULL till vdec is opened
8115 bufHdr->pBuffer = NULL;
8116 pPMEMInfo->offset = 0;
8117 pPMEMInfo->pmem_fd = 0;
8118 bufHdr->pPlatformPrivate = pPlatformList;
8119 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8120#ifdef USE_ION
8121 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8122#endif
8123 /*Create a mapping between buffers*/
8124 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8125 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8126 &drv_ctx.ptr_outputbuffer[i];
8127 // Move the buffer and buffer header pointers
8128 bufHdr++;
8129 pPMEMInfo++;
8130 pPlatformEntry++;
8131 pPlatformList++;
8132 }
8133 }
8134 else
8135 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008136 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008137 m_out_mem_ptr, pPtr);
8138 if(m_out_mem_ptr)
8139 {
8140 free(m_out_mem_ptr);
8141 m_out_mem_ptr = NULL;
8142 }
8143 if(pPtr)
8144 {
8145 free(pPtr);
8146 pPtr = NULL;
8147 }
8148 if(drv_ctx.ptr_outputbuffer)
8149 {
8150 free(drv_ctx.ptr_outputbuffer);
8151 drv_ctx.ptr_outputbuffer = NULL;
8152 }
8153 if(drv_ctx.ptr_respbuffer)
8154 {
8155 free(drv_ctx.ptr_respbuffer);
8156 drv_ctx.ptr_respbuffer = NULL;
8157 }
8158#ifdef USE_ION
8159 if (drv_ctx.op_buf_ion_info) {
8160 DEBUG_PRINT_LOW("\n Free o/p ion context");
8161 free(drv_ctx.op_buf_ion_info);
8162 drv_ctx.op_buf_ion_info = NULL;
8163 }
8164#endif
8165 eRet = OMX_ErrorInsufficientResources;
8166 }
8167 } else {
8168 eRet = OMX_ErrorInsufficientResources;
8169 }
8170 return eRet;
8171}
8172
8173void omx_vdec::complete_pending_buffer_done_cbs()
8174{
8175 unsigned p1;
8176 unsigned p2;
8177 unsigned ident;
8178 omx_cmd_queue tmp_q, pending_bd_q;
8179 pthread_mutex_lock(&m_lock);
8180 // pop all pending GENERATE FDB from ftb queue
8181 while (m_ftb_q.m_size)
8182 {
8183 m_ftb_q.pop_entry(&p1,&p2,&ident);
8184 if(ident == OMX_COMPONENT_GENERATE_FBD)
8185 {
8186 pending_bd_q.insert_entry(p1,p2,ident);
8187 }
8188 else
8189 {
8190 tmp_q.insert_entry(p1,p2,ident);
8191 }
8192 }
8193 //return all non GENERATE FDB to ftb queue
8194 while(tmp_q.m_size)
8195 {
8196 tmp_q.pop_entry(&p1,&p2,&ident);
8197 m_ftb_q.insert_entry(p1,p2,ident);
8198 }
8199 // pop all pending GENERATE EDB from etb queue
8200 while (m_etb_q.m_size)
8201 {
8202 m_etb_q.pop_entry(&p1,&p2,&ident);
8203 if(ident == OMX_COMPONENT_GENERATE_EBD)
8204 {
8205 pending_bd_q.insert_entry(p1,p2,ident);
8206 }
8207 else
8208 {
8209 tmp_q.insert_entry(p1,p2,ident);
8210 }
8211 }
8212 //return all non GENERATE FDB to etb queue
8213 while(tmp_q.m_size)
8214 {
8215 tmp_q.pop_entry(&p1,&p2,&ident);
8216 m_etb_q.insert_entry(p1,p2,ident);
8217 }
8218 pthread_mutex_unlock(&m_lock);
8219 // process all pending buffer dones
8220 while(pending_bd_q.m_size)
8221 {
8222 pending_bd_q.pop_entry(&p1,&p2,&ident);
8223 switch(ident)
8224 {
8225 case OMX_COMPONENT_GENERATE_EBD:
8226 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8227 {
8228 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8229 omx_report_error ();
8230 }
8231 break;
8232
8233 case OMX_COMPONENT_GENERATE_FBD:
8234 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8235 {
8236 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8237 omx_report_error ();
8238 }
8239 break;
8240 }
8241 }
8242}
8243
8244void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8245{
8246 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008247 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8248 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8249 {
8250 new_frame_interval = (act_timestamp > prev_ts)?
8251 act_timestamp - prev_ts :
8252 prev_ts - act_timestamp;
8253 if (new_frame_interval < frm_int || frm_int == 0)
8254 {
8255 frm_int = new_frame_interval;
8256 if(frm_int)
8257 {
8258 drv_ctx.frame_rate.fps_numerator = 1e6;
8259 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008260 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008261 frm_int, drv_ctx.frame_rate.fps_numerator /
8262 (float)drv_ctx.frame_rate.fps_denominator);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008263 }
8264 }
8265 }
8266 prev_ts = act_timestamp;
8267}
8268
8269void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8270{
8271 if (rst_prev_ts && VALID_TS(act_timestamp))
8272 {
8273 prev_ts = act_timestamp;
8274 rst_prev_ts = false;
8275 }
8276 else if (VALID_TS(prev_ts))
8277 {
8278 bool codec_cond = (drv_ctx.timestamp_adjust)?
8279 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8280 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8281 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8282 if(frm_int > 0 && codec_cond)
8283 {
8284 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8285 act_timestamp = prev_ts + frm_int;
8286 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8287 prev_ts = act_timestamp;
8288 }
8289 else
8290 set_frame_rate(act_timestamp);
8291 }
8292 else if (frm_int > 0) // In this case the frame rate was set along
8293 { // with the port definition, start ts with 0
8294 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8295 rst_prev_ts = true;
8296 }
8297}
8298
8299void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8300{
8301 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8302 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008303 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008304 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008305 OMX_U32 num_MB_in_frame;
8306 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008307 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008308 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008309 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8310 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008311 if (!drv_ctx.extradata_info.uaddr) {
8312 return;
8313 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008314 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008315 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8316 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8317 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008318 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008319 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008320 if (data) {
8321 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008322 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008323 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008324 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008325 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008326 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008327 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008328 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008329 struct msm_vidc_interlace_payload *payload;
8330 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008331 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8332 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008333 OMX_U32 mbaff = 0;
8334 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8335 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8336 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8337 else
8338 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8339 if(m_enable_android_native_buffers)
8340 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008341 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008342 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008343 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8344 append_interlace_extradata(p_extra, payload->format);
8345 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8346 }
8347 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008348 case EXTRADATA_FRAME_RATE:
8349 struct msm_vidc_framerate_payload *frame_rate_payload;
8350 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8351 frame_rate = frame_rate_payload->frame_rate;
8352 break;
8353 case EXTRADATA_TIMESTAMP:
8354 struct msm_vidc_ts_payload *time_stamp_payload;
8355 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008356 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008357 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008358 break;
8359 case EXTRADATA_NUM_CONCEALED_MB:
8360 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8361 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8362 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8363 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8364 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8365 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008366 case EXTRADATA_ASPECT_RATIO:
8367 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8368 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8369 ((struct vdec_output_frameinfo *)
8370 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8371 ((struct vdec_output_frameinfo *)
8372 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8373 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008374 case EXTRADATA_RECOVERY_POINT_SEI:
8375 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8376 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8377 recovery_sei_flags = recovery_sei_payload->flags;
8378 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8379 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008380 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008381 }
8382 break;
8383 case EXTRADATA_PANSCAN_WINDOW:
8384 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8385 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008386 default:
8387 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008388 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008389 consumed_len += data->nSize;
8390 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008391 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008392 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008393 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008394 append_frame_info_extradata(p_extra,
8395 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008396 panscan_payload,&((struct vdec_output_frameinfo *)
8397 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008398 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008399unrecognized_extradata:
8400 if(!secure_mode && client_extradata)
8401 append_terminator_extradata(p_extra);
8402 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008403}
8404
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008405OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8406 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008407{
8408 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008409 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008410 if(m_state != OMX_StateLoaded)
8411 {
8412 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8413 return OMX_ErrorIncorrectStateOperation;
8414 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008415 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008416 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008417
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008418 if (!is_internal) {
8419 if (enable)
8420 client_extradata |= requested_extradata;
8421 else
8422 client_extradata = client_extradata & ~requested_extradata;
8423 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008424
8425 if (enable) {
8426 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8427 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8428 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8429 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8430 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8431 " Quality of interlaced clips might be impacted.\n");
8432 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008433 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8434 {
8435 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8436 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8437 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8438 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8439 }
8440 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8441 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8442 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8443 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8444 }
8445 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8446 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8447 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8448 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8449 }
8450 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8451 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8452 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8453 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8454 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008455 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8456 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8457 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8458 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8459 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008460 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8461 {
8462 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8463 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8464 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8465 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8466 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008467 }
8468 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008469 return ret;
8470}
8471
8472OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8473{
8474 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8475 OMX_U8 *data_ptr = extra->data, data = 0;
8476 while (byte_count < extra->nDataSize)
8477 {
8478 data = *data_ptr;
8479 while (data)
8480 {
8481 num_MB += (data&0x01);
8482 data >>= 1;
8483 }
8484 data_ptr++;
8485 byte_count++;
8486 }
8487 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8488 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8489 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8490}
8491
8492void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8493{
8494 if (!m_debug_extradata)
8495 return;
8496
8497 DEBUG_PRINT_HIGH(
8498 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008499 " Size: %lu \n"
8500 " Version: %lu \n"
8501 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008502 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008503 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008504 extra->nSize, extra->nVersion.nVersion,
8505 extra->nPortIndex, extra->eType, extra->nDataSize);
8506
Shalaj Jain286b0062013-02-21 20:35:48 -08008507 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008508 {
8509 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8510 DEBUG_PRINT_HIGH(
8511 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008512 " Size: %lu \n"
8513 " Version: %lu \n"
8514 " PortIndex: %lu \n"
8515 " Is Interlace Format: %d \n"
8516 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008517 "=========== End of Interlace ===========\n",
8518 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8519 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8520 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008521 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008522 {
8523 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8524
8525 DEBUG_PRINT_HIGH(
8526 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008527 " Picture Type: %d \n"
8528 " Interlace Type: %d \n"
8529 " Pan Scan Total Frame Num: %lu \n"
8530 " Concealed Macro Blocks: %lu \n"
8531 " frame rate: %lu \n"
8532 " Aspect Ratio X: %lu \n"
8533 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008534 fminfo->ePicType,
8535 fminfo->interlaceType,
8536 fminfo->panScan.numWindows,
8537 fminfo->nConcealedMacroblocks,
8538 fminfo->nFrameRate,
8539 fminfo->aspectRatio.aspectRatioX,
8540 fminfo->aspectRatio.aspectRatioY);
8541
Praneeth Paladugu32284302013-02-14 22:53:06 -08008542 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008543 {
8544 DEBUG_PRINT_HIGH(
8545 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008546 " Pan Scan Frame Num: %lu \n"
8547 " Rectangle x: %ld \n"
8548 " Rectangle y: %ld \n"
8549 " Rectangle dx: %ld \n"
8550 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008551 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8552 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8553 }
8554
8555 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8556 }
8557 else if (extra->eType == OMX_ExtraDataNone)
8558 {
8559 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8560 }
8561 else
8562 {
8563 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8564 }
8565}
8566
8567void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8568 OMX_U32 interlaced_format_type)
8569{
8570 OMX_STREAMINTERLACEFORMAT *interlace_format;
8571 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008572 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8573 return;
8574 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008575 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8576 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8577 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8578 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8579 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8580 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8581 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8582 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8583 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8584 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008585 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586 {
8587 interlace_format->bInterlaceFormat = OMX_FALSE;
8588 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8589 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8590 }
8591 else
8592 {
8593 interlace_format->bInterlaceFormat = OMX_TRUE;
8594 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8595 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8596 }
8597 print_debug_extradata(extra);
8598}
8599
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008600void omx_vdec::fill_aspect_ratio_info(
8601 struct vdec_aspectratioinfo *aspect_ratio_info,
8602 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8603{
8604 m_extradata = frame_info;
8605 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8606 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008607 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008608 m_extradata->aspectRatio.aspectRatioY);
8609}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008610
8611void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008612 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008613 struct msm_vidc_panscan_window_payload *panscan_payload,
8614 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008615{
8616 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008617 struct msm_vidc_panscan_window *panscan_window;
8618 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8619 return;
8620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008621 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8622 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8623 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8624 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8625 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8626 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8627 switch (picture_type)
8628 {
8629 case PICTURE_TYPE_I:
8630 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8631 break;
8632 case PICTURE_TYPE_P:
8633 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8634 break;
8635 case PICTURE_TYPE_B:
8636 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8637 break;
8638 default:
8639 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8640 }
8641 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8642 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8643 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8644 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8645 else
8646 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008647 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008648 frame_info->nConcealedMacroblocks = num_conceal_mb;
8649 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008650 frame_info->panScan.numWindows = 0;
8651 if(panscan_payload) {
8652 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8653 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008654 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008655 {
8656 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8657 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8658 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8659 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8660 panscan_window++;
8661 }
8662 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008663 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008664 print_debug_extradata(extra);
8665}
8666
8667void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8668{
8669 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8670 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8671 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8672 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8673 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8674 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8675 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8676 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008677 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8678 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008679 portDefn->format.video.nFrameWidth,
8680 portDefn->format.video.nStride,
8681 portDefn->format.video.nSliceHeight);
8682}
8683
8684void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8685{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008686 if (!client_extradata) {
8687 return;
8688 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008689 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8690 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8691 extra->eType = OMX_ExtraDataNone;
8692 extra->nDataSize = 0;
8693 extra->data[0] = 0;
8694
8695 print_debug_extradata(extra);
8696}
8697
8698OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8699{
8700 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8701 if (index >= drv_ctx.ip_buf.actualcount)
8702 {
8703 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8704 return OMX_ErrorInsufficientResources;
8705 }
8706 if (m_desc_buffer_ptr == NULL)
8707 {
8708 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8709 calloc( (sizeof(desc_buffer_hdr)),
8710 drv_ctx.ip_buf.actualcount);
8711 if (m_desc_buffer_ptr == NULL)
8712 {
8713 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8714 return OMX_ErrorInsufficientResources;
8715 }
8716 }
8717
8718 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8719 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8720 {
8721 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8722 return OMX_ErrorInsufficientResources;
8723 }
8724
8725 return eRet;
8726}
8727
8728void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8729{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008730 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008731 if (m_demux_entries < 8192)
8732 {
8733 m_demux_offsets[m_demux_entries++] = address_offset;
8734 }
8735 return;
8736}
8737
8738void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8739{
8740 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8741 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8742 OMX_U32 index = 0;
8743
8744 m_demux_entries = 0;
8745
8746 while (index < bytes_to_parse)
8747 {
8748 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8749 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8750 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8751 (buf[index+2] == 0x01)) )
8752 {
8753 //Found start code, insert address offset
8754 insert_demux_addr_offset(index);
8755 if (buf[index+2] == 0x01) // 3 byte start code
8756 index += 3;
8757 else //4 byte start code
8758 index += 4;
8759 }
8760 else
8761 index++;
8762 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008763 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008764 return;
8765}
8766
8767OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8768{
8769 //fix this, handle 3 byte start code, vc1 terminator entry
8770 OMX_U8 *p_demux_data = NULL;
8771 OMX_U32 desc_data = 0;
8772 OMX_U32 start_addr = 0;
8773 OMX_U32 nal_size = 0;
8774 OMX_U32 suffix_byte = 0;
8775 OMX_U32 demux_index = 0;
8776 OMX_U32 buffer_index = 0;
8777
8778 if (m_desc_buffer_ptr == NULL)
8779 {
8780 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8781 return OMX_ErrorBadParameter;
8782 }
8783
8784 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8785 if (buffer_index > drv_ctx.ip_buf.actualcount)
8786 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008787 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008788 return OMX_ErrorBadParameter;
8789 }
8790
8791 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8792
8793 if ( ((OMX_U8*)p_demux_data == NULL) ||
8794 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8795 {
8796 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8797 return OMX_ErrorBadParameter;
8798 }
8799 else
8800 {
8801 for (; demux_index < m_demux_entries; demux_index++)
8802 {
8803 desc_data = 0;
8804 start_addr = m_demux_offsets[demux_index];
8805 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8806 {
8807 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8808 }
8809 else
8810 {
8811 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8812 }
8813 if (demux_index < (m_demux_entries - 1))
8814 {
8815 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8816 }
8817 else
8818 {
8819 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8820 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008821 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8822 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008823 suffix_byte,
8824 nal_size,
8825 demux_index);
8826 desc_data = (start_addr >> 3) << 1;
8827 desc_data |= (start_addr & 7) << 21;
8828 desc_data |= suffix_byte << 24;
8829
8830 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8831 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8832 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8833 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8834
8835 p_demux_data += 16;
8836 }
8837 if (codec_type_parse == CODEC_TYPE_VC1)
8838 {
8839 DEBUG_PRINT_LOW("VC1 terminator entry");
8840 desc_data = 0;
8841 desc_data = 0x82 << 24;
8842 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8843 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8844 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8845 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8846 p_demux_data += 16;
8847 m_demux_entries++;
8848 }
8849 //Add zero word to indicate end of descriptors
8850 memset(p_demux_data, 0, sizeof(OMX_U32));
8851
8852 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008853 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008854 }
8855 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8856 m_demux_entries = 0;
8857 DEBUG_PRINT_LOW("Demux table complete!");
8858 return OMX_ErrorNone;
8859}
8860
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008861OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008862{
8863 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008864 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008865 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008866 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8867 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008868 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008869 delete iDivXDrmDecrypt;
8870 iDivXDrmDecrypt = NULL;
8871 }
8872 }
8873 else {
8874 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008875 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008876 }
8877 return err;
8878}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008879
Vinay Kaliada4f4422013-01-09 10:45:03 -08008880omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8881{
8882 enabled = false;
8883 omx = NULL;
8884 init_members();
8885 ColorFormat = OMX_COLOR_FormatMax;
8886}
8887
8888void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8889{
8890 omx = reinterpret_cast<omx_vdec*>(client);
8891}
8892
8893void omx_vdec::allocate_color_convert_buf::init_members() {
8894 allocated_count = 0;
8895 buffer_size_req = 0;
8896 buffer_alignment_req = 0;
8897 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8898 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8899 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8900 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
8901#ifdef USE_ION
8902 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
8903#endif
8904 for (int i = 0; i < MAX_COUNT;i++)
8905 pmem_fd[i] = -1;
8906}
8907
8908omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
8909 c2d.destroy();
8910}
8911
8912bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8913{
8914 bool status = true;
8915 unsigned int src_size = 0, destination_size = 0;
8916 OMX_COLOR_FORMATTYPE drv_color_format;
8917 if (!omx){
8918 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8919 return false;
8920 }
8921 if (!enabled){
8922 DEBUG_PRINT_ERROR("\n No color conversion required");
8923 return status;
8924 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008925 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008926 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8927 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8928 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008929 status = false;
8930 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008931 }
8932 c2d.close();
8933 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8934 omx->drv_ctx.video_resolution.frame_width,
8935 NV12_128m,YCbCr420P);
8936 if (status) {
8937 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8938 if (status)
8939 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8940 }
8941 if (status) {
8942 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8943 !destination_size) {
8944 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8945 "driver size %d destination size %d",
8946 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8947 status = false;
8948 c2d.close();
8949 buffer_size_req = 0;
8950 } else {
8951 buffer_size_req = destination_size;
8952 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8953 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8954 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8955 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8956 }
8957 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008958fail_update_buf_req:
8959 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008960 return status;
8961}
8962
8963bool omx_vdec::allocate_color_convert_buf::set_color_format(
8964 OMX_COLOR_FORMATTYPE dest_color_format)
8965{
8966 bool status = true;
8967 OMX_COLOR_FORMATTYPE drv_color_format;
8968 if (!omx){
8969 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8970 return false;
8971 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008972 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008973 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8974 drv_color_format = (OMX_COLOR_FORMATTYPE)
8975 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8976 else {
8977 DEBUG_PRINT_ERROR("\n Incorrect color format");
8978 status = false;
8979 }
8980 if (status && (drv_color_format != dest_color_format)) {
8981 DEBUG_PRINT_LOW("Enabling C2D\n");
8982 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8983 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8984 status = false;
8985 } else {
8986 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8987 if (enabled)
8988 c2d.destroy();
8989 enabled = false;
8990 if (!c2d.init()) {
8991 DEBUG_PRINT_ERROR("\n open failed for c2d");
8992 status = false;
8993 } else
8994 enabled = true;
8995 }
8996 } else {
8997 if (enabled)
8998 c2d.destroy();
8999 enabled = false;
9000 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009001 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009002 return status;
9003}
9004
9005OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9006{
9007 if (!omx){
9008 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9009 return NULL;
9010 }
9011 if (!enabled)
9012 return omx->m_out_mem_ptr;
9013 return m_out_mem_ptr_client;
9014}
9015
9016OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9017 (OMX_BUFFERHEADERTYPE *bufadd)
9018{
9019 if (!omx){
9020 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9021 return NULL;
9022 }
9023 if (!enabled)
9024 return bufadd;
9025
9026 unsigned index = 0;
9027 index = bufadd - omx->m_out_mem_ptr;
9028 if (index < omx->drv_ctx.op_buf.actualcount) {
9029 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9030 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9031 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009032 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009033 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009034 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9035 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009036 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009037 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9038 if (!status){
9039 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009040 m_out_mem_ptr_client[index].nFilledLen = 0;
9041 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009042 }
9043 } else
9044 m_out_mem_ptr_client[index].nFilledLen = 0;
9045 return &m_out_mem_ptr_client[index];
9046 }
9047 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9048 return NULL;
9049}
9050
9051OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9052 (OMX_BUFFERHEADERTYPE *bufadd)
9053{
9054 if (!omx){
9055 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9056 return NULL;
9057 }
9058 if (!enabled)
9059 return bufadd;
9060 unsigned index = 0;
9061 index = bufadd - m_out_mem_ptr_client;
9062 if (index < omx->drv_ctx.op_buf.actualcount) {
9063 return &omx->m_out_mem_ptr[index];
9064 }
9065 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9066 return NULL;
9067}
9068bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9069 (unsigned int &buffer_size)
9070{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009071 bool status = true;
9072 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009073 if (!enabled)
9074 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009075 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009076 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9077 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009078 status = false;
9079 goto fail_get_buffer_size;
9080 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009081 }
9082 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9083 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9084 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9085 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009086fail_get_buffer_size:
9087 pthread_mutex_unlock(&omx->c_lock);
9088 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009089}
9090OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9091 OMX_BUFFERHEADERTYPE *bufhdr) {
9092 unsigned int index = 0;
9093
9094 if (!enabled)
9095 return omx->free_output_buffer(bufhdr);
9096 if (enabled && omx->is_component_secure())
9097 return OMX_ErrorNone;
9098 if (!allocated_count || !bufhdr) {
9099 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9100 return OMX_ErrorBadParameter;
9101 }
9102 index = bufhdr - m_out_mem_ptr_client;
9103 if (index >= omx->drv_ctx.op_buf.actualcount){
9104 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9105 return OMX_ErrorBadParameter;
9106 }
9107 if (pmem_fd[index] > 0) {
9108 munmap(pmem_baseaddress[index], buffer_size_req);
9109 close(pmem_fd[index]);
9110 }
9111 pmem_fd[index] = -1;
9112#ifdef USE_ION
9113 omx->free_ion_memory(&op_buf_ion_info[index]);
9114#endif
9115 m_heap_ptr[index].video_heap_ptr = NULL;
9116 if (allocated_count > 0)
9117 allocated_count--;
9118 else
9119 allocated_count = 0;
9120 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009121 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009122 c2d.close();
9123 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009124 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009125 }
9126 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9127}
9128
9129OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9130 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9131{
9132 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9133 if (!enabled){
9134 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9135 return eRet;
9136 }
9137 if (enabled && omx->is_component_secure()) {
9138 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9139 omx->is_component_secure());
9140 return OMX_ErrorUnsupportedSetting;
9141 }
9142 if (!bufferHdr || bytes > buffer_size_req) {
9143 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009144 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009145 buffer_size_req,bytes);
9146 return OMX_ErrorBadParameter;
9147 }
9148 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9149 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9150 return OMX_ErrorInsufficientResources;
9151 }
9152 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9153 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9154 port,appData,omx->drv_ctx.op_buf.buffer_size);
9155 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9156 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9157 return eRet;
9158 }
9159 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9160 omx->drv_ctx.op_buf.actualcount) {
9161 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9162 (temp_bufferHdr - omx->m_out_mem_ptr));
9163 return OMX_ErrorUndefined;
9164 }
9165 unsigned int i = allocated_count;
9166#ifdef USE_ION
9167 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9168 buffer_size_req,buffer_alignment_req,
9169 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009170 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009171 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9172 if (op_buf_ion_info[i].ion_device_fd < 0) {
9173 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9174 return OMX_ErrorInsufficientResources;
9175 }
9176 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9177 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9178
9179 if (pmem_baseaddress[i] == MAP_FAILED) {
9180 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9181 close(pmem_fd[i]);
9182 omx->free_ion_memory(&op_buf_ion_info[i]);
9183 return OMX_ErrorInsufficientResources;
9184 }
9185 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9186 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9187 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9188#endif
9189 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9190 m_pmem_info_client[i].offset = 0;
9191 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9192 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9193 m_platform_list_client[i].nEntries = 1;
9194 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9195 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9196 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9197 m_out_mem_ptr_client[i].nFilledLen = 0;
9198 m_out_mem_ptr_client[i].nFlags = 0;
9199 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9200 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9201 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9202 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9203 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9204 m_out_mem_ptr_client[i].pAppPrivate = appData;
9205 *bufferHdr = &m_out_mem_ptr_client[i];
9206 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9207 allocated_count++;
9208 return eRet;
9209}
9210
9211bool omx_vdec::is_component_secure()
9212{
9213 return secure_mode;
9214}
9215
9216bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9217{
9218 bool status = true;
9219 if (!enabled) {
9220 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9221 dest_color_format = (OMX_COLOR_FORMATTYPE)
9222 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9223 else
9224 status = false;
9225 } else {
9226 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9227 status = false;
9228 } else
9229 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9230 }
9231 return status;
9232}