blob: 3ddcf96149088bd90941517cb0234d6aec21f1c9 [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
Shalaj Jain273b3e02012-06-22 19:08:03 -070082#ifdef INPUT_BUFFER_LOG
83#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
84#define INPUT_BUFFER_FILE_NAME_LEN 30
85FILE *inputBufferFile1;
86char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
87#endif
88#ifdef OUTPUT_BUFFER_LOG
89FILE *outputBufferFile1;
90char outputfilename [] = "/data/output.yuv";
Vinay Kalia21649b32013-03-18 17:28:07 -070091
Shalaj Jain273b3e02012-06-22 19:08:03 -070092#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),
Praneeth Paladugu53478562013-03-12 14:49:46 -0700563 secure_mode(false),
564 opt_handle(NULL),
565 perf_lock_acq(NULL),
566 perf_lock_rel(NULL),
567 perf_lock_handle(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700568{
569 /* Assumption is that , to begin with , we have all the frames with decoder */
570 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
571#ifdef _ANDROID_
572 char property_value[PROPERTY_VALUE_MAX] = {0};
573 property_get("vidc.dec.debug.perf", property_value, "0");
574 perf_flag = atoi(property_value);
575 if (perf_flag)
576 {
577 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
578 dec_time.start();
579 proc_frms = latency = 0;
580 }
Shalaj Jain286b0062013-02-21 20:35:48 -0800581 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700582 property_get("vidc.dec.debug.ts", property_value, "0");
583 m_debug_timestamp = atoi(property_value);
584 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
585 if (m_debug_timestamp)
586 {
587 time_stamp_dts.set_timestamp_reorder_mode(true);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800588 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700589 }
590
Shalaj Jain286b0062013-02-21 20:35:48 -0800591 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700592 property_get("vidc.dec.debug.concealedmb", property_value, "0");
593 m_debug_concealedmb = atoi(property_value);
594 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
595
596#endif
597 memset(&m_cmp,0,sizeof(m_cmp));
598 memset(&m_cb,0,sizeof(m_cb));
599 memset (&drv_ctx,0,sizeof(drv_ctx));
600 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
601 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700602 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
603 m_demux_entries = 0;
604#ifdef _ANDROID_ICS_
605 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
606#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700607 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700608 drv_ctx.timestamp_adjust = false;
609 drv_ctx.video_driver_fd = -1;
610 m_vendor_config.pData = NULL;
611 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800612 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700613 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800614 streaming[CAPTURE_PORT] =
615 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700616#ifdef _ANDROID_
617 char extradata_value[PROPERTY_VALUE_MAX] = {0};
618 property_get("vidc.dec.debug.extradata", extradata_value, "0");
619 m_debug_extradata = atoi(extradata_value);
620 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
621#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800622 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
623 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700624}
625
Vinay Kalia85793762012-06-14 19:12:34 -0700626static const int event_type[] = {
627 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
628 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
629 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700630 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
631 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700632};
633
634static OMX_ERRORTYPE subscribe_to_events(int fd)
635{
636 OMX_ERRORTYPE eRet = OMX_ErrorNone;
637 struct v4l2_event_subscription sub;
638 int array_sz = sizeof(event_type)/sizeof(int);
639 int i,rc;
640 if (fd < 0) {
641 printf("Invalid input: %d\n", fd);
642 return OMX_ErrorBadParameter;
643 }
644
645 for (i = 0; i < array_sz; ++i) {
646 memset(&sub, 0, sizeof(sub));
647 sub.type = event_type[i];
648 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
649 if (rc) {
650 printf("Failed to subscribe event: 0x%x\n", sub.type);
651 break;
652 }
653 }
654 if (i < array_sz) {
655 for (--i; i >=0 ; i--) {
656 memset(&sub, 0, sizeof(sub));
657 sub.type = event_type[i];
658 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
659 if (rc)
660 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
661 }
662 eRet = OMX_ErrorNotImplemented;
663 }
664 return eRet;
665}
666
667
668static OMX_ERRORTYPE unsubscribe_to_events(int fd)
669{
670 OMX_ERRORTYPE eRet = OMX_ErrorNone;
671 struct v4l2_event_subscription sub;
672 int array_sz = sizeof(event_type)/sizeof(int);
673 int i,rc;
674 if (fd < 0) {
675 printf("Invalid input: %d\n", fd);
676 return OMX_ErrorBadParameter;
677 }
678
679 for (i = 0; i < array_sz; ++i) {
680 memset(&sub, 0, sizeof(sub));
681 sub.type = event_type[i];
682 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
683 if (rc) {
684 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
685 break;
686 }
687 }
688 return eRet;
689}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700690
691/* ======================================================================
692FUNCTION
693 omx_vdec::~omx_vdec
694
695DESCRIPTION
696 Destructor
697
698PARAMETERS
699 None
700
701RETURN VALUE
702 None.
703========================================================================== */
704omx_vdec::~omx_vdec()
705{
706 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700707 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700708 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
709 if(m_pipe_in) close(m_pipe_in);
710 if(m_pipe_out) close(m_pipe_out);
711 m_pipe_in = -1;
712 m_pipe_out = -1;
713 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
714 pthread_join(msg_thread_id,NULL);
715 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700716 dec.cmd = V4L2_DEC_CMD_STOP;
717 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
718 {
719 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
720 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700721 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700722 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700723 close(drv_ctx.video_driver_fd);
724 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800725 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700726 sem_destroy(&m_cmd_lock);
Praneeth Paladugu53478562013-03-12 14:49:46 -0700727 if (perf_lock_handle >= 0 && perf_lock_rel) {
728 DEBUG_PRINT_LOW("Lock released");
729 perf_lock_rel(perf_lock_handle);
730 perf_lock_handle = -1;
731 }
732 if (opt_handle) {
733 dlclose(opt_handle);
734 opt_handle = NULL;
735 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700736 if (perf_flag)
737 {
738 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
739 dec_time.end();
740 }
741 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
742}
743
Vinay Kaliafeef7032012-09-25 19:23:33 -0700744int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
745 struct v4l2_requestbuffers bufreq;
746 int rc = 0;
747 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
748 bufreq.memory = V4L2_MEMORY_USERPTR;
749 bufreq.count = 0;
750 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
751 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
752 }
753 return rc;
754}
755
Shalaj Jain273b3e02012-06-22 19:08:03 -0700756/* ======================================================================
757FUNCTION
758 omx_vdec::OMXCntrlProcessMsgCb
759
760DESCRIPTION
761 IL Client callbacks are generated through this routine. The decoder
762 provides the thread context for this routine.
763
764PARAMETERS
765 ctxt -- Context information related to the self.
766 id -- Event identifier. This could be any of the following:
767 1. Command completion event
768 2. Buffer done callback event
769 3. Frame done callback event
770
771RETURN VALUE
772 None.
773
774========================================================================== */
775void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
776{
Shalaj Jain286b0062013-02-21 20:35:48 -0800777 signed p1; // Parameter - 1
778 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700779 unsigned ident;
780 unsigned qsize=0; // qsize
781 omx_vdec *pThis = (omx_vdec *) ctxt;
782
783 if(!pThis)
784 {
785 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
786 __func__);
787 return;
788 }
789
790 // Protect the shared queue data structure
791 do
792 {
793 /*Read the message id's from the queue*/
794 pthread_mutex_lock(&pThis->m_lock);
795 qsize = pThis->m_cmd_q.m_size;
796 if(qsize)
797 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800798 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799 }
800
801 if (qsize == 0 && pThis->m_state != OMX_StatePause)
802 {
803 qsize = pThis->m_ftb_q.m_size;
804 if (qsize)
805 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800806 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700807 }
808 }
809
810 if (qsize == 0 && pThis->m_state != OMX_StatePause)
811 {
812 qsize = pThis->m_etb_q.m_size;
813 if (qsize)
814 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800815 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816 }
817 }
818 pthread_mutex_unlock(&pThis->m_lock);
819
820 /*process message if we have one*/
821 if(qsize > 0)
822 {
823 id = ident;
824 switch (id)
825 {
826 case OMX_COMPONENT_GENERATE_EVENT:
827 if (pThis->m_cb.EventHandler)
828 {
829 switch (p1)
830 {
831 case OMX_CommandStateSet:
832 pThis->m_state = (OMX_STATETYPE) p2;
833 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
834 pThis->m_state);
835 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
836 OMX_EventCmdComplete, p1, p2, NULL);
837 break;
838
839 case OMX_EventError:
840 if(p2 == OMX_StateInvalid)
841 {
842 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
843 pThis->m_state = (OMX_STATETYPE) p2;
844 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
845 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
846 }
847 else if (p2 == OMX_ErrorHardware)
848 {
849 pThis->omx_report_error();
850 }
851 else
852 {
853 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800854 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700855 }
856 break;
857
858 case OMX_CommandPortDisable:
859 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
860 if (BITMASK_PRESENT(&pThis->m_flags,
861 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
862 {
863 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
864 break;
865 }
866 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
867 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700868 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700869 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700870 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
871 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
872 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700873 pThis->in_reconfig = false;
874 if(eRet != OMX_ErrorNone)
875 {
876 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
877 pThis->omx_report_error();
878 break;
879 }
880 }
881 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
882 OMX_EventCmdComplete, p1, p2, NULL );
883 break;
884 case OMX_CommandPortEnable:
885 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
886 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
887 OMX_EventCmdComplete, p1, p2, NULL );
888 break;
889
890 default:
891 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
892 OMX_EventCmdComplete, p1, p2, NULL );
893 break;
894
895 }
896 }
897 else
898 {
899 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
900 }
901 break;
902 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
903 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
904 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
905 {
906 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
907 pThis->omx_report_error ();
908 }
909 break;
910 case OMX_COMPONENT_GENERATE_ETB:
911 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
912 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
913 {
914 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
915 pThis->omx_report_error ();
916 }
917 break;
918
919 case OMX_COMPONENT_GENERATE_FTB:
920 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
921 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
922 {
923 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
924 pThis->omx_report_error ();
925 }
926 break;
927
928 case OMX_COMPONENT_GENERATE_COMMAND:
929 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
930 (OMX_U32)p2,(OMX_PTR)NULL);
931 break;
932
933 case OMX_COMPONENT_GENERATE_EBD:
934
935 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
936 {
937 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
938 pThis->omx_report_error ();
939 }
940 else
941 {
942 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
943 {
944 pThis->m_inp_err_count++;
945 pThis->time_stamp_dts.remove_time_stamp(
946 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
947 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
948 ?true:false);
949 }
950 else
951 {
952 pThis->m_inp_err_count = 0;
953 }
954 if ( pThis->empty_buffer_done(&pThis->m_cmp,
955 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
956 {
957 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
958 pThis->omx_report_error ();
959 }
960 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
961 {
962 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
963 pThis->omx_report_error ();
964 }
965 }
966 break;
967 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
968 {
969 int64_t *timestamp = (int64_t *)p1;
970 if (p1)
971 {
972 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
973 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
974 ?true:false);
975 free(timestamp);
976 }
977 }
978 break;
979 case OMX_COMPONENT_GENERATE_FBD:
980 if (p2 != VDEC_S_SUCCESS)
981 {
982 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
983 pThis->omx_report_error ();
984 }
985 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
986 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
987 {
988 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
989 pThis->omx_report_error ();
990 }
991 break;
992
993 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
994 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
995 if (!pThis->input_flush_progress)
996 {
997 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
998 }
999 else
1000 {
1001 pThis->execute_input_flush();
1002 if (pThis->m_cb.EventHandler)
1003 {
1004 if (p2 != VDEC_S_SUCCESS)
1005 {
1006 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
1007 pThis->omx_report_error ();
1008 }
1009 else
1010 {
1011 /*Check if we need generate event for Flush done*/
1012 if(BITMASK_PRESENT(&pThis->m_flags,
1013 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1014 {
1015 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1016 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1017 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1018 OMX_EventCmdComplete,OMX_CommandFlush,
1019 OMX_CORE_INPUT_PORT_INDEX,NULL );
1020 }
1021 if (BITMASK_PRESENT(&pThis->m_flags,
1022 OMX_COMPONENT_IDLE_PENDING))
1023 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001024 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001025 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1026 pThis->omx_report_error ();
1027 } else {
1028 pThis->streaming[OUTPUT_PORT] = false;
1029 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001030 if (!pThis->output_flush_progress)
1031 {
Vinay Kalia22046272012-09-28 20:16:05 -07001032 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001033 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001034 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001035 }
1036 }
1037 }
1038 }
1039 else
1040 {
1041 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1042 }
1043 }
1044 break;
1045
1046 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1047 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1048 if (!pThis->output_flush_progress)
1049 {
1050 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1051 }
1052 else
1053 {
1054 pThis->execute_output_flush();
1055 if (pThis->m_cb.EventHandler)
1056 {
1057 if (p2 != VDEC_S_SUCCESS)
1058 {
1059 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1060 pThis->omx_report_error ();
1061 }
1062 else
1063 {
1064 /*Check if we need generate event for Flush done*/
1065 if(BITMASK_PRESENT(&pThis->m_flags,
1066 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1067 {
1068 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1069 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1070 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1071 OMX_EventCmdComplete,OMX_CommandFlush,
1072 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1073 }
1074 if(BITMASK_PRESENT(&pThis->m_flags,
1075 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1076 {
1077 DEBUG_PRINT_LOW("\n Internal flush complete");
1078 BITMASK_CLEAR (&pThis->m_flags,
1079 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1080 if (BITMASK_PRESENT(&pThis->m_flags,
1081 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1082 {
1083 pThis->post_event(OMX_CommandPortDisable,
1084 OMX_CORE_OUTPUT_PORT_INDEX,
1085 OMX_COMPONENT_GENERATE_EVENT);
1086 BITMASK_CLEAR (&pThis->m_flags,
1087 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1088
1089 }
1090 }
1091
1092 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1093 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001094 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001095 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1096 pThis->omx_report_error ();
1097 break;
1098 }
1099 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001100 if (!pThis->input_flush_progress)
1101 {
Vinay Kalia22046272012-09-28 20:16:05 -07001102 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001103 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001104 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001105 }
1106 }
1107 }
1108 }
1109 else
1110 {
1111 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1112 }
1113 }
1114 break;
1115
1116 case OMX_COMPONENT_GENERATE_START_DONE:
1117 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1118
1119 if (pThis->m_cb.EventHandler)
1120 {
1121 if (p2 != VDEC_S_SUCCESS)
1122 {
1123 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1124 pThis->omx_report_error ();
1125 }
1126 else
1127 {
1128 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1129 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1130 {
1131 DEBUG_PRINT_LOW("\n Move to executing");
1132 // Send the callback now
1133 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1134 pThis->m_state = OMX_StateExecuting;
1135 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1136 OMX_EventCmdComplete,OMX_CommandStateSet,
1137 OMX_StateExecuting, NULL);
1138 }
1139 else if (BITMASK_PRESENT(&pThis->m_flags,
1140 OMX_COMPONENT_PAUSE_PENDING))
1141 {
1142 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1143 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1144 {
1145 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1146 pThis->omx_report_error ();
1147 }
1148 }
1149 }
1150 }
1151 else
1152 {
1153 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1154 }
1155 break;
1156
1157 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1158 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1159 if (pThis->m_cb.EventHandler)
1160 {
1161 if (p2 != VDEC_S_SUCCESS)
1162 {
1163 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1164 pThis->omx_report_error ();
1165 }
1166 else
1167 {
1168 pThis->complete_pending_buffer_done_cbs();
1169 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1170 {
1171 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1172 //Send the callback now
1173 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1174 pThis->m_state = OMX_StatePause;
1175 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1176 OMX_EventCmdComplete,OMX_CommandStateSet,
1177 OMX_StatePause, NULL);
1178 }
1179 }
1180 }
1181 else
1182 {
1183 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1184 }
1185
1186 break;
1187
1188 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1189 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1190 if (pThis->m_cb.EventHandler)
1191 {
1192 if (p2 != VDEC_S_SUCCESS)
1193 {
1194 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1195 pThis->omx_report_error ();
1196 }
1197 else
1198 {
1199 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1200 {
1201 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1202 // Send the callback now
1203 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1204 pThis->m_state = OMX_StateExecuting;
1205 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1206 OMX_EventCmdComplete,OMX_CommandStateSet,
1207 OMX_StateExecuting,NULL);
1208 }
1209 }
1210 }
1211 else
1212 {
1213 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1214 }
1215
1216 break;
1217
1218 case OMX_COMPONENT_GENERATE_STOP_DONE:
1219 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1220 if (pThis->m_cb.EventHandler)
1221 {
1222 if (p2 != VDEC_S_SUCCESS)
1223 {
1224 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1225 pThis->omx_report_error ();
1226 }
1227 else
1228 {
1229 pThis->complete_pending_buffer_done_cbs();
1230 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1231 {
1232 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1233 // Send the callback now
1234 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1235 pThis->m_state = OMX_StateIdle;
1236 DEBUG_PRINT_LOW("\n Move to Idle State");
1237 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1238 OMX_EventCmdComplete,OMX_CommandStateSet,
1239 OMX_StateIdle,NULL);
1240 }
1241 }
1242 }
1243 else
1244 {
1245 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1246 }
1247
1248 break;
1249
1250 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1251 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001252
Vinay Kalia592e4b42012-12-19 15:55:47 -08001253 if (p2 == OMX_IndexParamPortDefinition) {
1254 pThis->in_reconfig = true;
1255 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001256 if (pThis->m_cb.EventHandler) {
1257 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001258 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001259 } else {
1260 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1261 }
1262
1263 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001264 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001265 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1266 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1267 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1268 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1269 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1270 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1271 else //unsupported interlace format; raise a error
1272 event = OMX_EventError;
1273 if (pThis->m_cb.EventHandler) {
1274 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1275 event, format, 0, NULL );
1276 } else {
1277 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001278 }
1279 }
1280 break;
1281
1282 case OMX_COMPONENT_GENERATE_EOS_DONE:
1283 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1284 if (pThis->m_cb.EventHandler) {
1285 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1286 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1287 } else {
1288 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1289 }
1290 pThis->prev_ts = LLONG_MAX;
1291 pThis->rst_prev_ts = true;
1292 break;
1293
1294 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1295 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1296 pThis->omx_report_error ();
1297 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001298
1299 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1300 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1301 pThis->omx_report_unsupported_setting();
1302 break;
1303
Shalaj Jain273b3e02012-06-22 19:08:03 -07001304 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1305 {
1306 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1307 if (pThis->m_cb.EventHandler) {
1308 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1309 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1310 } else {
1311 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1312 }
1313 }
1314 default:
1315 break;
1316 }
1317 }
1318 pthread_mutex_lock(&pThis->m_lock);
1319 qsize = pThis->m_cmd_q.m_size;
1320 if (pThis->m_state != OMX_StatePause)
1321 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1322 pthread_mutex_unlock(&pThis->m_lock);
1323 }
1324 while(qsize>0);
1325
1326}
1327
Vinay Kalia21649b32013-03-18 17:28:07 -07001328void omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001329{
1330 drv_ctx.video_resolution.frame_height = height;
1331 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001332 drv_ctx.video_resolution.scan_lines = scan_lines;
1333 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001334 rectangle.nLeft = 0;
1335 rectangle.nTop = 0;
1336 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1337 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1338}
1339
Arun Menon6836ba02013-02-19 20:37:40 -08001340OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1341{
1342 if (drv_ctx.video_resolution.frame_width < m_decoder_capability.min_width ||
1343 drv_ctx.video_resolution.frame_width > m_decoder_capability.max_width ||
1344 drv_ctx.video_resolution.frame_height < m_decoder_capability.min_height ||
1345 drv_ctx.video_resolution.frame_height > m_decoder_capability.max_height) {
1346 DEBUG_PRINT_ERROR("\n Unsupported video resolution width = %u height = %u\n",
1347 drv_ctx.video_resolution.frame_width,
1348 drv_ctx.video_resolution.frame_height);
1349 DEBUG_PRINT_ERROR("\n supported range width - min(%u) max(%u\n",
1350 m_decoder_capability.min_width,
1351 m_decoder_capability.max_width);
1352 DEBUG_PRINT_ERROR("\n supported range height - min(%u) max(%u)\n",
1353 m_decoder_capability.min_height,
1354 m_decoder_capability.max_height);
1355 return OMX_ErrorUnsupportedSetting;
1356 }
1357 DEBUG_PRINT_HIGH("\n video session supported\n");
1358 return OMX_ErrorNone;
1359}
1360
Shalaj Jain273b3e02012-06-22 19:08:03 -07001361/* ======================================================================
1362FUNCTION
1363 omx_vdec::ComponentInit
1364
1365DESCRIPTION
1366 Initialize the component.
1367
1368PARAMETERS
1369 ctxt -- Context information related to the self.
1370 id -- Event identifier. This could be any of the following:
1371 1. Command completion event
1372 2. Buffer done callback event
1373 3. Frame done callback event
1374
1375RETURN VALUE
1376 None.
1377
1378========================================================================== */
1379OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1380{
1381
1382 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001383 struct v4l2_fmtdesc fdesc;
1384 struct v4l2_format fmt;
1385 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001386 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001387 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001388 unsigned int alignment = 0,buffer_size = 0;
1389 int fds[2];
1390 int r,ret=0;
1391 bool codec_ambiguous = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001392 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001393 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1394 struct v4l2_control control;
1395 secure_mode = true;
1396 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001397 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001398 }
1399
Shalaj Jain273b3e02012-06-22 19:08:03 -07001400 drv_ctx.video_driver_fd = open("/dev/video32", O_RDWR);
1401
1402 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1403 drv_ctx.video_driver_fd, errno);
1404
1405 if(drv_ctx.video_driver_fd == 0){
1406 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1407 }
1408
1409 if(drv_ctx.video_driver_fd < 0)
1410 {
1411 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1412 return OMX_ErrorInsufficientResources;
1413 }
1414 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1415 drv_ctx.frame_rate.fps_denominator = 1;
1416
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001417 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1418 if(ret < 0) {
1419 close(drv_ctx.video_driver_fd);
1420 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1421 return OMX_ErrorInsufficientResources;
1422 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001423
1424#ifdef INPUT_BUFFER_LOG
1425 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1426#endif
1427#ifdef OUTPUT_BUFFER_LOG
1428 outputBufferFile1 = fopen (outputfilename, "ab");
1429#endif
1430#ifdef OUTPUT_EXTRADATA_LOG
1431 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1432#endif
1433
1434 // Copy the role information which provides the decoder kind
1435 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001436
Shalaj Jain273b3e02012-06-22 19:08:03 -07001437 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1438 OMX_MAX_STRINGNAME_SIZE))
1439 {
1440 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1441 OMX_MAX_STRINGNAME_SIZE);
1442 drv_ctx.timestamp_adjust = true;
1443 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1444 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001445 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001446 /*Initialize Start Code for MPEG4*/
1447 codec_type_parse = CODEC_TYPE_MPEG4;
1448 m_frame_parser.init_start_codes (codec_type_parse);
1449#ifdef INPUT_BUFFER_LOG
1450 strcat(inputfilename, "m4v");
1451#endif
1452 }
1453 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1454 OMX_MAX_STRINGNAME_SIZE))
1455 {
1456 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1457 OMX_MAX_STRINGNAME_SIZE);
1458 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001459 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001460 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1461 /*Initialize Start Code for MPEG2*/
1462 codec_type_parse = CODEC_TYPE_MPEG2;
1463 m_frame_parser.init_start_codes (codec_type_parse);
1464#ifdef INPUT_BUFFER_LOG
1465 strcat(inputfilename, "mpg");
1466#endif
1467 }
1468 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1469 OMX_MAX_STRINGNAME_SIZE))
1470 {
1471 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1472 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1473 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1474 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001475 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001476 codec_type_parse = CODEC_TYPE_H263;
1477 m_frame_parser.init_start_codes (codec_type_parse);
1478#ifdef INPUT_BUFFER_LOG
1479 strcat(inputfilename, "263");
1480#endif
1481 }
1482 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1483 OMX_MAX_STRINGNAME_SIZE))
1484 {
1485 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1486 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1487 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1488 output_capability = V4L2_PIX_FMT_DIVX_311;
1489 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1490 codec_type_parse = CODEC_TYPE_DIVX;
1491 m_frame_parser.init_start_codes (codec_type_parse);
1492
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001493 eRet = createDivxDrmContext();
1494 if (eRet != OMX_ErrorNone) {
1495 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1496 return eRet;
1497 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001498 }
1499 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1500 OMX_MAX_STRINGNAME_SIZE))
1501 {
1502 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1503 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1504 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1505 output_capability = V4L2_PIX_FMT_DIVX;
1506 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1507 codec_type_parse = CODEC_TYPE_DIVX;
1508 codec_ambiguous = true;
1509 m_frame_parser.init_start_codes (codec_type_parse);
1510
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001511 eRet = createDivxDrmContext();
1512 if (eRet != OMX_ErrorNone) {
1513 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1514 return eRet;
1515 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001516 }
1517 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1518 OMX_MAX_STRINGNAME_SIZE))
1519 {
1520 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1521 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1522 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1523 output_capability = V4L2_PIX_FMT_DIVX;
1524 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1525 codec_type_parse = CODEC_TYPE_DIVX;
1526 codec_ambiguous = true;
1527 m_frame_parser.init_start_codes (codec_type_parse);
1528
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001529 eRet = createDivxDrmContext();
1530 if (eRet != OMX_ErrorNone) {
1531 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1532 return eRet;
1533 }
1534
Shalaj Jain273b3e02012-06-22 19:08:03 -07001535 }
1536 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1537 OMX_MAX_STRINGNAME_SIZE))
1538 {
1539 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1540 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1541 output_capability=V4L2_PIX_FMT_H264;
1542 eCompressionFormat = OMX_VIDEO_CodingAVC;
1543 codec_type_parse = CODEC_TYPE_H264;
1544 m_frame_parser.init_start_codes (codec_type_parse);
1545 m_frame_parser.init_nal_length(nal_length);
1546#ifdef INPUT_BUFFER_LOG
1547 strcat(inputfilename, "264");
1548#endif
1549 }
1550 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1551 OMX_MAX_STRINGNAME_SIZE))
1552 {
1553 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1554 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1555 eCompressionFormat = OMX_VIDEO_CodingWMV;
1556 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001557 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001558 m_frame_parser.init_start_codes (codec_type_parse);
1559#ifdef INPUT_BUFFER_LOG
1560 strcat(inputfilename, "vc1");
1561#endif
1562 }
1563 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1564 OMX_MAX_STRINGNAME_SIZE))
1565 {
1566 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1567 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1568 eCompressionFormat = OMX_VIDEO_CodingWMV;
1569 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001570 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001571 m_frame_parser.init_start_codes (codec_type_parse);
1572#ifdef INPUT_BUFFER_LOG
1573 strcat(inputfilename, "vc1");
1574#endif
1575 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001576 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1577 OMX_MAX_STRINGNAME_SIZE))
1578 {
1579 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1580 output_capability=V4L2_PIX_FMT_VP8;
1581 eCompressionFormat = OMX_VIDEO_CodingVPX;
1582 codec_type_parse = CODEC_TYPE_VP8;
1583 arbitrary_bytes = false;
1584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001585 else
1586 {
1587 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1588 eRet = OMX_ErrorInvalidComponentName;
1589 }
1590#ifdef INPUT_BUFFER_LOG
1591 inputBufferFile1 = fopen (inputfilename, "ab");
1592#endif
1593 if (eRet == OMX_ErrorNone)
1594 {
1595
Vinay Kaliada4f4422013-01-09 10:45:03 -08001596 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1597 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1598 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1599 if (!client_buffers.set_color_format(dest_color_format)) {
1600 DEBUG_PRINT_ERROR("\n Setting color format failed");
1601 eRet = OMX_ErrorInsufficientResources;
1602 }
1603
Shalaj Jain273b3e02012-06-22 19:08:03 -07001604 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001605 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001606 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001607 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1608 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001609 }
1610
1611 struct v4l2_capability cap;
1612 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1613 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001614 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001615 /*TODO: How to handle this case */
1616 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001617 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001618 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1619 cap.bus_info, cap.version, cap.capabilities);
1620 }
1621 ret=0;
1622 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1623 fdesc.index=0;
1624 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001625 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001626 fdesc.pixelformat, fdesc.flags);
1627 fdesc.index++;
1628 }
1629 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1630 fdesc.index=0;
1631 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1632
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001633 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001634 fdesc.pixelformat, fdesc.flags);
1635 fdesc.index++;
1636 }
Vinay Kalia21649b32013-03-18 17:28:07 -07001637 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001638 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1639 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1640 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1641 fmt.fmt.pix_mp.pixelformat = output_capability;
1642 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1643 if (ret) {
1644 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001645 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001646 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001647 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001648 if (codec_ambiguous) {
1649 if (output_capability == V4L2_PIX_FMT_DIVX) {
1650 struct v4l2_control divx_ctrl;
1651
1652 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001653 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001654 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001655 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001656 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001657 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001658 }
1659
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001660 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001661 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001662 if (ret) {
1663 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1664 }
1665 } else {
1666 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1667 }
1668 }
1669
Arun Menon6836ba02013-02-19 20:37:40 -08001670 //Get the hardware capabilities
1671 memset((void *)&frmsize,0,sizeof(frmsize));
1672 frmsize.index = 0;
1673 frmsize.pixel_format = output_capability;
1674 ret = ioctl(drv_ctx.video_driver_fd,
1675 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1676 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1677 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1678 return OMX_ErrorHardware;
1679 }
1680
1681 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1682 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1683 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1684 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1685 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1686 }
1687
Shalaj Jain273b3e02012-06-22 19:08:03 -07001688 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1689 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1690 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001691 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001692 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1693 if (ret) {
1694 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001695 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001696 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001697 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001698 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001699 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1700 control.value = 1;
1701 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1702 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1703 if (ret) {
1704 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1705 close(drv_ctx.video_driver_fd);
1706 return OMX_ErrorInsufficientResources;
1707 }
1708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001709
1710 /*Get the Buffer requirements for input and output ports*/
1711 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1712 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001713 if (secure_mode) {
1714 drv_ctx.op_buf.alignment=SZ_1M;
1715 drv_ctx.ip_buf.alignment=SZ_1M;
1716 } else {
1717 drv_ctx.op_buf.alignment=SZ_4K;
1718 drv_ctx.ip_buf.alignment=SZ_4K;
1719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001720 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1721 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001722 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1723 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1724 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1725 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001726 drv_ctx.idr_only_decoding = 0;
1727
Vinay Kalia5713bb32013-01-16 18:39:59 -08001728 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001729#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001730 if (eRet == OMX_ErrorNone && !secure_mode)
1731 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001733 eRet=get_buffer_req(&drv_ctx.ip_buf);
1734 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1735 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001736 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1737 {
1738 if (m_frame_parser.mutils == NULL)
1739 {
1740 m_frame_parser.mutils = new H264_Utils();
1741
1742 if (m_frame_parser.mutils == NULL)
1743 {
1744 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1745 eRet = OMX_ErrorInsufficientResources;
1746 }
1747 else
1748 {
1749 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1750 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1751 h264_scratch.nFilledLen = 0;
1752 h264_scratch.nOffset = 0;
1753
1754 if (h264_scratch.pBuffer == NULL)
1755 {
1756 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1757 return OMX_ErrorInsufficientResources;
1758 }
1759 m_frame_parser.mutils->initialize_frame_checking_environment();
1760 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1761 }
1762 }
1763
1764 h264_parser = new h264_stream_parser();
1765 if (!h264_parser)
1766 {
1767 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1768 eRet = OMX_ErrorInsufficientResources;
1769 }
1770 }
1771
1772 if(pipe(fds))
1773 {
1774 DEBUG_PRINT_ERROR("pipe creation failed\n");
1775 eRet = OMX_ErrorInsufficientResources;
1776 }
1777 else
1778 {
1779 int temp1[2];
1780 if(fds[0] == 0 || fds[1] == 0)
1781 {
1782 if (pipe (temp1))
1783 {
1784 DEBUG_PRINT_ERROR("pipe creation failed\n");
1785 return OMX_ErrorInsufficientResources;
1786 }
1787 //close (fds[0]);
1788 //close (fds[1]);
1789 fds[0] = temp1 [0];
1790 fds[1] = temp1 [1];
1791 }
1792 m_pipe_in = fds[0];
1793 m_pipe_out = fds[1];
1794 r = pthread_create(&msg_thread_id,0,message_thread,this);
1795
1796 if(r < 0)
1797 {
1798 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1799 eRet = OMX_ErrorInsufficientResources;
1800 }
1801 }
1802 }
1803
1804 if (eRet != OMX_ErrorNone)
1805 {
1806 DEBUG_PRINT_ERROR("\n Component Init Failed");
1807 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1808 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1809 NULL);
1810 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1811 close (drv_ctx.video_driver_fd);
1812 drv_ctx.video_driver_fd = -1;
1813 }
1814 else
1815 {
1816 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001818 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1819 return eRet;
1820}
1821
1822/* ======================================================================
1823FUNCTION
1824 omx_vdec::GetComponentVersion
1825
1826DESCRIPTION
1827 Returns the component version.
1828
1829PARAMETERS
1830 TBD.
1831
1832RETURN VALUE
1833 OMX_ErrorNone.
1834
1835========================================================================== */
1836OMX_ERRORTYPE omx_vdec::get_component_version
1837 (
1838 OMX_IN OMX_HANDLETYPE hComp,
1839 OMX_OUT OMX_STRING componentName,
1840 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1841 OMX_OUT OMX_VERSIONTYPE* specVersion,
1842 OMX_OUT OMX_UUIDTYPE* componentUUID
1843 )
1844{
1845 if(m_state == OMX_StateInvalid)
1846 {
1847 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1848 return OMX_ErrorInvalidState;
1849 }
1850 /* TBD -- Return the proper version */
1851 if (specVersion)
1852 {
1853 specVersion->nVersion = OMX_SPEC_VERSION;
1854 }
1855 return OMX_ErrorNone;
1856}
1857/* ======================================================================
1858FUNCTION
1859 omx_vdec::SendCommand
1860
1861DESCRIPTION
1862 Returns zero if all the buffers released..
1863
1864PARAMETERS
1865 None.
1866
1867RETURN VALUE
1868 true/false
1869
1870========================================================================== */
1871OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1872 OMX_IN OMX_COMMANDTYPE cmd,
1873 OMX_IN OMX_U32 param1,
1874 OMX_IN OMX_PTR cmdData
1875 )
1876{
1877 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1878 if(m_state == OMX_StateInvalid)
1879 {
1880 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1881 return OMX_ErrorInvalidState;
1882 }
1883 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1884 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1885 {
1886 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001887 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001888 return OMX_ErrorBadPortIndex;
1889 }
1890 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1891 sem_wait(&m_cmd_lock);
1892 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1893 return OMX_ErrorNone;
1894}
1895
1896/* ======================================================================
1897FUNCTION
1898 omx_vdec::SendCommand
1899
1900DESCRIPTION
1901 Returns zero if all the buffers released..
1902
1903PARAMETERS
1904 None.
1905
1906RETURN VALUE
1907 true/false
1908
1909========================================================================== */
1910OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1911 OMX_IN OMX_COMMANDTYPE cmd,
1912 OMX_IN OMX_U32 param1,
1913 OMX_IN OMX_PTR cmdData
1914 )
1915{
1916 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1917 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1918 int bFlag = 1,sem_posted = 0,ret=0;
1919
1920 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1921 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1922 m_state, eState);
1923
1924 if(cmd == OMX_CommandStateSet)
1925 {
1926 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1927 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1928 /***************************/
1929 /* Current State is Loaded */
1930 /***************************/
1931 if(m_state == OMX_StateLoaded)
1932 {
1933 if(eState == OMX_StateIdle)
1934 {
1935 //if all buffers are allocated or all ports disabled
1936 if(allocate_done() ||
1937 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1938 {
1939 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1940 }
1941 else
1942 {
1943 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1944 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1945 // Skip the event notification
1946 bFlag = 0;
1947 }
1948 }
1949 /* Requesting transition from Loaded to Loaded */
1950 else if(eState == OMX_StateLoaded)
1951 {
1952 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1953 post_event(OMX_EventError,OMX_ErrorSameState,\
1954 OMX_COMPONENT_GENERATE_EVENT);
1955 eRet = OMX_ErrorSameState;
1956 }
1957 /* Requesting transition from Loaded to WaitForResources */
1958 else if(eState == OMX_StateWaitForResources)
1959 {
1960 /* Since error is None , we will post an event
1961 at the end of this function definition */
1962 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1963 }
1964 /* Requesting transition from Loaded to Executing */
1965 else if(eState == OMX_StateExecuting)
1966 {
1967 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1968 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1969 OMX_COMPONENT_GENERATE_EVENT);
1970 eRet = OMX_ErrorIncorrectStateTransition;
1971 }
1972 /* Requesting transition from Loaded to Pause */
1973 else if(eState == OMX_StatePause)
1974 {
1975 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1976 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1977 OMX_COMPONENT_GENERATE_EVENT);
1978 eRet = OMX_ErrorIncorrectStateTransition;
1979 }
1980 /* Requesting transition from Loaded to Invalid */
1981 else if(eState == OMX_StateInvalid)
1982 {
1983 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1984 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1985 eRet = OMX_ErrorInvalidState;
1986 }
1987 else
1988 {
1989 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1990 eState);
1991 eRet = OMX_ErrorBadParameter;
1992 }
1993 }
1994
1995 /***************************/
1996 /* Current State is IDLE */
1997 /***************************/
1998 else if(m_state == OMX_StateIdle)
1999 {
2000 if(eState == OMX_StateLoaded)
2001 {
2002 if(release_done())
2003 {
2004 /*
2005 Since error is None , we will post an event at the end
2006 of this function definition
2007 */
2008 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2009 }
2010 else
2011 {
2012 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2013 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2014 // Skip the event notification
2015 bFlag = 0;
2016 }
2017 }
2018 /* Requesting transition from Idle to Executing */
2019 else if(eState == OMX_StateExecuting)
2020 {
2021 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2022 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2023 bFlag = 1;
2024 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2025 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002026 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002027 }
2028 /* Requesting transition from Idle to Idle */
2029 else if(eState == OMX_StateIdle)
2030 {
2031 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2032 post_event(OMX_EventError,OMX_ErrorSameState,\
2033 OMX_COMPONENT_GENERATE_EVENT);
2034 eRet = OMX_ErrorSameState;
2035 }
2036 /* Requesting transition from Idle to WaitForResources */
2037 else if(eState == OMX_StateWaitForResources)
2038 {
2039 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2040 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2041 OMX_COMPONENT_GENERATE_EVENT);
2042 eRet = OMX_ErrorIncorrectStateTransition;
2043 }
2044 /* Requesting transition from Idle to Pause */
2045 else if(eState == OMX_StatePause)
2046 {
2047 /*To pause the Video core we need to start the driver*/
2048 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2049 NULL) < */0)
2050 {
2051 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2052 omx_report_error ();
2053 eRet = OMX_ErrorHardware;
2054 }
2055 else
2056 {
2057 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2058 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2059 bFlag = 0;
2060 }
2061 }
2062 /* Requesting transition from Idle to Invalid */
2063 else if(eState == OMX_StateInvalid)
2064 {
2065 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2066 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2067 eRet = OMX_ErrorInvalidState;
2068 }
2069 else
2070 {
2071 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2072 eRet = OMX_ErrorBadParameter;
2073 }
2074 }
2075
2076 /******************************/
2077 /* Current State is Executing */
2078 /******************************/
2079 else if(m_state == OMX_StateExecuting)
2080 {
2081 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2082 /* Requesting transition from Executing to Idle */
2083 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002084 {
2085 /* Since error is None , we will post an event
2086 at the end of this function definition
2087 */
2088 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002089 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002090 if(!sem_posted)
2091 {
2092 sem_posted = 1;
2093 sem_post (&m_cmd_lock);
2094 execute_omx_flush(OMX_ALL);
2095 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002096 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002098 /* Requesting transition from Executing to Paused */
2099 else if(eState == OMX_StatePause)
2100 {
2101 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002102 m_state = OMX_StatePause;
2103 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002104 }
2105 /* Requesting transition from Executing to Loaded */
2106 else if(eState == OMX_StateLoaded)
2107 {
2108 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2109 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2110 OMX_COMPONENT_GENERATE_EVENT);
2111 eRet = OMX_ErrorIncorrectStateTransition;
2112 }
2113 /* Requesting transition from Executing to WaitForResources */
2114 else if(eState == OMX_StateWaitForResources)
2115 {
2116 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2117 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2118 OMX_COMPONENT_GENERATE_EVENT);
2119 eRet = OMX_ErrorIncorrectStateTransition;
2120 }
2121 /* Requesting transition from Executing to Executing */
2122 else if(eState == OMX_StateExecuting)
2123 {
2124 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2125 post_event(OMX_EventError,OMX_ErrorSameState,\
2126 OMX_COMPONENT_GENERATE_EVENT);
2127 eRet = OMX_ErrorSameState;
2128 }
2129 /* Requesting transition from Executing to Invalid */
2130 else if(eState == OMX_StateInvalid)
2131 {
2132 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2133 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2134 eRet = OMX_ErrorInvalidState;
2135 }
2136 else
2137 {
2138 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2139 eRet = OMX_ErrorBadParameter;
2140 }
2141 }
2142 /***************************/
2143 /* Current State is Pause */
2144 /***************************/
2145 else if(m_state == OMX_StatePause)
2146 {
2147 /* Requesting transition from Pause to Executing */
2148 if(eState == OMX_StateExecuting)
2149 {
2150 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002151 m_state = OMX_StateExecuting;
2152 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002153 }
2154 /* Requesting transition from Pause to Idle */
2155 else if(eState == OMX_StateIdle)
2156 {
2157 /* Since error is None , we will post an event
2158 at the end of this function definition */
2159 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2160 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2161 if(!sem_posted)
2162 {
2163 sem_posted = 1;
2164 sem_post (&m_cmd_lock);
2165 execute_omx_flush(OMX_ALL);
2166 }
2167 bFlag = 0;
2168 }
2169 /* Requesting transition from Pause to loaded */
2170 else if(eState == OMX_StateLoaded)
2171 {
2172 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2173 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2174 OMX_COMPONENT_GENERATE_EVENT);
2175 eRet = OMX_ErrorIncorrectStateTransition;
2176 }
2177 /* Requesting transition from Pause to WaitForResources */
2178 else if(eState == OMX_StateWaitForResources)
2179 {
2180 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2181 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2182 OMX_COMPONENT_GENERATE_EVENT);
2183 eRet = OMX_ErrorIncorrectStateTransition;
2184 }
2185 /* Requesting transition from Pause to Pause */
2186 else if(eState == OMX_StatePause)
2187 {
2188 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2189 post_event(OMX_EventError,OMX_ErrorSameState,\
2190 OMX_COMPONENT_GENERATE_EVENT);
2191 eRet = OMX_ErrorSameState;
2192 }
2193 /* Requesting transition from Pause to Invalid */
2194 else if(eState == OMX_StateInvalid)
2195 {
2196 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2197 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2198 eRet = OMX_ErrorInvalidState;
2199 }
2200 else
2201 {
2202 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2203 eRet = OMX_ErrorBadParameter;
2204 }
2205 }
2206 /***************************/
2207 /* Current State is WaitForResources */
2208 /***************************/
2209 else if(m_state == OMX_StateWaitForResources)
2210 {
2211 /* Requesting transition from WaitForResources to Loaded */
2212 if(eState == OMX_StateLoaded)
2213 {
2214 /* Since error is None , we will post an event
2215 at the end of this function definition */
2216 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2217 }
2218 /* Requesting transition from WaitForResources to WaitForResources */
2219 else if (eState == OMX_StateWaitForResources)
2220 {
2221 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2222 post_event(OMX_EventError,OMX_ErrorSameState,
2223 OMX_COMPONENT_GENERATE_EVENT);
2224 eRet = OMX_ErrorSameState;
2225 }
2226 /* Requesting transition from WaitForResources to Executing */
2227 else if(eState == OMX_StateExecuting)
2228 {
2229 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2230 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2231 OMX_COMPONENT_GENERATE_EVENT);
2232 eRet = OMX_ErrorIncorrectStateTransition;
2233 }
2234 /* Requesting transition from WaitForResources to Pause */
2235 else if(eState == OMX_StatePause)
2236 {
2237 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2238 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2239 OMX_COMPONENT_GENERATE_EVENT);
2240 eRet = OMX_ErrorIncorrectStateTransition;
2241 }
2242 /* Requesting transition from WaitForResources to Invalid */
2243 else if(eState == OMX_StateInvalid)
2244 {
2245 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2246 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2247 eRet = OMX_ErrorInvalidState;
2248 }
2249 /* Requesting transition from WaitForResources to Loaded -
2250 is NOT tested by Khronos TS */
2251
2252 }
2253 else
2254 {
2255 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2256 eRet = OMX_ErrorBadParameter;
2257 }
2258 }
2259 /********************************/
2260 /* Current State is Invalid */
2261 /*******************************/
2262 else if(m_state == OMX_StateInvalid)
2263 {
2264 /* State Transition from Inavlid to any state */
2265 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2266 || OMX_StateIdle || OMX_StateExecuting
2267 || OMX_StatePause || OMX_StateInvalid))
2268 {
2269 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2270 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2271 OMX_COMPONENT_GENERATE_EVENT);
2272 eRet = OMX_ErrorInvalidState;
2273 }
2274 }
2275 else if (cmd == OMX_CommandFlush)
2276 {
2277 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002278 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002279 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2280 {
2281 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2282 }
2283 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2284 {
2285 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2286 }
2287 if (!sem_posted){
2288 sem_posted = 1;
2289 DEBUG_PRINT_LOW("\n Set the Semaphore");
2290 sem_post (&m_cmd_lock);
2291 execute_omx_flush(param1);
2292 }
2293 bFlag = 0;
2294 }
2295 else if ( cmd == OMX_CommandPortEnable)
2296 {
2297 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002298 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002299 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2300 {
2301 m_inp_bEnabled = OMX_TRUE;
2302
2303 if( (m_state == OMX_StateLoaded &&
2304 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2305 || allocate_input_done())
2306 {
2307 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2308 OMX_COMPONENT_GENERATE_EVENT);
2309 }
2310 else
2311 {
2312 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2313 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2314 // Skip the event notification
2315 bFlag = 0;
2316 }
2317 }
2318 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2319 {
2320 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2321 m_out_bEnabled = OMX_TRUE;
2322
2323 if( (m_state == OMX_StateLoaded &&
2324 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2325 || (allocate_output_done()))
2326 {
2327 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2328 OMX_COMPONENT_GENERATE_EVENT);
2329
2330 }
2331 else
2332 {
2333 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2334 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2335 // Skip the event notification
2336 bFlag = 0;
2337 }
2338 }
2339 }
2340 else if (cmd == OMX_CommandPortDisable)
2341 {
2342 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002343 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002344 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2345 {
2346 m_inp_bEnabled = OMX_FALSE;
2347 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2348 && release_input_done())
2349 {
2350 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2351 OMX_COMPONENT_GENERATE_EVENT);
2352 }
2353 else
2354 {
2355 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2356 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2357 {
2358 if(!sem_posted)
2359 {
2360 sem_posted = 1;
2361 sem_post (&m_cmd_lock);
2362 }
2363 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2364 }
2365
2366 // Skip the event notification
2367 bFlag = 0;
2368 }
2369 }
2370 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2371 {
2372 m_out_bEnabled = OMX_FALSE;
2373 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2374 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2375 && release_output_done())
2376 {
2377 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2378 OMX_COMPONENT_GENERATE_EVENT);
2379 }
2380 else
2381 {
2382 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2383 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2384 {
2385 if (!sem_posted)
2386 {
2387 sem_posted = 1;
2388 sem_post (&m_cmd_lock);
2389 }
2390 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2391 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2392 }
2393 // Skip the event notification
2394 bFlag = 0;
2395
2396 }
2397 }
2398 }
2399 else
2400 {
2401 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2402 eRet = OMX_ErrorNotImplemented;
2403 }
2404 if(eRet == OMX_ErrorNone && bFlag)
2405 {
2406 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2407 }
2408 if(!sem_posted)
2409 {
2410 sem_post(&m_cmd_lock);
2411 }
2412
2413 return eRet;
2414}
2415
2416/* ======================================================================
2417FUNCTION
2418 omx_vdec::ExecuteOmxFlush
2419
2420DESCRIPTION
2421 Executes the OMX flush.
2422
2423PARAMETERS
2424 flushtype - input flush(1)/output flush(0)/ both.
2425
2426RETURN VALUE
2427 true/false
2428
2429========================================================================== */
2430bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2431{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002432 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002433 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002434 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002435 struct v4l2_decoder_cmd dec;
2436 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002437 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002438 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002439 switch (flushType)
2440 {
2441 case OMX_CORE_INPUT_PORT_INDEX:
2442 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002443 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002444 break;
2445 case OMX_CORE_OUTPUT_PORT_INDEX:
2446 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002447 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002448 break;
2449 default:
2450 input_flush_progress = true;
2451 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002452 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2453 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002454 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002455
2456 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002457 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002458 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459 bRet = false;
2460 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002461
Shalaj Jain273b3e02012-06-22 19:08:03 -07002462 return bRet;
2463}
2464/*=========================================================================
2465FUNCTION : execute_output_flush
2466
2467DESCRIPTION
2468 Executes the OMX flush at OUTPUT PORT.
2469
2470PARAMETERS
2471 None.
2472
2473RETURN VALUE
2474 true/false
2475==========================================================================*/
2476bool omx_vdec::execute_output_flush()
2477{
2478 unsigned p1 = 0; // Parameter - 1
2479 unsigned p2 = 0; // Parameter - 2
2480 unsigned ident = 0;
2481 bool bRet = true;
2482
2483 /*Generate FBD for all Buffers in the FTBq*/
2484 pthread_mutex_lock(&m_lock);
2485 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2486 while (m_ftb_q.m_size)
2487 {
2488 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2489 m_ftb_q.m_size,pending_output_buffers);
2490 m_ftb_q.pop_entry(&p1,&p2,&ident);
2491 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002492 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002493 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002494 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002495 }
2496 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2497 {
2498 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2499 }
2500 }
2501 pthread_mutex_unlock(&m_lock);
2502 output_flush_progress = false;
2503
2504 if (arbitrary_bytes)
2505 {
2506 prev_ts = LLONG_MAX;
2507 rst_prev_ts = true;
2508 }
2509 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2510 return bRet;
2511}
2512/*=========================================================================
2513FUNCTION : execute_input_flush
2514
2515DESCRIPTION
2516 Executes the OMX flush at INPUT PORT.
2517
2518PARAMETERS
2519 None.
2520
2521RETURN VALUE
2522 true/false
2523==========================================================================*/
2524bool omx_vdec::execute_input_flush()
2525{
2526 unsigned i =0;
2527 unsigned p1 = 0; // Parameter - 1
2528 unsigned p2 = 0; // Parameter - 2
2529 unsigned ident = 0;
2530 bool bRet = true;
2531
2532 /*Generate EBD for all Buffers in the ETBq*/
2533 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2534
2535 pthread_mutex_lock(&m_lock);
2536 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2537 while (m_etb_q.m_size)
2538 {
2539 m_etb_q.pop_entry(&p1,&p2,&ident);
2540
2541 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2542 {
2543 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2544 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2545 }
2546 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2547 {
2548 pending_input_buffers++;
2549 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2550 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2551 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2552 }
2553 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2554 {
2555 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2556 (OMX_BUFFERHEADERTYPE *)p1);
2557 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2558 }
2559 }
2560 time_stamp_dts.flush_timestamp();
2561 /*Check if Heap Buffers are to be flushed*/
2562 if (arbitrary_bytes)
2563 {
2564 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2565 h264_scratch.nFilledLen = 0;
2566 nal_count = 0;
2567 look_ahead_nal = false;
2568 frame_count = 0;
2569 h264_last_au_ts = LLONG_MAX;
2570 h264_last_au_flags = 0;
2571 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2572 m_demux_entries = 0;
2573 DEBUG_PRINT_LOW("\n Initialize parser");
2574 if (m_frame_parser.mutils)
2575 {
2576 m_frame_parser.mutils->initialize_frame_checking_environment();
2577 }
2578
2579 while (m_input_pending_q.m_size)
2580 {
2581 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2582 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2583 }
2584
2585 if (psource_frame)
2586 {
2587 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2588 psource_frame = NULL;
2589 }
2590
2591 if (pdest_frame)
2592 {
2593 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002594 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2595 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002596 pdest_frame = NULL;
2597 }
2598 m_frame_parser.flush();
2599 }
2600 pthread_mutex_unlock(&m_lock);
2601 input_flush_progress = false;
2602 if (!arbitrary_bytes)
2603 {
2604 prev_ts = LLONG_MAX;
2605 rst_prev_ts = true;
2606 }
2607#ifdef _ANDROID_
2608 if (m_debug_timestamp)
2609 {
2610 m_timestamp_list.reset_ts_list();
2611 }
2612#endif
2613 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2614 return bRet;
2615}
2616
2617
2618/* ======================================================================
2619FUNCTION
2620 omx_vdec::SendCommandEvent
2621
2622DESCRIPTION
2623 Send the event to decoder pipe. This is needed to generate the callbacks
2624 in decoder thread context.
2625
2626PARAMETERS
2627 None.
2628
2629RETURN VALUE
2630 true/false
2631
2632========================================================================== */
2633bool omx_vdec::post_event(unsigned int p1,
2634 unsigned int p2,
2635 unsigned int id)
2636{
2637 bool bRet = false;
2638
2639
2640 pthread_mutex_lock(&m_lock);
2641
Vinay Kaliada4f4422013-01-09 10:45:03 -08002642 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002643 id == OMX_COMPONENT_GENERATE_FBD)
2644 {
2645 m_ftb_q.insert_entry(p1,p2,id);
2646 }
2647 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2648 id == OMX_COMPONENT_GENERATE_EBD ||
2649 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2650 {
2651 m_etb_q.insert_entry(p1,p2,id);
2652 }
2653 else
2654 {
2655 m_cmd_q.insert_entry(p1,p2,id);
2656 }
2657
2658 bRet = true;
2659 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2660 post_message(this, id);
2661
2662 pthread_mutex_unlock(&m_lock);
2663
2664 return bRet;
2665}
2666
2667OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2668{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002669 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002670 if(!profileLevelType)
2671 return OMX_ErrorBadParameter;
2672
2673 if(profileLevelType->nPortIndex == 0) {
2674 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2675 {
2676 if (profileLevelType->nProfileIndex == 0)
2677 {
2678 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2679 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2680
2681 }
2682 else if (profileLevelType->nProfileIndex == 1)
2683 {
2684 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2685 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2686 }
2687 else if(profileLevelType->nProfileIndex == 2)
2688 {
2689 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2690 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2691 }
2692 else
2693 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002694 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002695 profileLevelType->nProfileIndex);
2696 eRet = OMX_ErrorNoMore;
2697 }
2698 }
2699 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2700 {
2701 if (profileLevelType->nProfileIndex == 0)
2702 {
2703 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2704 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2705 }
2706 else
2707 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002708 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002709 eRet = OMX_ErrorNoMore;
2710 }
2711 }
2712 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2713 {
2714 if (profileLevelType->nProfileIndex == 0)
2715 {
2716 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2717 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2718 }
2719 else if(profileLevelType->nProfileIndex == 1)
2720 {
2721 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2722 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2723 }
2724 else
2725 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002726 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002727 eRet = OMX_ErrorNoMore;
2728 }
2729 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002730 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2731 {
2732 eRet = OMX_ErrorNoMore;
2733 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002734 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2735 {
2736 if (profileLevelType->nProfileIndex == 0)
2737 {
2738 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2739 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2740 }
2741 else if(profileLevelType->nProfileIndex == 1)
2742 {
2743 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2744 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2745 }
2746 else
2747 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002748 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002749 eRet = OMX_ErrorNoMore;
2750 }
2751 }
2752 }
2753 else
2754 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002755 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 -07002756 eRet = OMX_ErrorBadPortIndex;
2757 }
2758 return eRet;
2759}
2760
2761/* ======================================================================
2762FUNCTION
2763 omx_vdec::GetParameter
2764
2765DESCRIPTION
2766 OMX Get Parameter method implementation
2767
2768PARAMETERS
2769 <TBD>.
2770
2771RETURN VALUE
2772 Error None if successful.
2773
2774========================================================================== */
2775OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2776 OMX_IN OMX_INDEXTYPE paramIndex,
2777 OMX_INOUT OMX_PTR paramData)
2778{
2779 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2780
2781 DEBUG_PRINT_LOW("get_parameter: \n");
2782 if(m_state == OMX_StateInvalid)
2783 {
2784 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2785 return OMX_ErrorInvalidState;
2786 }
2787 if(paramData == NULL)
2788 {
2789 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2790 return OMX_ErrorBadParameter;
2791 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002792 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002793 {
2794 case OMX_IndexParamPortDefinition:
2795 {
2796 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2797 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2798 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2799 eRet = update_portdef(portDefn);
2800 if (eRet == OMX_ErrorNone)
2801 m_port_def = *portDefn;
2802 break;
2803 }
2804 case OMX_IndexParamVideoInit:
2805 {
2806 OMX_PORT_PARAM_TYPE *portParamType =
2807 (OMX_PORT_PARAM_TYPE *) paramData;
2808 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2809
2810 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2811 portParamType->nSize = sizeof(portParamType);
2812 portParamType->nPorts = 2;
2813 portParamType->nStartPortNumber = 0;
2814 break;
2815 }
2816 case OMX_IndexParamVideoPortFormat:
2817 {
2818 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2819 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2820 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2821
2822 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2823 portFmt->nSize = sizeof(portFmt);
2824
2825 if (0 == portFmt->nPortIndex)
2826 {
2827 if (0 == portFmt->nIndex)
2828 {
2829 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2830 portFmt->eCompressionFormat = eCompressionFormat;
2831 }
2832 else
2833 {
2834 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2835 " NoMore compression formats\n");
2836 eRet = OMX_ErrorNoMore;
2837 }
2838 }
2839 else if (1 == portFmt->nPortIndex)
2840 {
2841 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2842
2843 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002844 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2845 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2846 else if (1 == portFmt->nIndex)
2847 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002848 else
2849 {
2850 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2851 " NoMore Color formats\n");
2852 eRet = OMX_ErrorNoMore;
2853 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002854 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002855 }
2856 else
2857 {
2858 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2859 (int)portFmt->nPortIndex);
2860 eRet = OMX_ErrorBadPortIndex;
2861 }
2862 break;
2863 }
2864 /*Component should support this port definition*/
2865 case OMX_IndexParamAudioInit:
2866 {
2867 OMX_PORT_PARAM_TYPE *audioPortParamType =
2868 (OMX_PORT_PARAM_TYPE *) paramData;
2869 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2870 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2871 audioPortParamType->nSize = sizeof(audioPortParamType);
2872 audioPortParamType->nPorts = 0;
2873 audioPortParamType->nStartPortNumber = 0;
2874 break;
2875 }
2876 /*Component should support this port definition*/
2877 case OMX_IndexParamImageInit:
2878 {
2879 OMX_PORT_PARAM_TYPE *imagePortParamType =
2880 (OMX_PORT_PARAM_TYPE *) paramData;
2881 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2882 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2883 imagePortParamType->nSize = sizeof(imagePortParamType);
2884 imagePortParamType->nPorts = 0;
2885 imagePortParamType->nStartPortNumber = 0;
2886 break;
2887
2888 }
2889 /*Component should support this port definition*/
2890 case OMX_IndexParamOtherInit:
2891 {
2892 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2893 paramIndex);
2894 eRet =OMX_ErrorUnsupportedIndex;
2895 break;
2896 }
2897 case OMX_IndexParamStandardComponentRole:
2898 {
2899 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2900 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2901 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2902 comp_role->nSize = sizeof(*comp_role);
2903
2904 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2905 paramIndex);
2906 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2907 OMX_MAX_STRINGNAME_SIZE);
2908 break;
2909 }
2910 /* Added for parameter test */
2911 case OMX_IndexParamPriorityMgmt:
2912 {
2913
2914 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2915 (OMX_PRIORITYMGMTTYPE *) paramData;
2916 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2917 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2918 priorityMgmType->nSize = sizeof(priorityMgmType);
2919
2920 break;
2921 }
2922 /* Added for parameter test */
2923 case OMX_IndexParamCompBufferSupplier:
2924 {
2925 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2926 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2927 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2928
2929 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2930 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2931 if(0 == bufferSupplierType->nPortIndex)
2932 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2933 else if (1 == bufferSupplierType->nPortIndex)
2934 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2935 else
2936 eRet = OMX_ErrorBadPortIndex;
2937
2938
2939 break;
2940 }
2941 case OMX_IndexParamVideoAvc:
2942 {
2943 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2944 paramIndex);
2945 break;
2946 }
2947 case OMX_IndexParamVideoH263:
2948 {
2949 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2950 paramIndex);
2951 break;
2952 }
2953 case OMX_IndexParamVideoMpeg4:
2954 {
2955 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2956 paramIndex);
2957 break;
2958 }
2959 case OMX_IndexParamVideoMpeg2:
2960 {
2961 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2962 paramIndex);
2963 break;
2964 }
2965 case OMX_IndexParamVideoProfileLevelQuerySupported:
2966 {
2967 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2968 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2969 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2970 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2971 break;
2972 }
2973#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2974 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2975 {
2976 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2977 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2978 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2979
2980 if(secure_mode) {
2981 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302982 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002983 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08002984 nativeBuffersUsage->nUsage =
2985 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2986 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002987 }
2988 } else {
2989 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2990 eRet = OMX_ErrorBadParameter;
2991 }
2992 }
2993 break;
2994#endif
2995
2996 default:
2997 {
2998 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2999 eRet =OMX_ErrorUnsupportedIndex;
3000 }
3001
3002 }
3003
3004 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3005 drv_ctx.video_resolution.frame_width,
3006 drv_ctx.video_resolution.frame_height,
3007 drv_ctx.video_resolution.stride,
3008 drv_ctx.video_resolution.scan_lines);
3009
3010 return eRet;
3011}
3012
3013#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3014OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3015{
3016 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3017 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3018 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3019
3020 if((params == NULL) ||
3021 (params->nativeBuffer == NULL) ||
3022 (params->nativeBuffer->handle == NULL) ||
3023 !m_enable_android_native_buffers)
3024 return OMX_ErrorBadParameter;
3025 m_use_android_native_buffers = OMX_TRUE;
3026 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3027 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3028 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3029 OMX_U8 *buffer = NULL;
3030 if(!secure_mode) {
3031 buffer = (OMX_U8*)mmap(0, handle->size,
3032 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3033 if(buffer == MAP_FAILED) {
3034 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3035 return OMX_ErrorInsufficientResources;
3036 }
3037 }
3038 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3039 } else {
3040 eRet = OMX_ErrorBadParameter;
3041 }
3042 return eRet;
3043}
3044#endif
3045/* ======================================================================
3046FUNCTION
3047 omx_vdec::Setparameter
3048
3049DESCRIPTION
3050 OMX Set Parameter method implementation.
3051
3052PARAMETERS
3053 <TBD>.
3054
3055RETURN VALUE
3056 OMX Error None if successful.
3057
3058========================================================================== */
3059OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3060 OMX_IN OMX_INDEXTYPE paramIndex,
3061 OMX_IN OMX_PTR paramData)
3062{
3063 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003064 int ret=0;
3065 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003066 if(m_state == OMX_StateInvalid)
3067 {
3068 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3069 return OMX_ErrorInvalidState;
3070 }
3071 if(paramData == NULL)
3072 {
3073 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3074 return OMX_ErrorBadParameter;
3075 }
3076 if((m_state != OMX_StateLoaded) &&
3077 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3078 (m_out_bEnabled == OMX_TRUE) &&
3079 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3080 (m_inp_bEnabled == OMX_TRUE)) {
3081 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3082 return OMX_ErrorIncorrectStateOperation;
3083 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003084 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003085 {
3086 case OMX_IndexParamPortDefinition:
3087 {
3088 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3089 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3090 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3091 //been called.
3092 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3093 (int)portDefn->format.video.nFrameHeight,
3094 (int)portDefn->format.video.nFrameWidth);
3095 if(OMX_DirOutput == portDefn->eDir)
3096 {
3097 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3098 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003099 unsigned int buffer_size;
3100 if (!client_buffers.get_buffer_req(buffer_size)) {
3101 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003102 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003103 } else {
3104 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3105 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3106 {
3107 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3108 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3109 eRet = set_buffer_req(&drv_ctx.op_buf);
3110 if (eRet == OMX_ErrorNone)
3111 m_port_def = *portDefn;
3112 }
3113 else
3114 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003115 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003116 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3117 portDefn->nBufferCountActual, portDefn->nBufferSize);
3118 eRet = OMX_ErrorBadParameter;
3119 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003120 }
3121 }
3122 else if(OMX_DirInput == portDefn->eDir)
3123 {
3124 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3125 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3126 {
3127 // Frame rate only should be set if this is a "known value" or to
3128 // activate ts prediction logic (arbitrary mode only) sending input
3129 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003130 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003131 portDefn->format.video.xFramerate >> 16);
3132 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3133 drv_ctx.frame_rate.fps_denominator);
3134 if(!drv_ctx.frame_rate.fps_numerator)
3135 {
3136 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3137 drv_ctx.frame_rate.fps_numerator = 30;
3138 }
3139 if(drv_ctx.frame_rate.fps_denominator)
3140 drv_ctx.frame_rate.fps_numerator = (int)
3141 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3142 drv_ctx.frame_rate.fps_denominator = 1;
3143 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3144 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003145 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003146 frm_int, drv_ctx.frame_rate.fps_numerator /
3147 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07003148 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003149 }
3150 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3151 if(drv_ctx.video_resolution.frame_height !=
3152 portDefn->format.video.nFrameHeight ||
3153 drv_ctx.video_resolution.frame_width !=
3154 portDefn->format.video.nFrameWidth)
3155 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003156 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003157 portDefn->format.video.nFrameWidth,
3158 portDefn->format.video.nFrameHeight);
3159 if (portDefn->format.video.nFrameHeight != 0x0 &&
3160 portDefn->format.video.nFrameWidth != 0x0)
3161 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003162 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003163 portDefn->format.video.nFrameHeight,
3164 portDefn->format.video.nFrameWidth,
3165 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003166 eRet = is_video_session_supported();
3167 if (eRet)
3168 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003169 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3170 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3171 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3172 fmt.fmt.pix_mp.pixelformat = output_capability;
3173 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);
3174 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003175 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003176 {
3177 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3178 eRet = OMX_ErrorUnsupportedSetting;
3179 }
3180 else
3181 eRet = get_buffer_req(&drv_ctx.op_buf);
3182 }
3183 }
3184 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003185 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003186 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003187 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003188 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003189 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3190 (~(buffer_prop->alignment - 1));
3191 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003192 }
3193 else
3194 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003195 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003196 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3197 portDefn->nBufferCountActual, portDefn->nBufferSize);
3198 eRet = OMX_ErrorBadParameter;
3199 }
3200 }
3201 else if (portDefn->eDir == OMX_DirMax)
3202 {
3203 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3204 (int)portDefn->nPortIndex);
3205 eRet = OMX_ErrorBadPortIndex;
3206 }
3207 }
3208 break;
3209 case OMX_IndexParamVideoPortFormat:
3210 {
3211 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3212 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3213 int ret=0;
3214 struct v4l2_format fmt;
3215 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3216 portFmt->eColorFormat);
3217
3218 if(1 == portFmt->nPortIndex)
3219 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003220 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3221 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3222 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3223 fmt.fmt.pix_mp.pixelformat = capture_capability;
3224 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003225 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3226 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003227 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003228 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003229 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003230 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003231 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3232 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3233 else
3234 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003235
Vinay Kaliada4f4422013-01-09 10:45:03 -08003236 if(eRet == OMX_ErrorNone)
3237 {
3238 drv_ctx.output_format = op_format;
3239 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3240 if(ret)
3241 {
3242 DEBUG_PRINT_ERROR("\n Set output format failed");
3243 eRet = OMX_ErrorUnsupportedSetting;
3244 /*TODO: How to handle this case */
3245 }
3246 else
3247 {
3248 eRet = get_buffer_req(&drv_ctx.op_buf);
3249 }
3250 }
3251 if (eRet == OMX_ErrorNone){
3252 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3253 DEBUG_PRINT_ERROR("\n Set color format failed");
3254 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003255 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003256 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003257 }
3258 }
3259 break;
3260
3261 case OMX_QcomIndexPortDefn:
3262 {
3263 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3264 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003265 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003266 portFmt->nFramePackingFormat);
3267
3268 /* Input port */
3269 if (portFmt->nPortIndex == 0)
3270 {
3271 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3272 {
3273 if(secure_mode) {
3274 arbitrary_bytes = false;
3275 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3276 eRet = OMX_ErrorUnsupportedSetting;
3277 } else {
3278 arbitrary_bytes = true;
3279 }
3280 }
3281 else if (portFmt->nFramePackingFormat ==
3282 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3283 {
3284 arbitrary_bytes = false;
3285 }
3286 else
3287 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003288 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003289 portFmt->nFramePackingFormat);
3290 eRet = OMX_ErrorUnsupportedSetting;
3291 }
3292 }
3293 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3294 {
3295 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3296 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3297 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3298 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3299 {
3300 m_out_mem_region_smi = OMX_TRUE;
3301 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3302 {
3303 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3304 m_use_output_pmem = OMX_TRUE;
3305 }
3306 }
3307 }
3308 }
3309 break;
3310
3311 case OMX_IndexParamStandardComponentRole:
3312 {
3313 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3314 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3315 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3316 comp_role->cRole);
3317
3318 if((m_state == OMX_StateLoaded)&&
3319 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3320 {
3321 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3322 }
3323 else
3324 {
3325 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3326 return OMX_ErrorIncorrectStateOperation;
3327 }
3328
3329 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3330 {
3331 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3332 {
3333 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3334 }
3335 else
3336 {
3337 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3338 eRet =OMX_ErrorUnsupportedSetting;
3339 }
3340 }
3341 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3342 {
3343 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3344 {
3345 strlcpy((char*)m_cRole,"video_decoder.mpeg4",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 }
3353 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3354 {
3355 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3356 {
3357 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3358 }
3359 else
3360 {
3361 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3362 eRet =OMX_ErrorUnsupportedSetting;
3363 }
3364 }
3365 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3366 {
3367 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3368 {
3369 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3370 }
3371 else
3372 {
3373 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3374 eRet = OMX_ErrorUnsupportedSetting;
3375 }
3376 }
3377 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3378 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3379 )
3380 {
3381 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3382 {
3383 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3384 }
3385 else
3386 {
3387 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3388 eRet =OMX_ErrorUnsupportedSetting;
3389 }
3390 }
3391 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3392 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3393 )
3394 {
3395 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3396 {
3397 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3398 }
3399 else
3400 {
3401 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3402 eRet =OMX_ErrorUnsupportedSetting;
3403 }
3404 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003405 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3406 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003407 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3408 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003409 {
3410 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3411 }
3412 else
3413 {
3414 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3415 eRet = OMX_ErrorUnsupportedSetting;
3416 }
3417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003418 else
3419 {
3420 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3421 eRet = OMX_ErrorInvalidComponentName;
3422 }
3423 break;
3424 }
3425
3426 case OMX_IndexParamPriorityMgmt:
3427 {
3428 if(m_state != OMX_StateLoaded)
3429 {
3430 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3431 return OMX_ErrorIncorrectStateOperation;
3432 }
3433 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003434 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003435 priorityMgmtype->nGroupID);
3436
Shalaj Jainaf08f302013-03-18 13:15:35 -07003437 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003438 priorityMgmtype->nGroupPriority);
3439
3440 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3441 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3442
3443 break;
3444 }
3445
3446 case OMX_IndexParamCompBufferSupplier:
3447 {
3448 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3449 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3450 bufferSupplierType->eBufferSupplier);
3451 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3452 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3453
3454 else
3455
3456 eRet = OMX_ErrorBadPortIndex;
3457
3458 break;
3459
3460 }
3461 case OMX_IndexParamVideoAvc:
3462 {
3463 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3464 paramIndex);
3465 break;
3466 }
3467 case OMX_IndexParamVideoH263:
3468 {
3469 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3470 paramIndex);
3471 break;
3472 }
3473 case OMX_IndexParamVideoMpeg4:
3474 {
3475 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3476 paramIndex);
3477 break;
3478 }
3479 case OMX_IndexParamVideoMpeg2:
3480 {
3481 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3482 paramIndex);
3483 break;
3484 }
3485 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3486 {
3487 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3488 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003489 struct v4l2_control control;
3490 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003491 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3492 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003493 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3494 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3495 }
3496 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3497 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003498 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003499 }
3500 else
3501 eRet = OMX_ErrorBadParameter;
3502 if (eRet == OMX_ErrorNone)
3503 {
3504 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3505 control.value = pic_order;
3506 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3507 if(rc)
3508 {
3509 DEBUG_PRINT_ERROR("\n Set picture order failed");
3510 eRet = OMX_ErrorUnsupportedSetting;
3511 }
3512 }
3513 break;
3514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003515 case OMX_QcomIndexParamConcealMBMapExtraData:
3516 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003517 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003518 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3519 else {
3520 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3521 eRet = OMX_ErrorUnsupportedSetting;
3522 }
3523 break;
3524 case OMX_QcomIndexParamFrameInfoExtraData:
3525 {
3526 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003527 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003528 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3529 else {
3530 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3531 eRet = OMX_ErrorUnsupportedSetting;
3532 }
3533 break;
3534 }
3535 case OMX_QcomIndexParamInterlaceExtraData:
3536 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003537 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003538 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3539 else {
3540 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3541 eRet = OMX_ErrorUnsupportedSetting;
3542 }
3543 break;
3544 case OMX_QcomIndexParamH264TimeInfo:
3545 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003546 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003547 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3548 else {
3549 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3550 eRet = OMX_ErrorUnsupportedSetting;
3551 }
3552 break;
3553 case OMX_QcomIndexParamVideoDivx:
3554 {
3555 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003556 }
3557 break;
3558 case OMX_QcomIndexPlatformPvt:
3559 {
3560 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3561 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3562 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3563 {
3564 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3565 eRet = OMX_ErrorUnsupportedSetting;
3566 }
3567 else
3568 {
3569 m_out_pvt_entry_pmem = OMX_TRUE;
3570 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3571 {
3572 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3573 m_use_output_pmem = OMX_TRUE;
3574 }
3575 }
3576
3577 }
3578 break;
3579 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3580 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003581 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3582 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3583 struct v4l2_control control;
3584 int rc;
3585 drv_ctx.idr_only_decoding = 1;
3586 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3587 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3588 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3589 if(rc)
3590 {
3591 DEBUG_PRINT_ERROR("\n Set picture order failed");
3592 eRet = OMX_ErrorUnsupportedSetting;
3593 } else {
3594 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3595 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3596 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3597 if(rc)
3598 {
3599 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3600 eRet = OMX_ErrorUnsupportedSetting;
3601 }
3602 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003603 }
3604 break;
3605
3606 case OMX_QcomIndexParamIndexExtraDataType:
3607 {
3608 if(!secure_mode) {
3609 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3610 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3611 (extradataIndexType->bEnabled == OMX_TRUE) &&
3612 (extradataIndexType->nPortIndex == 1))
3613 {
3614 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003615 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003616
Shalaj Jain273b3e02012-06-22 19:08:03 -07003617 }
3618 }
3619 }
3620 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003621 case OMX_QcomIndexParamEnableSmoothStreaming:
3622 {
3623 struct v4l2_control control;
3624 struct v4l2_format fmt;
3625 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3626 control.value = 1;
3627 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3628 if(rc < 0) {
3629 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3630 eRet = OMX_ErrorHardware;
3631 }
3632 }
3633 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003634#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3635 /* Need to allow following two set_parameters even in Idle
3636 * state. This is ANDROID architecture which is not in sync
3637 * with openmax standard. */
3638 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3639 {
3640 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3641 if(enableNativeBuffers) {
3642 m_enable_android_native_buffers = enableNativeBuffers->enable;
3643 }
3644 }
3645 break;
3646 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3647 {
3648 eRet = use_android_native_buffer(hComp, paramData);
3649 }
3650 break;
3651#endif
3652 case OMX_QcomIndexParamEnableTimeStampReorder:
3653 {
3654 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003655 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003656 if (reorder->bEnable == OMX_TRUE) {
3657 frm_int =0;
3658 time_stamp_dts.set_timestamp_reorder_mode(true);
3659 }
3660 else
3661 time_stamp_dts.set_timestamp_reorder_mode(false);
3662 } else {
3663 time_stamp_dts.set_timestamp_reorder_mode(false);
3664 if (reorder->bEnable == OMX_TRUE)
3665 {
3666 eRet = OMX_ErrorUnsupportedSetting;
3667 }
3668 }
3669 }
3670 break;
3671 default:
3672 {
3673 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3674 eRet = OMX_ErrorUnsupportedIndex;
3675 }
3676 }
3677 return eRet;
3678}
3679
3680/* ======================================================================
3681FUNCTION
3682 omx_vdec::GetConfig
3683
3684DESCRIPTION
3685 OMX Get Config Method implementation.
3686
3687PARAMETERS
3688 <TBD>.
3689
3690RETURN VALUE
3691 OMX Error None if successful.
3692
3693========================================================================== */
3694OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3695 OMX_IN OMX_INDEXTYPE configIndex,
3696 OMX_INOUT OMX_PTR configData)
3697{
3698 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3699
3700 if (m_state == OMX_StateInvalid)
3701 {
3702 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3703 return OMX_ErrorInvalidState;
3704 }
3705
Shalaj Jain286b0062013-02-21 20:35:48 -08003706 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003707 {
3708 case OMX_QcomIndexConfigInterlaced:
3709 {
3710 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3711 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3712 if (configFmt->nPortIndex == 1)
3713 {
3714 if (configFmt->nIndex == 0)
3715 {
3716 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3717 }
3718 else if (configFmt->nIndex == 1)
3719 {
3720 configFmt->eInterlaceType =
3721 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3722 }
3723 else if (configFmt->nIndex == 2)
3724 {
3725 configFmt->eInterlaceType =
3726 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3727 }
3728 else
3729 {
3730 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3731 " NoMore Interlaced formats\n");
3732 eRet = OMX_ErrorNoMore;
3733 }
3734
3735 }
3736 else
3737 {
3738 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3739 (int)configFmt->nPortIndex);
3740 eRet = OMX_ErrorBadPortIndex;
3741 }
3742 break;
3743 }
3744 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3745 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003746 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3747 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003748 decoderinstances->nNumOfInstances = 16;
3749 /*TODO: How to handle this case */
3750 break;
3751 }
3752 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3753 {
3754 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3755 {
3756 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3757 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3758 h264_parser->get_frame_pack_data(configFmt);
3759 }
3760 else
3761 {
3762 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3763 }
3764 break;
3765 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003766 case OMX_IndexConfigCommonOutputCrop:
3767 {
3768 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3769 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3770 break;
3771 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003772 default:
3773 {
3774 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3775 eRet = OMX_ErrorBadParameter;
3776 }
3777
3778 }
3779
3780 return eRet;
3781}
3782
3783/* ======================================================================
3784FUNCTION
3785 omx_vdec::SetConfig
3786
3787DESCRIPTION
3788 OMX Set Config method implementation
3789
3790PARAMETERS
3791 <TBD>.
3792
3793RETURN VALUE
3794 OMX Error None if successful.
3795========================================================================== */
3796OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3797 OMX_IN OMX_INDEXTYPE configIndex,
3798 OMX_IN OMX_PTR configData)
3799{
3800 if(m_state == OMX_StateInvalid)
3801 {
3802 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3803 return OMX_ErrorInvalidState;
3804 }
3805
3806 OMX_ERRORTYPE ret = OMX_ErrorNone;
3807 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3808
3809 DEBUG_PRINT_LOW("\n Set Config Called");
3810
3811 if (m_state == OMX_StateExecuting)
3812 {
3813 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3814 return ret;
3815 }
3816
Shalaj Jain286b0062013-02-21 20:35:48 -08003817 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003818 {
3819 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3820 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3821 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3822 {
3823 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3824 OMX_U32 extra_size;
3825 // Parsing done here for the AVC atom is definitely not generic
3826 // Currently this piece of code is working, but certainly
3827 // not tested with all .mp4 files.
3828 // Incase of failure, we might need to revisit this
3829 // for a generic piece of code.
3830
3831 // Retrieve size of NAL length field
3832 // byte #4 contains the size of NAL lenght field
3833 nal_length = (config->pData[4] & 0x03) + 1;
3834
3835 extra_size = 0;
3836 if (nal_length > 2)
3837 {
3838 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3839 extra_size = (nal_length - 2) * 2;
3840 }
3841
3842 // SPS starts from byte #6
3843 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3844 OMX_U8 *pDestBuf;
3845 m_vendor_config.nPortIndex = config->nPortIndex;
3846
3847 // minus 6 --> SPS starts from byte #6
3848 // minus 1 --> picture param set byte to be ignored from avcatom
3849 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3850 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3851 OMX_U32 len;
3852 OMX_U8 index = 0;
3853 // case where SPS+PPS is sent as part of set_config
3854 pDestBuf = m_vendor_config.pData;
3855
Shalaj Jainaf08f302013-03-18 13:15:35 -07003856 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003857 m_vendor_config.nPortIndex,
3858 m_vendor_config.nDataSize,
3859 m_vendor_config.pData);
3860 while (index < 2)
3861 {
3862 uint8 *psize;
3863 len = *pSrcBuf;
3864 len = len << 8;
3865 len |= *(pSrcBuf + 1);
3866 psize = (uint8 *) & len;
3867 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003868 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003869 {
3870 pDestBuf[i] = psize[nal_length - 1 - i];
3871 }
3872 //memcpy(pDestBuf,pSrcBuf,(len+2));
3873 pDestBuf += len + nal_length;
3874 pSrcBuf += len + 2;
3875 index++;
3876 pSrcBuf++; // skip picture param set
3877 len = 0;
3878 }
3879 }
3880 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3881 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3882 {
3883 m_vendor_config.nPortIndex = config->nPortIndex;
3884 m_vendor_config.nDataSize = config->nDataSize;
3885 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3886 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3887 }
3888 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3889 {
3890 if(m_vendor_config.pData)
3891 {
3892 free(m_vendor_config.pData);
3893 m_vendor_config.pData = NULL;
3894 m_vendor_config.nDataSize = 0;
3895 }
3896
3897 if (((*((OMX_U32 *) config->pData)) &
3898 VC1_SP_MP_START_CODE_MASK) ==
3899 VC1_SP_MP_START_CODE)
3900 {
3901 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3902 m_vendor_config.nPortIndex = config->nPortIndex;
3903 m_vendor_config.nDataSize = config->nDataSize;
3904 m_vendor_config.pData =
3905 (OMX_U8 *) malloc(config->nDataSize);
3906 memcpy(m_vendor_config.pData, config->pData,
3907 config->nDataSize);
3908 m_vc1_profile = VC1_SP_MP_RCV;
3909 }
3910 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3911 {
3912 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3913 m_vendor_config.nPortIndex = config->nPortIndex;
3914 m_vendor_config.nDataSize = config->nDataSize;
3915 m_vendor_config.pData =
3916 (OMX_U8 *) malloc((config->nDataSize));
3917 memcpy(m_vendor_config.pData, config->pData,
3918 config->nDataSize);
3919 m_vc1_profile = VC1_AP;
3920 }
3921 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3922 {
3923 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3924 m_vendor_config.nPortIndex = config->nPortIndex;
3925 m_vendor_config.nDataSize = config->nDataSize;
3926 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3927 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3928 m_vc1_profile = VC1_SP_MP_RCV;
3929 }
3930 else
3931 {
3932 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3933 }
3934 }
3935 return ret;
3936 }
3937 else if (configIndex == OMX_IndexConfigVideoNalSize)
3938 {
3939
3940 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3941 nal_length = pNal->nNaluBytes;
3942 m_frame_parser.init_nal_length(nal_length);
3943 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3944 return ret;
3945 }
3946
3947 return OMX_ErrorNotImplemented;
3948}
3949
3950/* ======================================================================
3951FUNCTION
3952 omx_vdec::GetExtensionIndex
3953
3954DESCRIPTION
3955 OMX GetExtensionIndex method implementaion. <TBD>
3956
3957PARAMETERS
3958 <TBD>.
3959
3960RETURN VALUE
3961 OMX Error None if everything successful.
3962
3963========================================================================== */
3964OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3965 OMX_IN OMX_STRING paramName,
3966 OMX_OUT OMX_INDEXTYPE* indexType)
3967{
3968 if(m_state == OMX_StateInvalid)
3969 {
3970 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3971 return OMX_ErrorInvalidState;
3972 }
3973 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3974 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3975 }
3976 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3977 {
3978 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3979 }
3980#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3981 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3982 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3983 }
3984 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3985 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3986 }
3987 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3988 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3989 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3990 }
3991 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3992 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3993 }
3994#endif
3995 else {
3996 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3997 return OMX_ErrorNotImplemented;
3998 }
3999 return OMX_ErrorNone;
4000}
4001
4002/* ======================================================================
4003FUNCTION
4004 omx_vdec::GetState
4005
4006DESCRIPTION
4007 Returns the state information back to the caller.<TBD>
4008
4009PARAMETERS
4010 <TBD>.
4011
4012RETURN VALUE
4013 Error None if everything is successful.
4014========================================================================== */
4015OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4016 OMX_OUT OMX_STATETYPE* state)
4017{
4018 *state = m_state;
4019 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4020 return OMX_ErrorNone;
4021}
4022
4023/* ======================================================================
4024FUNCTION
4025 omx_vdec::ComponentTunnelRequest
4026
4027DESCRIPTION
4028 OMX Component Tunnel Request method implementation. <TBD>
4029
4030PARAMETERS
4031 None.
4032
4033RETURN VALUE
4034 OMX Error None if everything successful.
4035
4036========================================================================== */
4037OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4038 OMX_IN OMX_U32 port,
4039 OMX_IN OMX_HANDLETYPE peerComponent,
4040 OMX_IN OMX_U32 peerPort,
4041 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4042{
4043 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4044 return OMX_ErrorNotImplemented;
4045}
4046
4047/* ======================================================================
4048FUNCTION
4049 omx_vdec::UseOutputBuffer
4050
4051DESCRIPTION
4052 Helper function for Use buffer in the input pin
4053
4054PARAMETERS
4055 None.
4056
4057RETURN VALUE
4058 true/false
4059
4060========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004061OMX_ERRORTYPE omx_vdec::allocate_extradata()
4062{
4063#ifdef USE_ION
4064 if (drv_ctx.extradata_info.buffer_size) {
4065 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4066 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4067 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4068 free_ion_memory(&drv_ctx.extradata_info.ion);
4069 }
4070 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4071 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4072 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4073 &drv_ctx.extradata_info.ion.ion_alloc_data,
4074 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4075 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4076 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4077 return OMX_ErrorInsufficientResources;
4078 }
4079 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4080 drv_ctx.extradata_info.size,
4081 PROT_READ|PROT_WRITE, MAP_SHARED,
4082 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4083 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4084 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4085 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4086 free_ion_memory(&drv_ctx.extradata_info.ion);
4087 return OMX_ErrorInsufficientResources;
4088 }
4089 }
4090#endif
4091 return OMX_ErrorNone;
4092}
4093
4094void omx_vdec::free_extradata() {
4095#ifdef USE_ION
4096 if (drv_ctx.extradata_info.uaddr) {
4097 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4098 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4099 free_ion_memory(&drv_ctx.extradata_info.ion);
4100 }
4101 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4102#endif
4103}
4104
Shalaj Jain273b3e02012-06-22 19:08:03 -07004105OMX_ERRORTYPE omx_vdec::use_output_buffer(
4106 OMX_IN OMX_HANDLETYPE hComp,
4107 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4108 OMX_IN OMX_U32 port,
4109 OMX_IN OMX_PTR appData,
4110 OMX_IN OMX_U32 bytes,
4111 OMX_IN OMX_U8* buffer)
4112{
4113 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4114 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4115 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004116 struct vdec_setbuffer_cmd setbuffers;
4117 OMX_PTR privateAppData = NULL;
4118 private_handle_t *handle = NULL;
4119 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004120 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004121 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4122 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004123
Shalaj Jain273b3e02012-06-22 19:08:03 -07004124 if (!m_out_mem_ptr) {
4125 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4126 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004127 if (eRet == OMX_ErrorNone)
4128 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004129 }
4130
4131 if (eRet == OMX_ErrorNone) {
4132 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4133 if(BITMASK_ABSENT(&m_out_bm_count,i))
4134 {
4135 break;
4136 }
4137 }
4138 }
4139
4140 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004141 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004142 eRet = OMX_ErrorInsufficientResources;
4143 }
4144
4145 if (eRet == OMX_ErrorNone) {
4146#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4147 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004148 if (m_use_android_native_buffers) {
4149 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4150 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4151 handle = (private_handle_t *)nBuf->handle;
4152 privateAppData = params->pAppPrivate;
4153 } else {
4154 handle = (private_handle_t *)buff;
4155 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004156 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004157
4158 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4159 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4160 " expected %u, got %lu",
4161 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4162 return OMX_ErrorBadParameter;
4163 }
4164
4165 if (!m_use_android_native_buffers) {
4166 if (!secure_mode) {
4167 buff = (OMX_U8*)mmap(0, handle->size,
4168 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4169 if (buff == MAP_FAILED) {
4170 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4171 return OMX_ErrorInsufficientResources;
4172 }
4173 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004174 }
4175#if defined(_ANDROID_ICS_)
4176 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004177 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004178#endif
4179 if(!handle) {
4180 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4181 return OMX_ErrorBadParameter;
4182 }
4183 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4184 drv_ctx.ptr_outputbuffer[i].offset = 0;
4185 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4186 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4187 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4188 } else
4189#endif
4190
4191 if (!ouput_egl_buffers && !m_use_output_pmem) {
4192#ifdef USE_ION
4193 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4194 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4195 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004196 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004198 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 -07004199 return OMX_ErrorInsufficientResources;
4200 }
4201 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4202 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4203#else
4204 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4205 open (MEM_DEVICE,O_RDWR);
4206
4207 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004208 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 -07004209 return OMX_ErrorInsufficientResources;
4210 }
4211
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004212 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004213 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4214 {
4215 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4216 open (MEM_DEVICE,O_RDWR);
4217 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004218 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 -07004219 return OMX_ErrorInsufficientResources;
4220 }
4221 }
4222
4223 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4224 drv_ctx.op_buf.buffer_size,
4225 drv_ctx.op_buf.alignment))
4226 {
4227 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4228 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4229 return OMX_ErrorInsufficientResources;
4230 }
4231#endif
4232 if(!secure_mode) {
4233 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4234 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4235 PROT_READ|PROT_WRITE, MAP_SHARED,
4236 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4237 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4238 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4239#ifdef USE_ION
4240 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4241#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004242 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004243 return OMX_ErrorInsufficientResources;
4244 }
4245 }
4246 drv_ctx.ptr_outputbuffer[i].offset = 0;
4247 privateAppData = appData;
4248 }
4249 else {
4250
4251 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4252 if (!appData || !bytes ) {
4253 if(!secure_mode && !buffer) {
4254 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4255 return OMX_ErrorBadParameter;
4256 }
4257 }
4258
4259 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4260 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4261 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4262 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4263 !pmem_list->nEntries ||
4264 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4265 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4266 return OMX_ErrorBadParameter;
4267 }
4268 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4269 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004270 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004271 pmem_info->pmem_fd);
4272 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4273 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4274 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4275 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4276 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4277 privateAppData = appData;
4278 }
4279 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4280 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4281
4282 *bufferHdr = (m_out_mem_ptr + i );
4283 if(secure_mode)
4284 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4285 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4286 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4287 sizeof (vdec_bufferpayload));
4288
Shalaj Jain286b0062013-02-21 20:35:48 -08004289 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4290 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4291 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004292
4293 buf.index = i;
4294 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4295 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004296 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004297 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4298 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004299 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4300 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4301 plane[0].data_offset = 0;
4302 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4303 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4304 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4305 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4306#ifdef USE_ION
4307 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4308#endif
4309 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4310 plane[extra_idx].data_offset = 0;
4311 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4312 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4313 return OMX_ErrorBadParameter;
4314 }
4315 buf.m.planes = plane;
4316 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004317
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004318 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4319 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4320 /*TODO: How to handle this case */
4321 return OMX_ErrorInsufficientResources;
4322 }
4323
4324 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4325 enum v4l2_buf_type buf_type;
4326 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4327 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4328 return OMX_ErrorInsufficientResources;
4329 } else {
4330 streaming[CAPTURE_PORT] = true;
4331 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4332 }
4333 }
4334
Shalaj Jain273b3e02012-06-22 19:08:03 -07004335 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004336 if (m_enable_android_native_buffers) {
4337 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4338 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4339 } else {
4340 (*bufferHdr)->pBuffer = buff;
4341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004342 (*bufferHdr)->pAppPrivate = privateAppData;
4343 BITMASK_SET(&m_out_bm_count,i);
4344 }
4345 return eRet;
4346}
4347
4348/* ======================================================================
4349FUNCTION
4350 omx_vdec::use_input_heap_buffers
4351
4352DESCRIPTION
4353 OMX Use Buffer Heap allocation method implementation.
4354
4355PARAMETERS
4356 <TBD>.
4357
4358RETURN VALUE
4359 OMX Error None , if everything successful.
4360
4361========================================================================== */
4362OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
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 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4371 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4372 if(!m_inp_heap_ptr)
4373 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4374 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4375 drv_ctx.ip_buf.actualcount);
4376 if(!m_phdr_pmem_ptr)
4377 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4378 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4379 drv_ctx.ip_buf.actualcount);
4380 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4381 {
4382 DEBUG_PRINT_ERROR("Insufficent memory");
4383 eRet = OMX_ErrorInsufficientResources;
4384 }
4385 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4386 {
4387 input_use_buffer = true;
4388 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4389 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4390 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4391 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4392 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4393 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4394 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4395 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4396 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 -08004397 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4398 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399 {
4400 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4401 return OMX_ErrorInsufficientResources;
4402 }
4403 m_in_alloc_cnt++;
4404 }
4405 else
4406 {
4407 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4408 eRet = OMX_ErrorInsufficientResources;
4409 }
4410 return eRet;
4411}
4412
4413/* ======================================================================
4414FUNCTION
4415 omx_vdec::UseBuffer
4416
4417DESCRIPTION
4418 OMX Use Buffer method implementation.
4419
4420PARAMETERS
4421 <TBD>.
4422
4423RETURN VALUE
4424 OMX Error None , if everything successful.
4425
4426========================================================================== */
4427OMX_ERRORTYPE omx_vdec::use_buffer(
4428 OMX_IN OMX_HANDLETYPE hComp,
4429 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4430 OMX_IN OMX_U32 port,
4431 OMX_IN OMX_PTR appData,
4432 OMX_IN OMX_U32 bytes,
4433 OMX_IN OMX_U8* buffer)
4434{
4435 OMX_ERRORTYPE error = OMX_ErrorNone;
4436 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004437
4438 if (bufferHdr == NULL || bytes == 0)
4439 {
4440 if(!secure_mode && buffer == NULL) {
4441 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4442 return OMX_ErrorBadParameter;
4443 }
4444 }
4445 if(m_state == OMX_StateInvalid)
4446 {
4447 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4448 return OMX_ErrorInvalidState;
4449 }
4450 if(port == OMX_CORE_INPUT_PORT_INDEX)
4451 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4452 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4453 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4454 else
4455 {
4456 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4457 error = OMX_ErrorBadPortIndex;
4458 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004459 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004460 if(error == OMX_ErrorNone)
4461 {
4462 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4463 {
4464 // Send the callback now
4465 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4466 post_event(OMX_CommandStateSet,OMX_StateIdle,
4467 OMX_COMPONENT_GENERATE_EVENT);
4468 }
4469 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4470 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4471 {
4472 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4473 post_event(OMX_CommandPortEnable,
4474 OMX_CORE_INPUT_PORT_INDEX,
4475 OMX_COMPONENT_GENERATE_EVENT);
4476 }
4477 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4478 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4479 {
4480 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4481 post_event(OMX_CommandPortEnable,
4482 OMX_CORE_OUTPUT_PORT_INDEX,
4483 OMX_COMPONENT_GENERATE_EVENT);
4484 }
4485 }
4486 return error;
4487}
4488
4489OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4490 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4491{
4492 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4493 {
4494 if(m_inp_heap_ptr[bufferindex].pBuffer)
4495 free(m_inp_heap_ptr[bufferindex].pBuffer);
4496 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4497 }
4498 if (pmem_bufferHdr)
4499 free_input_buffer(pmem_bufferHdr);
4500 return OMX_ErrorNone;
4501}
4502
4503OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4504{
4505 unsigned int index = 0;
4506 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4507 {
4508 return OMX_ErrorBadParameter;
4509 }
4510
4511 index = bufferHdr - m_inp_mem_ptr;
4512 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4513
4514 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4515 {
4516 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4517 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4518 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004519 struct vdec_setbuffer_cmd setbuffers;
4520 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4521 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4522 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004523 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4524 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Shalaj Jainaf08f302013-03-18 13:15:35 -07004525 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004526 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4527 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4528 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4529 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4530 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4531 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4532 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4533 {
4534 free(m_desc_buffer_ptr[index].buf_addr);
4535 m_desc_buffer_ptr[index].buf_addr = NULL;
4536 m_desc_buffer_ptr[index].desc_data_size = 0;
4537 }
4538#ifdef USE_ION
4539 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4540#endif
4541 }
4542 }
4543
4544 return OMX_ErrorNone;
4545}
4546
4547OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4548{
4549 unsigned int index = 0;
4550
4551 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4552 {
4553 return OMX_ErrorBadParameter;
4554 }
4555
4556 index = bufferHdr - m_out_mem_ptr;
4557 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4558
4559 if (index < drv_ctx.op_buf.actualcount
4560 && drv_ctx.ptr_outputbuffer)
4561 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004562 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004563 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4564
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565 struct vdec_setbuffer_cmd setbuffers;
4566 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4567 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4568 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569#ifdef _ANDROID_
4570 if(m_enable_android_native_buffers) {
4571 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4572 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4573 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4574 }
4575 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4576 } else {
4577#endif
4578 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4579 {
4580 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4581 drv_ctx.ptr_outputbuffer[0].pmem_fd);
Shalaj Jainaf08f302013-03-18 13:15:35 -07004582 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004583 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004584 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4585 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004586 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4588 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4589#ifdef USE_ION
4590 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4591#endif
4592 }
4593#ifdef _ANDROID_
4594 }
4595#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004596 if (release_output_done()) {
4597 free_extradata();
4598 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004599 }
4600
4601 return OMX_ErrorNone;
4602
4603}
4604
4605OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4606 OMX_BUFFERHEADERTYPE **bufferHdr,
4607 OMX_U32 port,
4608 OMX_PTR appData,
4609 OMX_U32 bytes)
4610{
4611 OMX_BUFFERHEADERTYPE *input = NULL;
4612 unsigned char *buf_addr = NULL;
4613 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4614 unsigned i = 0;
4615
4616 /* Sanity Check*/
4617 if (bufferHdr == NULL)
4618 {
4619 return OMX_ErrorBadParameter;
4620 }
4621
4622 if (m_inp_heap_ptr == NULL)
4623 {
4624 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4625 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4626 drv_ctx.ip_buf.actualcount);
4627 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4628 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4629 drv_ctx.ip_buf.actualcount);
4630
4631 if (m_inp_heap_ptr == NULL)
4632 {
4633 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4634 return OMX_ErrorInsufficientResources;
4635 }
4636 }
4637
4638 /*Find a Free index*/
4639 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4640 {
4641 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4642 {
4643 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4644 break;
4645 }
4646 }
4647
4648 if (i < drv_ctx.ip_buf.actualcount)
4649 {
4650 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4651
4652 if (buf_addr == NULL)
4653 {
4654 return OMX_ErrorInsufficientResources;
4655 }
4656
4657 *bufferHdr = (m_inp_heap_ptr + i);
4658 input = *bufferHdr;
4659 BITMASK_SET(&m_heap_inp_bm_count,i);
4660
4661 input->pBuffer = (OMX_U8 *)buf_addr;
4662 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4663 input->nVersion.nVersion = OMX_SPEC_VERSION;
4664 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4665 input->pAppPrivate = appData;
4666 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4667 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4668 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004669 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004671 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4672 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004673 {
4674 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4675 return OMX_ErrorInsufficientResources;
4676 }
4677 }
4678 else
4679 {
4680 return OMX_ErrorBadParameter;
4681 }
4682
4683 return eRet;
4684
4685}
4686
4687
4688/* ======================================================================
4689FUNCTION
4690 omx_vdec::AllocateInputBuffer
4691
4692DESCRIPTION
4693 Helper function for allocate buffer in the input pin
4694
4695PARAMETERS
4696 None.
4697
4698RETURN VALUE
4699 true/false
4700
4701========================================================================== */
4702OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4703 OMX_IN OMX_HANDLETYPE hComp,
4704 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4705 OMX_IN OMX_U32 port,
4706 OMX_IN OMX_PTR appData,
4707 OMX_IN OMX_U32 bytes)
4708{
4709
4710 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4711 struct vdec_setbuffer_cmd setbuffers;
4712 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004713 unsigned i = 0;
4714 unsigned char *buf_addr = NULL;
4715 int pmem_fd = -1;
4716
4717 if(bytes != drv_ctx.ip_buf.buffer_size)
4718 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004719 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004720 bytes, drv_ctx.ip_buf.buffer_size);
4721 return OMX_ErrorBadParameter;
4722 }
4723
4724 if(!m_inp_mem_ptr)
4725 {
4726 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4727 drv_ctx.ip_buf.actualcount,
4728 drv_ctx.ip_buf.buffer_size);
4729
4730 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4731 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4732
4733 if (m_inp_mem_ptr == NULL)
4734 {
4735 return OMX_ErrorInsufficientResources;
4736 }
4737
4738 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4739 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4740
4741 if (drv_ctx.ptr_inputbuffer == NULL)
4742 {
4743 return OMX_ErrorInsufficientResources;
4744 }
4745#ifdef USE_ION
4746 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4747 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4748
4749 if (drv_ctx.ip_buf_ion_info == NULL)
4750 {
4751 return OMX_ErrorInsufficientResources;
4752 }
4753#endif
4754
4755 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4756 {
4757 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4758#ifdef USE_ION
4759 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4760#endif
4761 }
4762 }
4763
4764 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4765 {
4766 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4767 {
4768 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4769 break;
4770 }
4771 }
4772
4773 if(i < drv_ctx.ip_buf.actualcount)
4774 {
4775 struct v4l2_buffer buf;
4776 struct v4l2_plane plane;
4777 int rc;
4778 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4779#ifdef USE_ION
4780 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4781 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4782 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004783 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004784 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4785 return OMX_ErrorInsufficientResources;
4786 }
4787 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4788#else
4789 pmem_fd = open (MEM_DEVICE,O_RDWR);
4790
4791 if (pmem_fd < 0)
4792 {
4793 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4794 return OMX_ErrorInsufficientResources;
4795 }
4796
4797 if (pmem_fd == 0)
4798 {
4799 pmem_fd = open (MEM_DEVICE,O_RDWR);
4800
4801 if (pmem_fd < 0)
4802 {
4803 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4804 return OMX_ErrorInsufficientResources;
4805 }
4806 }
4807
4808 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4809 drv_ctx.ip_buf.alignment))
4810 {
4811 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4812 close(pmem_fd);
4813 return OMX_ErrorInsufficientResources;
4814 }
4815#endif
4816 if (!secure_mode) {
4817 buf_addr = (unsigned char *)mmap(NULL,
4818 drv_ctx.ip_buf.buffer_size,
4819 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4820
4821 if (buf_addr == MAP_FAILED)
4822 {
4823 close(pmem_fd);
4824#ifdef USE_ION
4825 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4826#endif
4827 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4828 return OMX_ErrorInsufficientResources;
4829 }
4830 }
4831 *bufferHdr = (m_inp_mem_ptr + i);
4832 if (secure_mode)
4833 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4834 else
4835 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4836 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4837 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4838 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4839 drv_ctx.ptr_inputbuffer [i].offset = 0;
4840
4841
4842 buf.index = i;
4843 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4844 buf.memory = V4L2_MEMORY_USERPTR;
4845 plane.bytesused = 0;
4846 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4847 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4848 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4849 plane.reserved[1] = 0;
4850 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4851 buf.m.planes = &plane;
4852 buf.length = 1;
4853
Shalaj Jainaf08f302013-03-18 13:15:35 -07004854 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4855 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004856
4857 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4858
4859 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004860 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861 /*TODO: How to handle this case */
4862 return OMX_ErrorInsufficientResources;
4863 }
4864
4865 input = *bufferHdr;
4866 BITMASK_SET(&m_inp_bm_count,i);
4867 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4868 if (secure_mode)
4869 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4870 else
4871 input->pBuffer = (OMX_U8 *)buf_addr;
4872 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4873 input->nVersion.nVersion = OMX_SPEC_VERSION;
4874 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4875 input->pAppPrivate = appData;
4876 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4877 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4878
4879 if (drv_ctx.disable_dmx)
4880 {
4881 eRet = allocate_desc_buffer(i);
4882 }
4883 }
4884 else
4885 {
4886 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4887 eRet = OMX_ErrorInsufficientResources;
4888 }
4889 return eRet;
4890}
4891
4892
4893/* ======================================================================
4894FUNCTION
4895 omx_vdec::AllocateOutputBuffer
4896
4897DESCRIPTION
4898 Helper fn for AllocateBuffer in the output pin
4899
4900PARAMETERS
4901 <TBD>.
4902
4903RETURN VALUE
4904 OMX Error None if everything went well.
4905
4906========================================================================== */
4907OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4908 OMX_IN OMX_HANDLETYPE hComp,
4909 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4910 OMX_IN OMX_U32 port,
4911 OMX_IN OMX_PTR appData,
4912 OMX_IN OMX_U32 bytes)
4913{
4914 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4915 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4916 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004917 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004918 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004919#ifdef USE_ION
4920 int ion_device_fd =-1;
4921 struct ion_allocation_data ion_alloc_data;
4922 struct ion_fd_data fd_ion_data;
4923#endif
4924 if(!m_out_mem_ptr)
4925 {
4926 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4927 drv_ctx.op_buf.actualcount,
4928 drv_ctx.op_buf.buffer_size);
4929 int nBufHdrSize = 0;
4930 int nPlatformEntrySize = 0;
4931 int nPlatformListSize = 0;
4932 int nPMEMInfoSize = 0;
4933 int pmem_fd = -1;
4934 unsigned char *pmem_baseaddress = NULL;
4935
4936 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4937 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4938 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4939
4940 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4941 drv_ctx.op_buf.actualcount);
4942 nBufHdrSize = drv_ctx.op_buf.actualcount *
4943 sizeof(OMX_BUFFERHEADERTYPE);
4944
4945 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4946 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4947 nPlatformListSize = drv_ctx.op_buf.actualcount *
4948 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4949 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4950 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4951
4952 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4953 sizeof(OMX_BUFFERHEADERTYPE),
4954 nPMEMInfoSize,
4955 nPlatformListSize);
4956 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4957 drv_ctx.op_buf.actualcount);
4958#ifdef USE_ION
4959 ion_device_fd = alloc_map_ion_memory(
4960 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4961 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004962 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963 if (ion_device_fd < 0) {
4964 return OMX_ErrorInsufficientResources;
4965 }
4966 pmem_fd = fd_ion_data.fd;
4967#else
4968 pmem_fd = open (MEM_DEVICE,O_RDWR);
4969
4970 if (pmem_fd < 0)
4971 {
4972 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4973 drv_ctx.op_buf.buffer_size);
4974 return OMX_ErrorInsufficientResources;
4975 }
4976
4977 if(pmem_fd == 0)
4978 {
4979 pmem_fd = open (MEM_DEVICE,O_RDWR);
4980
4981 if (pmem_fd < 0)
4982 {
4983 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4984 drv_ctx.op_buf.buffer_size);
4985 return OMX_ErrorInsufficientResources;
4986 }
4987 }
4988
4989 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4990 drv_ctx.op_buf.actualcount,
4991 drv_ctx.op_buf.alignment))
4992 {
4993 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4994 close(pmem_fd);
4995 return OMX_ErrorInsufficientResources;
4996 }
4997#endif
4998 if (!secure_mode) {
4999 pmem_baseaddress = (unsigned char *)mmap(NULL,
5000 (drv_ctx.op_buf.buffer_size *
5001 drv_ctx.op_buf.actualcount),
5002 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5003 if (pmem_baseaddress == MAP_FAILED)
5004 {
5005 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5006 drv_ctx.op_buf.buffer_size);
5007 close(pmem_fd);
5008#ifdef USE_ION
5009 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5010#endif
5011 return OMX_ErrorInsufficientResources;
5012 }
5013 }
5014 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5015 // Alloc mem for platform specific info
5016 char *pPtr=NULL;
5017 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5018 nPMEMInfoSize,1);
5019 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5020 calloc (sizeof(struct vdec_bufferpayload),
5021 drv_ctx.op_buf.actualcount);
5022 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5023 calloc (sizeof (struct vdec_output_frameinfo),
5024 drv_ctx.op_buf.actualcount);
5025#ifdef USE_ION
5026 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5027 calloc (sizeof(struct vdec_ion),
5028 drv_ctx.op_buf.actualcount);
5029#endif
5030
5031 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5032 && drv_ctx.ptr_respbuffer)
5033 {
5034 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5035 (drv_ctx.op_buf.buffer_size *
5036 drv_ctx.op_buf.actualcount);
5037 bufHdr = m_out_mem_ptr;
5038 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5039 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5040 (((char *) m_platform_list) + nPlatformListSize);
5041 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5042 (((char *) m_platform_entry) + nPlatformEntrySize);
5043 pPlatformList = m_platform_list;
5044 pPlatformEntry = m_platform_entry;
5045 pPMEMInfo = m_pmem_info;
5046
5047 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5048
5049 // Settting the entire storage nicely
5050 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5051 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5052 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5053 {
5054 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5055 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5056 // Set the values when we determine the right HxW param
5057 bufHdr->nAllocLen = bytes;
5058 bufHdr->nFilledLen = 0;
5059 bufHdr->pAppPrivate = appData;
5060 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5061 // Platform specific PMEM Information
5062 // Initialize the Platform Entry
5063 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5064 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5065 pPlatformEntry->entry = pPMEMInfo;
5066 // Initialize the Platform List
5067 pPlatformList->nEntries = 1;
5068 pPlatformList->entryList = pPlatformEntry;
5069 // Keep pBuffer NULL till vdec is opened
5070 bufHdr->pBuffer = NULL;
5071 bufHdr->nOffset = 0;
5072
5073 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5074 pPMEMInfo->pmem_fd = 0;
5075 bufHdr->pPlatformPrivate = pPlatformList;
5076
5077 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005078 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005079#ifdef USE_ION
5080 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5081 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5082 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5083#endif
5084
5085 /*Create a mapping between buffers*/
5086 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5087 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5088 &drv_ctx.ptr_outputbuffer[i];
5089 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5090 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5091 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5092
5093 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5094 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5095 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5096 // Move the buffer and buffer header pointers
5097 bufHdr++;
5098 pPMEMInfo++;
5099 pPlatformEntry++;
5100 pPlatformList++;
5101 }
5102 }
5103 else
5104 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005105 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106 m_out_mem_ptr, pPtr);
5107 if(m_out_mem_ptr)
5108 {
5109 free(m_out_mem_ptr);
5110 m_out_mem_ptr = NULL;
5111 }
5112 if(pPtr)
5113 {
5114 free(pPtr);
5115 pPtr = NULL;
5116 }
5117 if(drv_ctx.ptr_outputbuffer)
5118 {
5119 free(drv_ctx.ptr_outputbuffer);
5120 drv_ctx.ptr_outputbuffer = NULL;
5121 }
5122 if(drv_ctx.ptr_respbuffer)
5123 {
5124 free(drv_ctx.ptr_respbuffer);
5125 drv_ctx.ptr_respbuffer = NULL;
5126 }
5127#ifdef USE_ION
5128 if (drv_ctx.op_buf_ion_info) {
5129 DEBUG_PRINT_LOW("\n Free o/p ion context");
5130 free(drv_ctx.op_buf_ion_info);
5131 drv_ctx.op_buf_ion_info = NULL;
5132 }
5133#endif
5134 eRet = OMX_ErrorInsufficientResources;
5135 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005136 if (eRet == OMX_ErrorNone)
5137 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005138 }
5139
5140 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5141 {
5142 if(BITMASK_ABSENT(&m_out_bm_count,i))
5143 {
5144 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5145 break;
5146 }
5147 }
5148
5149 if (eRet == OMX_ErrorNone)
5150 {
5151 if(i < drv_ctx.op_buf.actualcount)
5152 {
5153 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005154 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005155 int rc;
5156 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5157
5158 drv_ctx.ptr_outputbuffer[i].buffer_len =
5159 drv_ctx.op_buf.buffer_size;
5160
5161 *bufferHdr = (m_out_mem_ptr + i );
5162 if (secure_mode) {
5163 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5164 }
5165 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5166
5167 buf.index = i;
5168 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5169 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005170 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005171 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5172 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005173#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005174 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005175#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005176 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5177 plane[0].data_offset = 0;
5178 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5179 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5180 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5181 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5182#ifdef USE_ION
5183 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5184#endif
5185 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5186 plane[extra_idx].data_offset = 0;
5187 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5188 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5189 return OMX_ErrorBadParameter;
5190 }
5191 buf.m.planes = plane;
5192 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005193 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 -07005194 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5195 if (rc) {
5196 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197 return OMX_ErrorInsufficientResources;
5198 }
5199
5200 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5201 enum v4l2_buf_type buf_type;
5202 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5203 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5204 if (rc) {
5205 return OMX_ErrorInsufficientResources;
5206 } else {
5207 streaming[CAPTURE_PORT] = true;
5208 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5209 }
5210 }
5211
5212 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5213 (*bufferHdr)->pAppPrivate = appData;
5214 BITMASK_SET(&m_out_bm_count,i);
5215 }
5216 else
5217 {
5218 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5219 eRet = OMX_ErrorInsufficientResources;
5220 }
5221 }
5222
5223 return eRet;
5224}
5225
5226
5227// AllocateBuffer -- API Call
5228/* ======================================================================
5229FUNCTION
5230 omx_vdec::AllocateBuffer
5231
5232DESCRIPTION
5233 Returns zero if all the buffers released..
5234
5235PARAMETERS
5236 None.
5237
5238RETURN VALUE
5239 true/false
5240
5241========================================================================== */
5242OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5243 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5244 OMX_IN OMX_U32 port,
5245 OMX_IN OMX_PTR appData,
5246 OMX_IN OMX_U32 bytes)
5247{
5248 unsigned i = 0;
5249 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5250
5251 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5252 if(m_state == OMX_StateInvalid)
5253 {
5254 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5255 return OMX_ErrorInvalidState;
5256 }
5257
5258 if(port == OMX_CORE_INPUT_PORT_INDEX)
5259 {
5260 if (arbitrary_bytes)
5261 {
5262 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5263 }
5264 else
5265 {
5266 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5267 }
5268 }
5269 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5270 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005271 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5272 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273 }
5274 else
5275 {
5276 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5277 eRet = OMX_ErrorBadPortIndex;
5278 }
5279 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5280 if(eRet == OMX_ErrorNone)
5281 {
5282 if(allocate_done()){
5283 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5284 {
5285 // Send the callback now
5286 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5287 post_event(OMX_CommandStateSet,OMX_StateIdle,
5288 OMX_COMPONENT_GENERATE_EVENT);
5289 }
5290 }
5291 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5292 {
5293 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5294 {
5295 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5296 post_event(OMX_CommandPortEnable,
5297 OMX_CORE_INPUT_PORT_INDEX,
5298 OMX_COMPONENT_GENERATE_EVENT);
5299 }
5300 }
5301 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5302 {
5303 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5304 {
5305 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5306 post_event(OMX_CommandPortEnable,
5307 OMX_CORE_OUTPUT_PORT_INDEX,
5308 OMX_COMPONENT_GENERATE_EVENT);
5309 }
5310 }
5311 }
5312 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5313 return eRet;
5314}
5315
5316// Free Buffer - API call
5317/* ======================================================================
5318FUNCTION
5319 omx_vdec::FreeBuffer
5320
5321DESCRIPTION
5322
5323PARAMETERS
5324 None.
5325
5326RETURN VALUE
5327 true/false
5328
5329========================================================================== */
5330OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5331 OMX_IN OMX_U32 port,
5332 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5333{
5334 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5335 unsigned int nPortIndex;
5336 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5337
5338 if(m_state == OMX_StateIdle &&
5339 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5340 {
5341 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5342 }
5343 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5344 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5345 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005346 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005347 }
5348 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5349 {
5350 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5351 post_event(OMX_EventError,
5352 OMX_ErrorPortUnpopulated,
5353 OMX_COMPONENT_GENERATE_EVENT);
5354
5355 return OMX_ErrorIncorrectStateOperation;
5356 }
5357 else if (m_state != OMX_StateInvalid)
5358 {
5359 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5360 post_event(OMX_EventError,
5361 OMX_ErrorPortUnpopulated,
5362 OMX_COMPONENT_GENERATE_EVENT);
5363 }
5364
5365 if(port == OMX_CORE_INPUT_PORT_INDEX)
5366 {
5367 /*Check if arbitrary bytes*/
5368 if(!arbitrary_bytes && !input_use_buffer)
5369 nPortIndex = buffer - m_inp_mem_ptr;
5370 else
5371 nPortIndex = buffer - m_inp_heap_ptr;
5372
5373 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5374 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5375 {
5376 // Clear the bit associated with it.
5377 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5378 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5379 if (input_use_buffer == true)
5380 {
5381
5382 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5383 if(m_phdr_pmem_ptr)
5384 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5385 }
5386 else
5387 {
5388 if (arbitrary_bytes)
5389 {
5390 if(m_phdr_pmem_ptr)
5391 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5392 else
5393 free_input_buffer(nPortIndex,NULL);
5394 }
5395 else
5396 free_input_buffer(buffer);
5397 }
5398 m_inp_bPopulated = OMX_FALSE;
5399 /*Free the Buffer Header*/
5400 if (release_input_done())
5401 {
5402 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5403 free_input_buffer_header();
5404 }
5405 }
5406 else
5407 {
5408 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5409 eRet = OMX_ErrorBadPortIndex;
5410 }
5411
5412 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5413 && release_input_done())
5414 {
5415 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5416 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5417 post_event(OMX_CommandPortDisable,
5418 OMX_CORE_INPUT_PORT_INDEX,
5419 OMX_COMPONENT_GENERATE_EVENT);
5420 }
5421 }
5422 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5423 {
5424 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005425 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005426 if(nPortIndex < drv_ctx.op_buf.actualcount)
5427 {
5428 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5429 // Clear the bit associated with it.
5430 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5431 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005432 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005433
5434 if (release_output_done())
5435 {
5436 free_output_buffer_header();
5437 }
5438 }
5439 else
5440 {
5441 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5442 eRet = OMX_ErrorBadPortIndex;
5443 }
5444 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5445 && release_output_done())
5446 {
5447 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5448
5449 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5450 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5451#ifdef _ANDROID_ICS_
5452 if (m_enable_android_native_buffers)
5453 {
5454 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5455 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5456 }
5457#endif
5458
5459 post_event(OMX_CommandPortDisable,
5460 OMX_CORE_OUTPUT_PORT_INDEX,
5461 OMX_COMPONENT_GENERATE_EVENT);
5462 }
5463 }
5464 else
5465 {
5466 eRet = OMX_ErrorBadPortIndex;
5467 }
5468 if((eRet == OMX_ErrorNone) &&
5469 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5470 {
5471 if(release_done())
5472 {
5473 // Send the callback now
5474 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5475 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5476 OMX_COMPONENT_GENERATE_EVENT);
5477 }
5478 }
5479 return eRet;
5480}
5481
5482
5483/* ======================================================================
5484FUNCTION
5485 omx_vdec::EmptyThisBuffer
5486
5487DESCRIPTION
5488 This routine is used to push the encoded video frames to
5489 the video decoder.
5490
5491PARAMETERS
5492 None.
5493
5494RETURN VALUE
5495 OMX Error None if everything went successful.
5496
5497========================================================================== */
5498OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5499 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5500{
5501 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5502 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5503
5504 if(m_state == OMX_StateInvalid)
5505 {
5506 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5507 return OMX_ErrorInvalidState;
5508 }
5509
5510 if (buffer == NULL)
5511 {
5512 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5513 return OMX_ErrorBadParameter;
5514 }
5515
5516 if (!m_inp_bEnabled)
5517 {
5518 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5519 return OMX_ErrorIncorrectStateOperation;
5520 }
5521
5522 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5523 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005524 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525 return OMX_ErrorBadPortIndex;
5526 }
5527
5528#ifdef _ANDROID_
5529 if(iDivXDrmDecrypt)
5530 {
5531 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5532 if(drmErr != OMX_ErrorNone) {
5533 // this error can be ignored
5534 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5535 }
5536 }
5537#endif //_ANDROID_
5538 if (perf_flag)
5539 {
5540 if (!latency)
5541 {
5542 dec_time.stop();
5543 latency = dec_time.processing_time_us();
5544 dec_time.start();
5545 }
5546 }
5547
5548 if (arbitrary_bytes)
5549 {
5550 nBufferIndex = buffer - m_inp_heap_ptr;
5551 }
5552 else
5553 {
5554 if (input_use_buffer == true)
5555 {
5556 nBufferIndex = buffer - m_inp_heap_ptr;
5557 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5558 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5559 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5560 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005561 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 -07005562 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5563 }
5564 else{
5565 nBufferIndex = buffer - m_inp_mem_ptr;
5566 }
5567 }
5568
5569 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5570 {
5571 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5572 return OMX_ErrorBadParameter;
5573 }
5574
5575 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5576 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5577 if (arbitrary_bytes)
5578 {
5579 post_event ((unsigned)hComp,(unsigned)buffer,
5580 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5581 }
5582 else
5583 {
5584 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5585 set_frame_rate(buffer->nTimeStamp);
5586 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5587 }
5588 return OMX_ErrorNone;
5589}
5590
5591/* ======================================================================
5592FUNCTION
5593 omx_vdec::empty_this_buffer_proxy
5594
5595DESCRIPTION
5596 This routine is used to push the encoded video frames to
5597 the video decoder.
5598
5599PARAMETERS
5600 None.
5601
5602RETURN VALUE
5603 OMX Error None if everything went successful.
5604
5605========================================================================== */
5606OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5607 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5608{
5609 int push_cnt = 0,i=0;
5610 unsigned nPortIndex = 0;
5611 OMX_ERRORTYPE ret = OMX_ErrorNone;
5612 struct vdec_input_frameinfo frameinfo;
5613 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005614 struct vdec_seqheader seq_header;
5615 bool port_setting_changed = true;
5616 bool not_coded_vop = false;
5617
5618 /*Should we generate a Aync error event*/
5619 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5620 {
5621 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5622 return OMX_ErrorBadParameter;
5623 }
5624
5625 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5626
5627 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5628 {
5629 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5630 nPortIndex);
5631 return OMX_ErrorBadParameter;
5632 }
5633
5634 pending_input_buffers++;
5635
5636 /* return zero length and not an EOS buffer */
5637 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5638 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5639 {
5640 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5641 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5642 OMX_COMPONENT_GENERATE_EBD);
5643 return OMX_ErrorNone;
5644 }
5645
5646
5647 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5648 mp4StreamType psBits;
5649 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5650 psBits.numBytes = buffer->nFilledLen;
5651 mp4_headerparser.parseHeader(&psBits);
5652 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5653 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5654 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005655 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005656 buffer->nFilledLen,frame_count);
5657 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5658 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5659 not_coded_vop = false;
5660 buffer->nFilledLen = 0;
5661 }
5662 }
5663 }
5664
5665 if(input_flush_progress == true
5666
5667 || not_coded_vop
5668
5669 )
5670 {
5671 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5672 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5673 OMX_COMPONENT_GENERATE_EBD);
5674 return OMX_ErrorNone;
5675 }
5676
5677 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5678
5679 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5680 {
5681 return OMX_ErrorBadParameter;
5682 }
5683
5684 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5685 /*for use buffer we need to memcpy the data*/
5686 temp_buffer->buffer_len = buffer->nFilledLen;
5687
5688 if (input_use_buffer)
5689 {
5690 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5691 {
5692 if(arbitrary_bytes)
5693 {
5694 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5695 }
5696 else
5697 {
5698 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5699 buffer->nFilledLen);
5700 }
5701 }
5702 else
5703 {
5704 return OMX_ErrorBadParameter;
5705 }
5706
5707 }
5708
5709 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5710 frameinfo.client_data = (void *) buffer;
5711 frameinfo.datalen = temp_buffer->buffer_len;
5712 frameinfo.flags = 0;
5713 frameinfo.offset = buffer->nOffset;
5714 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5715 frameinfo.pmem_offset = temp_buffer->offset;
5716 frameinfo.timestamp = buffer->nTimeStamp;
5717 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5718 {
5719 DEBUG_PRINT_LOW("ETB: dmx enabled");
5720 if (m_demux_entries == 0)
5721 {
5722 extract_demux_addr_offsets(buffer);
5723 }
5724
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005725 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005726 handle_demux_data(buffer);
5727 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5728 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5729 }
5730 else
5731 {
5732 frameinfo.desc_addr = NULL;
5733 frameinfo.desc_size = 0;
5734 }
5735 if(!arbitrary_bytes)
5736 {
5737 frameinfo.flags |= buffer->nFlags;
5738 }
5739
5740#ifdef _ANDROID_
5741 if (m_debug_timestamp)
5742 {
5743 if(arbitrary_bytes)
5744 {
5745 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5746 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5747 }
5748 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5749 {
5750 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5751 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5752 }
5753 }
5754#endif
5755
5756#ifdef INPUT_BUFFER_LOG
5757 if (inputBufferFile1)
5758 {
5759 fwrite((const char *)temp_buffer->bufferaddr,
5760 temp_buffer->buffer_len,1,inputBufferFile1);
5761 }
5762#endif
5763
5764 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5765 {
5766 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5767 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5768 }
5769
5770 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5771 {
5772 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5773 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5774 h264_scratch.nFilledLen = 0;
5775 nal_count = 0;
5776 look_ahead_nal = false;
5777 frame_count = 0;
5778 if (m_frame_parser.mutils)
5779 m_frame_parser.mutils->initialize_frame_checking_environment();
5780 m_frame_parser.flush();
5781 h264_last_au_ts = LLONG_MAX;
5782 h264_last_au_flags = 0;
5783 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5784 m_demux_entries = 0;
5785 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005786 struct v4l2_buffer buf;
5787 struct v4l2_plane plane;
5788 memset( (void *)&buf, 0, sizeof(buf));
5789 memset( (void *)&plane, 0, sizeof(plane));
5790 int rc;
5791 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5793 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005794 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795 }
5796 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5797 buf.index = nPortIndex;
5798 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5799 buf.memory = V4L2_MEMORY_USERPTR;
5800 plane.bytesused = temp_buffer->buffer_len;
5801 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005802 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5803 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005804 plane.reserved[0] = temp_buffer->pmem_fd;
5805 plane.reserved[1] = temp_buffer->offset;
5806 plane.data_offset = 0;
5807 buf.m.planes = &plane;
5808 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005809 if (frameinfo.timestamp >= LLONG_MAX) {
5810 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5811 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005812 //assumption is that timestamp is in milliseconds
5813 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5814 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005815 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5816
Shalaj Jain273b3e02012-06-22 19:08:03 -07005817 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005818 if(rc)
5819 {
5820 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5821 return OMX_ErrorHardware;
5822 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005823 if(!streaming[OUTPUT_PORT])
5824 {
5825 enum v4l2_buf_type buf_type;
5826 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005827
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5829 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5830 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5831 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005832 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005833 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834 } else{
5835 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005836 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005837 }
5838}
5839 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5840 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5841 time_stamp_dts.insert_timestamp(buffer);
5842
5843 return ret;
5844}
5845
5846/* ======================================================================
5847FUNCTION
5848 omx_vdec::FillThisBuffer
5849
5850DESCRIPTION
5851 IL client uses this method to release the frame buffer
5852 after displaying them.
5853
5854PARAMETERS
5855 None.
5856
5857RETURN VALUE
5858 true/false
5859
5860========================================================================== */
5861OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5862 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5863{
5864
5865 if(m_state == OMX_StateInvalid)
5866 {
5867 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5868 return OMX_ErrorInvalidState;
5869 }
5870
5871 if (!m_out_bEnabled)
5872 {
5873 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5874 return OMX_ErrorIncorrectStateOperation;
5875 }
5876
Vinay Kaliada4f4422013-01-09 10:45:03 -08005877 if (buffer == NULL ||
5878 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005879 {
5880 return OMX_ErrorBadParameter;
5881 }
5882
5883 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5884 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005885 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886 return OMX_ErrorBadPortIndex;
5887 }
5888
5889 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005890 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005891 return OMX_ErrorNone;
5892}
5893/* ======================================================================
5894FUNCTION
5895 omx_vdec::fill_this_buffer_proxy
5896
5897DESCRIPTION
5898 IL client uses this method to release the frame buffer
5899 after displaying them.
5900
5901PARAMETERS
5902 None.
5903
5904RETURN VALUE
5905 true/false
5906
5907========================================================================== */
5908OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5909 OMX_IN OMX_HANDLETYPE hComp,
5910 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5911{
5912 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5914 unsigned nPortIndex = 0;
5915 struct vdec_fillbuffer_cmd fillbuffer;
5916 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5917 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5918
Vinay Kaliada4f4422013-01-09 10:45:03 -08005919 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005920
Vinay Kaliada4f4422013-01-09 10:45:03 -08005921 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922 return OMX_ErrorBadParameter;
5923
5924 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5925 bufferAdd, bufferAdd->pBuffer);
5926 /*Return back the output buffer to client*/
5927 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5928 {
5929 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5930 buffer->nFilledLen = 0;
5931 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5932 return OMX_ErrorNone;
5933 }
5934 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005935 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005936 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5937 if (ptr_respbuffer)
5938 {
5939 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5940 }
5941
5942 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5943 {
5944 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5945 buffer->nFilledLen = 0;
5946 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5947 pending_output_buffers--;
5948 return OMX_ErrorBadParameter;
5949 }
5950
Shalaj Jain286b0062013-02-21 20:35:48 -08005951 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08005953 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005954
5955#ifdef _ANDROID_ICS_
5956 if (m_enable_android_native_buffers)
5957 {
5958 // Acquire a write lock on this buffer.
5959 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5960 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5961 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5962 buffer->nFilledLen = 0;
5963 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5964 pending_output_buffers--;
5965 return OMX_ErrorInsufficientResources;
5966 } else {
5967 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5968 }
5969 }
5970#endif
5971 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08005972 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005973 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08005974 memset( (void *)&buf, 0, sizeof(buf));
5975 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005976 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005977
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005978 buf.index = nPortIndex;
5979 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5980 buf.memory = V4L2_MEMORY_USERPTR;
5981 plane[0].bytesused = buffer->nFilledLen;
5982 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005983 plane[0].m.userptr =
5984 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5985 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005986 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5987 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5988 plane[0].data_offset = 0;
5989 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5990 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5991 plane[extra_idx].bytesused = 0;
5992 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5993 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5994#ifdef USE_ION
5995 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5996#endif
5997 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5998 plane[extra_idx].data_offset = 0;
5999 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6000 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6001 return OMX_ErrorBadParameter;
6002 }
6003 buf.m.planes = plane;
6004 buf.length = drv_ctx.num_planes;
6005 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6006 if (rc) {
6007 /*TODO: How to handle this case */
6008 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6009 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010//#ifdef _ANDROID_ICS_
6011 // if (m_enable_android_native_buffers)
6012 // {
6013 // Unlock the buffer
6014 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6015 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6016 // return OMX_ErrorInsufficientResources;
6017 /// } else {
6018 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6019 // }
6020 // }
6021//#endif
6022 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6023 // pending_output_buffers--;
6024 // return OMX_ErrorBadParameter;
6025 //}
6026 return OMX_ErrorNone;
6027}
6028
6029/* ======================================================================
6030FUNCTION
6031 omx_vdec::SetCallbacks
6032
6033DESCRIPTION
6034 Set the callbacks.
6035
6036PARAMETERS
6037 None.
6038
6039RETURN VALUE
6040 OMX Error None if everything successful.
6041
6042========================================================================== */
6043OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6044 OMX_IN OMX_CALLBACKTYPE* callbacks,
6045 OMX_IN OMX_PTR appData)
6046{
6047
6048 m_cb = *callbacks;
6049 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6050 m_cb.EventHandler,m_cb.FillBufferDone);
6051 m_app_data = appData;
6052 return OMX_ErrorNotImplemented;
6053}
6054
6055/* ======================================================================
6056FUNCTION
6057 omx_vdec::ComponentDeInit
6058
6059DESCRIPTION
6060 Destroys the component and release memory allocated to the heap.
6061
6062PARAMETERS
6063 <TBD>.
6064
6065RETURN VALUE
6066 OMX Error None if everything successful.
6067
6068========================================================================== */
6069OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6070{
6071#ifdef _ANDROID_
6072 if(iDivXDrmDecrypt)
6073 {
6074 delete iDivXDrmDecrypt;
6075 iDivXDrmDecrypt=NULL;
6076 }
6077#endif //_ANDROID_
6078
Shalaj Jain286b0062013-02-21 20:35:48 -08006079 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006080 if (OMX_StateLoaded != m_state)
6081 {
6082 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6083 m_state);
6084 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6085 }
6086 else
6087 {
6088 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6089 }
6090
6091 /*Check if the output buffers have to be cleaned up*/
6092 if(m_out_mem_ptr)
6093 {
6094 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006095 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096 {
6097 free_output_buffer (&m_out_mem_ptr[i]);
6098#ifdef _ANDROID_ICS_
6099 if (m_enable_android_native_buffers)
6100 {
6101 if (native_buffer[i].inuse)
6102 {
6103 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6104 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6105 }
6106 native_buffer[i].inuse = false;
6107 }
6108 }
6109#endif
6110 }
6111#ifdef _ANDROID_ICS_
6112 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6113#endif
6114 }
6115
6116 /*Check if the input buffers have to be cleaned up*/
6117 if(m_inp_mem_ptr || m_inp_heap_ptr)
6118 {
6119 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006120 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006121 {
6122 if (m_inp_mem_ptr)
6123 free_input_buffer (i,&m_inp_mem_ptr[i]);
6124 else
6125 free_input_buffer (i,NULL);
6126 }
6127 }
6128 free_input_buffer_header();
6129 free_output_buffer_header();
6130 if(h264_scratch.pBuffer)
6131 {
6132 free(h264_scratch.pBuffer);
6133 h264_scratch.pBuffer = NULL;
6134 }
6135
6136 if (h264_parser)
6137 {
6138 delete h264_parser;
6139 h264_parser = NULL;
6140 }
6141
6142 if(m_platform_list)
6143 {
6144 free(m_platform_list);
6145 m_platform_list = NULL;
6146 }
6147 if(m_vendor_config.pData)
6148 {
6149 free(m_vendor_config.pData);
6150 m_vendor_config.pData = NULL;
6151 }
6152
6153 // Reset counters in mesg queues
6154 m_ftb_q.m_size=0;
6155 m_cmd_q.m_size=0;
6156 m_etb_q.m_size=0;
6157 m_ftb_q.m_read = m_ftb_q.m_write =0;
6158 m_cmd_q.m_read = m_cmd_q.m_write =0;
6159 m_etb_q.m_read = m_etb_q.m_write =0;
6160#ifdef _ANDROID_
6161 if (m_debug_timestamp)
6162 {
6163 m_timestamp_list.reset_ts_list();
6164 }
6165#endif
6166
6167 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6168 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6169 // NULL);
6170 DEBUG_PRINT_HIGH("\n Close the driver instance");
6171
6172#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006173 if (inputBufferFile1)
6174 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006175#endif
6176#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006177 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006178 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006179#endif
6180#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006181 if (outputExtradataFile)
6182 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183#endif
6184 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6185 return OMX_ErrorNone;
6186}
6187
6188/* ======================================================================
6189FUNCTION
6190 omx_vdec::UseEGLImage
6191
6192DESCRIPTION
6193 OMX Use EGL Image method implementation <TBD>.
6194
6195PARAMETERS
6196 <TBD>.
6197
6198RETURN VALUE
6199 Not Implemented error.
6200
6201========================================================================== */
6202OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6203 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6204 OMX_IN OMX_U32 port,
6205 OMX_IN OMX_PTR appData,
6206 OMX_IN void* eglImage)
6207{
6208 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6209 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6210 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6211
6212#ifdef USE_EGL_IMAGE_GPU
6213 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6214 EGLint fd = -1, offset = 0,pmemPtr = 0;
6215#else
6216 int fd = -1, offset = 0;
6217#endif
6218 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6219 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6220 DEBUG_PRINT_ERROR("\n ");
6221 }
6222#ifdef USE_EGL_IMAGE_GPU
6223 if(m_display_id == NULL) {
6224 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6225 return OMX_ErrorInsufficientResources;
6226 }
6227 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6228 eglGetProcAddress("eglQueryImageKHR");
6229 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6230 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6231 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6232#else //with OMX test app
6233 struct temp_egl {
6234 int pmem_fd;
6235 int offset;
6236 };
6237 struct temp_egl *temp_egl_id = NULL;
6238 void * pmemPtr = (void *) eglImage;
6239 temp_egl_id = (struct temp_egl *)eglImage;
6240 if (temp_egl_id != NULL)
6241 {
6242 fd = temp_egl_id->pmem_fd;
6243 offset = temp_egl_id->offset;
6244 }
6245#endif
6246 if (fd < 0) {
6247 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6248 return OMX_ErrorInsufficientResources;
6249 }
6250 pmem_info.pmem_fd = (OMX_U32) fd;
6251 pmem_info.offset = (OMX_U32) offset;
6252 pmem_entry.entry = (void *) &pmem_info;
6253 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6254 pmem_list.entryList = &pmem_entry;
6255 pmem_list.nEntries = 1;
6256 ouput_egl_buffers = true;
6257 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6258 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6259 (OMX_U8 *)pmemPtr)) {
6260 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6261 return OMX_ErrorInsufficientResources;
6262 }
6263 return OMX_ErrorNone;
6264}
6265
6266/* ======================================================================
6267FUNCTION
6268 omx_vdec::ComponentRoleEnum
6269
6270DESCRIPTION
6271 OMX Component Role Enum method implementation.
6272
6273PARAMETERS
6274 <TBD>.
6275
6276RETURN VALUE
6277 OMX Error None if everything is successful.
6278========================================================================== */
6279OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6280 OMX_OUT OMX_U8* role,
6281 OMX_IN OMX_U32 index)
6282{
6283 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6284
6285 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6286 {
6287 if((0 == index) && role)
6288 {
6289 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6290 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6291 }
6292 else
6293 {
6294 eRet = OMX_ErrorNoMore;
6295 }
6296 }
6297 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6298 {
6299 if((0 == index) && role)
6300 {
6301 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6302 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6303 }
6304 else
6305 {
6306 eRet = OMX_ErrorNoMore;
6307 }
6308 }
6309 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6310 {
6311 if((0 == index) && role)
6312 {
6313 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6314 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6315 }
6316 else
6317 {
6318 DEBUG_PRINT_LOW("\n No more roles \n");
6319 eRet = OMX_ErrorNoMore;
6320 }
6321 }
6322
6323 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6324 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6325 )
6326
6327 {
6328 if((0 == index) && role)
6329 {
6330 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6331 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6332 }
6333 else
6334 {
6335 DEBUG_PRINT_LOW("\n No more roles \n");
6336 eRet = OMX_ErrorNoMore;
6337 }
6338 }
6339 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6340 {
6341 if((0 == index) && role)
6342 {
6343 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6344 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6345 }
6346 else
6347 {
6348 DEBUG_PRINT_LOW("\n No more roles \n");
6349 eRet = OMX_ErrorNoMore;
6350 }
6351 }
6352 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6353 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6354 )
6355 {
6356 if((0 == index) && role)
6357 {
6358 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6359 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6360 }
6361 else
6362 {
6363 DEBUG_PRINT_LOW("\n No more roles \n");
6364 eRet = OMX_ErrorNoMore;
6365 }
6366 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006367 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6368 {
6369 if((0 == index) && role)
6370 {
6371 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6372 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6373 }
6374 else
6375 {
6376 DEBUG_PRINT_LOW("\n No more roles \n");
6377 eRet = OMX_ErrorNoMore;
6378 }
6379 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006380 else
6381 {
6382 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6383 eRet = OMX_ErrorInvalidComponentName;
6384 }
6385 return eRet;
6386}
6387
6388
6389
6390
6391/* ======================================================================
6392FUNCTION
6393 omx_vdec::AllocateDone
6394
6395DESCRIPTION
6396 Checks if entire buffer pool is allocated by IL Client or not.
6397 Need this to move to IDLE state.
6398
6399PARAMETERS
6400 None.
6401
6402RETURN VALUE
6403 true/false.
6404
6405========================================================================== */
6406bool omx_vdec::allocate_done(void)
6407{
6408 bool bRet = false;
6409 bool bRet_In = false;
6410 bool bRet_Out = false;
6411
6412 bRet_In = allocate_input_done();
6413 bRet_Out = allocate_output_done();
6414
6415 if(bRet_In && bRet_Out)
6416 {
6417 bRet = true;
6418 }
6419
6420 return bRet;
6421}
6422/* ======================================================================
6423FUNCTION
6424 omx_vdec::AllocateInputDone
6425
6426DESCRIPTION
6427 Checks if I/P buffer pool is allocated by IL Client or not.
6428
6429PARAMETERS
6430 None.
6431
6432RETURN VALUE
6433 true/false.
6434
6435========================================================================== */
6436bool omx_vdec::allocate_input_done(void)
6437{
6438 bool bRet = false;
6439 unsigned i=0;
6440
6441 if (m_inp_mem_ptr == NULL)
6442 {
6443 return bRet;
6444 }
6445 if(m_inp_mem_ptr )
6446 {
6447 for(;i<drv_ctx.ip_buf.actualcount;i++)
6448 {
6449 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6450 {
6451 break;
6452 }
6453 }
6454 }
6455 if(i == drv_ctx.ip_buf.actualcount)
6456 {
6457 bRet = true;
6458 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6459 }
6460 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6461 {
6462 m_inp_bPopulated = OMX_TRUE;
6463 }
6464 return bRet;
6465}
6466/* ======================================================================
6467FUNCTION
6468 omx_vdec::AllocateOutputDone
6469
6470DESCRIPTION
6471 Checks if entire O/P buffer pool is allocated by IL Client or not.
6472
6473PARAMETERS
6474 None.
6475
6476RETURN VALUE
6477 true/false.
6478
6479========================================================================== */
6480bool omx_vdec::allocate_output_done(void)
6481{
6482 bool bRet = false;
6483 unsigned j=0;
6484
6485 if (m_out_mem_ptr == NULL)
6486 {
6487 return bRet;
6488 }
6489
6490 if (m_out_mem_ptr)
6491 {
6492 for(;j < drv_ctx.op_buf.actualcount;j++)
6493 {
6494 if(BITMASK_ABSENT(&m_out_bm_count,j))
6495 {
6496 break;
6497 }
6498 }
6499 }
6500
6501 if(j == drv_ctx.op_buf.actualcount)
6502 {
6503 bRet = true;
6504 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6505 if(m_out_bEnabled)
6506 m_out_bPopulated = OMX_TRUE;
6507 }
6508
6509 return bRet;
6510}
6511
6512/* ======================================================================
6513FUNCTION
6514 omx_vdec::ReleaseDone
6515
6516DESCRIPTION
6517 Checks if IL client has released all the buffers.
6518
6519PARAMETERS
6520 None.
6521
6522RETURN VALUE
6523 true/false
6524
6525========================================================================== */
6526bool omx_vdec::release_done(void)
6527{
6528 bool bRet = false;
6529
6530 if(release_input_done())
6531 {
6532 if(release_output_done())
6533 {
6534 bRet = true;
6535 }
6536 }
6537 return bRet;
6538}
6539
6540
6541/* ======================================================================
6542FUNCTION
6543 omx_vdec::ReleaseOutputDone
6544
6545DESCRIPTION
6546 Checks if IL client has released all the buffers.
6547
6548PARAMETERS
6549 None.
6550
6551RETURN VALUE
6552 true/false
6553
6554========================================================================== */
6555bool omx_vdec::release_output_done(void)
6556{
6557 bool bRet = false;
6558 unsigned i=0,j=0;
6559
6560 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6561 if(m_out_mem_ptr)
6562 {
6563 for(;j < drv_ctx.op_buf.actualcount ; j++)
6564 {
6565 if(BITMASK_PRESENT(&m_out_bm_count,j))
6566 {
6567 break;
6568 }
6569 }
6570 if(j == drv_ctx.op_buf.actualcount)
6571 {
6572 m_out_bm_count = 0;
6573 bRet = true;
6574 }
6575 }
6576 else
6577 {
6578 m_out_bm_count = 0;
6579 bRet = true;
6580 }
6581 return bRet;
6582}
6583/* ======================================================================
6584FUNCTION
6585 omx_vdec::ReleaseInputDone
6586
6587DESCRIPTION
6588 Checks if IL client has released all the buffers.
6589
6590PARAMETERS
6591 None.
6592
6593RETURN VALUE
6594 true/false
6595
6596========================================================================== */
6597bool omx_vdec::release_input_done(void)
6598{
6599 bool bRet = false;
6600 unsigned i=0,j=0;
6601
6602 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6603 if(m_inp_mem_ptr)
6604 {
6605 for(;j<drv_ctx.ip_buf.actualcount;j++)
6606 {
6607 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6608 {
6609 break;
6610 }
6611 }
6612 if(j==drv_ctx.ip_buf.actualcount)
6613 {
6614 bRet = true;
6615 }
6616 }
6617 else
6618 {
6619 bRet = true;
6620 }
6621 return bRet;
6622}
6623
6624OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6625 OMX_BUFFERHEADERTYPE * buffer)
6626{
6627 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6628 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6629 {
6630 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6631 return OMX_ErrorBadParameter;
6632 }
6633 else if (output_flush_progress)
6634 {
6635 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6636 buffer->nFilledLen = 0;
6637 buffer->nTimeStamp = 0;
6638 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6639 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6640 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6641 }
6642
6643 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6644 buffer, buffer->pBuffer);
6645 pending_output_buffers --;
6646
6647 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6648 {
6649 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6650 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006651 post_event((unsigned)NULL, (unsigned)NULL,
6652 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006653
6654 if (psource_frame)
6655 {
6656 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6657 psource_frame = NULL;
6658 }
6659 if (pdest_frame)
6660 {
6661 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006662 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6663 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006664 pdest_frame = NULL;
6665 }
6666 }
6667
6668 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6669#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006670 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006671 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006672 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006673 int stride = drv_ctx.video_resolution.stride;
6674 int scanlines = drv_ctx.video_resolution.scan_lines;
6675 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006676 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006677 int bytes_written = 0;
6678 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6679 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6680 temp += stride;
6681 }
6682 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006683 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006684 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6685 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6686 temp += stride_c;
6687 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006688 }
6689#endif
6690
6691 /* For use buffer we need to copy the data */
6692 if (!output_flush_progress)
6693 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006694 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006695 bool is_duplicate_ts_valid = true;
6696 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6697 output_capability == V4L2_PIX_FMT_DIVX ||
6698 output_capability == V4L2_PIX_FMT_DIVX_311)
6699 is_duplicate_ts_valid = false;
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006700 if (buffer->nFilledLen > 0)
6701 time_stamp_dts.get_next_timestamp(buffer,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006702 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6703 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006704 else {
6705 m_inp_err_count++;
6706 time_stamp_dts.remove_time_stamp(
6707 buffer->nTimeStamp,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006708 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6709 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006710 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006711 if (m_debug_timestamp)
6712 {
6713 {
6714 OMX_TICKS expected_ts = 0;
6715 m_timestamp_list.pop_min_ts(expected_ts);
6716 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6717 buffer->nTimeStamp, expected_ts);
6718
6719 if (buffer->nTimeStamp != expected_ts)
6720 {
6721 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6722 }
6723 }
6724 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006725 }
6726 if (m_cb.FillBufferDone)
6727 {
6728 if (buffer->nFilledLen > 0)
6729 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006730 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006731 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6732 // Keep min timestamp interval to handle corrupted bit stream scenario
6733 set_frame_rate(buffer->nTimeStamp);
6734 else if (arbitrary_bytes)
6735 adjust_timestamp(buffer->nTimeStamp);
6736 if (perf_flag)
6737 {
6738 if (!proc_frms)
6739 {
6740 dec_time.stop();
6741 latency = dec_time.processing_time_us() - latency;
6742 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6743 dec_time.start();
6744 fps_metrics.start();
6745 }
6746 proc_frms++;
6747 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6748 {
6749 OMX_U64 proc_time = 0;
6750 fps_metrics.stop();
6751 proc_time = fps_metrics.processing_time_us();
6752 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6753 proc_frms, (float)proc_time / 1e6,
6754 (float)(1e6 * proc_frms) / proc_time);
6755 proc_frms = 0;
6756 }
6757 }
6758
6759#ifdef OUTPUT_EXTRADATA_LOG
6760 if (outputExtradataFile)
6761 {
6762
6763 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6764 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6765 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6766 buffer->nFilledLen + 3)&(~3));
6767 while(p_extra &&
6768 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6769 {
6770 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6771 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6772 if (p_extra->eType == OMX_ExtraDataNone)
6773 {
6774 break;
6775 }
6776 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6777 }
6778 }
6779#endif
6780 }
6781 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6782 prev_ts = LLONG_MAX;
6783 rst_prev_ts = true;
6784 }
6785
6786 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6787 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6788 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006789 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006790#ifdef _ANDROID_ICS_
6791 if (m_enable_android_native_buffers)
6792 {
6793 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6794 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6795 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6796 return OMX_ErrorInsufficientResources;
6797 }
6798 else {
6799 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6800 }
6801 }
6802 }
6803#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006804 OMX_BUFFERHEADERTYPE *il_buffer;
6805 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6806 if (il_buffer)
6807 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6808 else {
6809 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6810 return OMX_ErrorBadParameter;
6811 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006812 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006813 }
6814 else
6815 {
6816 return OMX_ErrorBadParameter;
6817 }
6818
6819 return OMX_ErrorNone;
6820}
6821
6822OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6823 OMX_BUFFERHEADERTYPE* buffer)
6824{
6825
6826 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6827 {
6828 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6829 return OMX_ErrorBadParameter;
6830 }
6831
6832 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6833 buffer, buffer->pBuffer);
6834 pending_input_buffers--;
6835
6836 if (arbitrary_bytes)
6837 {
6838 if (pdest_frame == NULL && input_flush_progress == false)
6839 {
6840 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6841 pdest_frame = buffer;
6842 buffer->nFilledLen = 0;
6843 buffer->nTimeStamp = LLONG_MAX;
6844 push_input_buffer (hComp);
6845 }
6846 else
6847 {
6848 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6849 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006850 if (!m_input_free_q.insert_entry((unsigned)buffer,
6851 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006852 {
6853 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6854 }
6855 }
6856 }
6857 else if(m_cb.EmptyBufferDone)
6858 {
6859 buffer->nFilledLen = 0;
6860 if (input_use_buffer == true){
6861 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6862 }
6863 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6864 }
6865 return OMX_ErrorNone;
6866}
6867
Shalaj Jain273b3e02012-06-22 19:08:03 -07006868int omx_vdec::async_message_process (void *context, void* message)
6869{
6870 omx_vdec* omx = NULL;
6871 struct vdec_msginfo *vdec_msg = NULL;
6872 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006873 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006874 struct vdec_output_frameinfo *output_respbuf = NULL;
6875 int rc=1;
6876 if (context == NULL || message == NULL)
6877 {
6878 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6879 return -1;
6880 }
6881 vdec_msg = (struct vdec_msginfo *)message;
6882
6883 omx = reinterpret_cast<omx_vdec*>(context);
6884
Shalaj Jain273b3e02012-06-22 19:08:03 -07006885 switch (vdec_msg->msgcode)
6886 {
6887
6888 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006889 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006890 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6891 break;
6892
6893 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006894 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006895 OMX_COMPONENT_GENERATE_START_DONE);
6896 break;
6897
6898 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006899 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900 OMX_COMPONENT_GENERATE_STOP_DONE);
6901 break;
6902
6903 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006904 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006905 OMX_COMPONENT_GENERATE_RESUME_DONE);
6906 break;
6907
6908 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006909 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006910 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6911 break;
6912
6913 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006914 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006915 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6916 break;
6917 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006918 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006919 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6920 break;
6921 case VDEC_MSG_RESP_INPUT_FLUSHED:
6922 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6923
Shalaj Jain286b0062013-02-21 20:35:48 -08006924 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6925 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006926
6927 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6928 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6929 if (omxhdr == NULL ||
6930 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6931 {
6932 omxhdr = NULL;
6933 vdec_msg->status_code = VDEC_S_EFATAL;
6934 }
6935
6936 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6937 OMX_COMPONENT_GENERATE_EBD);
6938 break;
6939 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6940 int64_t *timestamp;
6941 timestamp = (int64_t *) malloc(sizeof(int64_t));
6942 if (timestamp) {
6943 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6944 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6945 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6946 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6947 vdec_msg->msgdata.output_frame.time_stamp);
6948 }
6949 break;
6950 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6951 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6952
6953 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6954 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6955 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6956 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6957 vdec_msg->msgdata.output_frame.pic_type);
6958
6959 if (omxhdr && omxhdr->pOutputPortPrivate &&
6960 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6961 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6962 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6963 {
6964 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6965 {
6966 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6967 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006968 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006969 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6970
6971 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6972 {
6973 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6974 //rc = -1;
6975 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006976 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6977 {
6978 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6979 }
Shalaj Jain286b0062013-02-21 20:35:48 -08006980 vdec_msg->msgdata.output_frame.bufferaddr =
6981 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6982 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6983 vdec_msg->msgdata.output_frame.framesize.left)
6984 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08006985 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6986 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6987 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6988 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6989 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6990 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6991 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
6992 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6993 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6994 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006995 output_respbuf = (struct vdec_output_frameinfo *)\
6996 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006997 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6998 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006999 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7000 {
7001 output_respbuf->pic_type = PICTURE_TYPE_I;
7002 }
7003 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7004 {
7005 output_respbuf->pic_type = PICTURE_TYPE_P;
7006 }
7007 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7008 output_respbuf->pic_type = PICTURE_TYPE_B;
7009 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007010
7011 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007012 memcpy ( omxhdr->pBuffer, (void *)
7013 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7014 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7015 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007016 }
7017 else
7018 omxhdr->nFilledLen = 0;
7019 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7020 OMX_COMPONENT_GENERATE_FBD);
7021 }
7022 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007023 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 OMX_COMPONENT_GENERATE_EOS_DONE);
7025 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007026 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007027 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7028 break;
7029 case VDEC_MSG_EVT_CONFIG_CHANGED:
7030 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007031 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7032 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007033 break;
7034 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
7035 {
7036 DEBUG_PRINT_HIGH("\n Port settings changed info");
7037 // get_buffer_req and populate port defn structure
7038 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07007039 struct v4l2_format fmt;
7040 int ret;
7041 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7042 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
Vinay Kalia21649b32013-03-18 17:28:07 -07007043 omx->update_resolution(fmt.fmt.pix_mp.width,
7044 fmt.fmt.pix_mp.height,
7045 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7046 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Arun Menon6836ba02013-02-19 20:37:40 -08007047 ret = omx->is_video_session_supported();
7048 if (ret) {
7049 omx->post_event (NULL, vdec_msg->status_code,
7050 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7051 }
7052 else {
7053 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
7054 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
7055 omx->m_port_def.nPortIndex = 1;
7056 eRet = omx->update_portdef(&(omx->m_port_def));
7057 omx->post_event ((unsigned)NULL,vdec_msg->status_code,\
7058 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
7059 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007060 break;
7061 }
7062 default:
7063 break;
7064 }
7065 return rc;
7066}
7067
7068OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7069 OMX_HANDLETYPE hComp,
7070 OMX_BUFFERHEADERTYPE *buffer
7071 )
7072{
7073 unsigned address,p2,id;
7074 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7075
7076 if (buffer == NULL)
7077 {
7078 return OMX_ErrorBadParameter;
7079 }
7080 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007081 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7082 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007083
7084 /* return zero length and not an EOS buffer */
7085 /* return buffer if input flush in progress */
7086 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7087 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7088 {
7089 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7090 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7091 return OMX_ErrorNone;
7092 }
7093
7094 if (psource_frame == NULL)
7095 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007096 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007097 psource_frame = buffer;
7098 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7099 push_input_buffer (hComp);
7100 }
7101 else
7102 {
7103 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007104 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7105 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007106 {
7107 return OMX_ErrorBadParameter;
7108 }
7109 }
7110
7111
7112 return OMX_ErrorNone;
7113}
7114
7115OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7116{
7117 unsigned address,p2,id;
7118 OMX_ERRORTYPE ret = OMX_ErrorNone;
7119
7120 if (pdest_frame == NULL || psource_frame == NULL)
7121 {
7122 /*Check if we have a destination buffer*/
7123 if (pdest_frame == NULL)
7124 {
7125 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7126 if (m_input_free_q.m_size)
7127 {
7128 m_input_free_q.pop_entry(&address,&p2,&id);
7129 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7130 pdest_frame->nFilledLen = 0;
7131 pdest_frame->nTimeStamp = LLONG_MAX;
7132 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7133 }
7134 }
7135
7136 /*Check if we have a destination buffer*/
7137 if (psource_frame == NULL)
7138 {
7139 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7140 if (m_input_pending_q.m_size)
7141 {
7142 m_input_pending_q.pop_entry(&address,&p2,&id);
7143 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007144 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007145 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007146 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007147 psource_frame->nFlags,psource_frame->nFilledLen);
7148
7149 }
7150 }
7151
7152 }
7153
7154 while ((pdest_frame != NULL) && (psource_frame != NULL))
7155 {
7156 switch (codec_type_parse)
7157 {
7158 case CODEC_TYPE_MPEG4:
7159 case CODEC_TYPE_H263:
7160 case CODEC_TYPE_MPEG2:
7161 ret = push_input_sc_codec(hComp);
7162 break;
7163 case CODEC_TYPE_H264:
7164 ret = push_input_h264(hComp);
7165 break;
7166 case CODEC_TYPE_VC1:
7167 ret = push_input_vc1(hComp);
7168 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007169 default:
7170 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007171 }
7172 if (ret != OMX_ErrorNone)
7173 {
7174 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7175 omx_report_error ();
7176 break;
7177 }
7178 }
7179
7180 return ret;
7181}
7182
7183OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7184{
7185 OMX_U32 partial_frame = 1;
7186 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007187 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007188
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007189 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007190 psource_frame,psource_frame->nTimeStamp);
7191 if (m_frame_parser.parse_sc_frame(psource_frame,
7192 pdest_frame,&partial_frame) == -1)
7193 {
7194 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7195 return OMX_ErrorBadParameter;
7196 }
7197
7198 if (partial_frame == 0)
7199 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007200 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007201 pdest_frame->nFilledLen,psource_frame,frame_count);
7202
7203
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007204 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007205 /*First Parsed buffer will have only header Hence skip*/
7206 if (frame_count == 0)
7207 {
7208 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7209
7210 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7211 codec_type_parse == CODEC_TYPE_DIVX) {
7212 mp4StreamType psBits;
7213 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7214 psBits.numBytes = pdest_frame->nFilledLen;
7215 mp4_headerparser.parseHeader(&psBits);
7216 }
7217
7218 frame_count++;
7219 }
7220 else
7221 {
7222 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7223 if(pdest_frame->nFilledLen)
7224 {
7225 /*Push the frame to the Decoder*/
7226 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7227 {
7228 return OMX_ErrorBadParameter;
7229 }
7230 frame_count++;
7231 pdest_frame = NULL;
7232
7233 if (m_input_free_q.m_size)
7234 {
7235 m_input_free_q.pop_entry(&address,&p2,&id);
7236 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7237 pdest_frame->nFilledLen = 0;
7238 }
7239 }
7240 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7241 {
7242 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007243 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7244 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007245 pdest_frame = NULL;
7246 }
7247 }
7248 }
7249 else
7250 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007251 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007252 /*Check if Destination Buffer is full*/
7253 if (pdest_frame->nAllocLen ==
7254 pdest_frame->nFilledLen + pdest_frame->nOffset)
7255 {
7256 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7257 return OMX_ErrorStreamCorrupt;
7258 }
7259 }
7260
7261 if (psource_frame->nFilledLen == 0)
7262 {
7263 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7264 {
7265 if (pdest_frame)
7266 {
7267 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007268 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007269 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007270 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007271 pdest_frame->nFilledLen,frame_count++);
7272 /*Push the frame to the Decoder*/
7273 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7274 {
7275 return OMX_ErrorBadParameter;
7276 }
7277 frame_count++;
7278 pdest_frame = NULL;
7279 }
7280 else
7281 {
7282 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7283 generate_ebd = OMX_FALSE;
7284 }
7285 }
7286 if(generate_ebd)
7287 {
7288 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7289 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7290 psource_frame = NULL;
7291
7292 if (m_input_pending_q.m_size)
7293 {
7294 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7295 m_input_pending_q.pop_entry(&address,&p2,&id);
7296 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007297 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007298 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007299 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007300 psource_frame->nFlags,psource_frame->nFilledLen);
7301 }
7302 }
7303 }
7304 return OMX_ErrorNone;
7305}
7306
7307OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7308{
7309 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007310 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007311 OMX_BOOL isNewFrame = OMX_FALSE;
7312 OMX_BOOL generate_ebd = OMX_TRUE;
7313
7314 if (h264_scratch.pBuffer == NULL)
7315 {
7316 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7317 return OMX_ErrorBadParameter;
7318 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007319 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007320 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007321 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007322 if (h264_scratch.nFilledLen && look_ahead_nal)
7323 {
7324 look_ahead_nal = false;
7325 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7326 h264_scratch.nFilledLen)
7327 {
7328 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7329 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7330 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7331 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7332 h264_scratch.nFilledLen = 0;
7333 }
7334 else
7335 {
7336 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7337 return OMX_ErrorBadParameter;
7338 }
7339 }
7340 if (nal_length == 0)
7341 {
7342 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7343 if (m_frame_parser.parse_sc_frame(psource_frame,
7344 &h264_scratch,&partial_frame) == -1)
7345 {
7346 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7347 return OMX_ErrorBadParameter;
7348 }
7349 }
7350 else
7351 {
7352 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7353 if (m_frame_parser.parse_h264_nallength(psource_frame,
7354 &h264_scratch,&partial_frame) == -1)
7355 {
7356 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7357 return OMX_ErrorBadParameter;
7358 }
7359 }
7360
7361 if (partial_frame == 0)
7362 {
7363 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7364 {
7365 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7366 nal_count++;
7367 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7368 h264_scratch.nFlags = psource_frame->nFlags;
7369 }
7370 else
7371 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007372 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007373 if(h264_scratch.nFilledLen)
7374 {
7375 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7376 NALU_TYPE_SPS);
7377#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7378 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7379 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7380 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7381 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7382 // If timeinfo is present frame info from SEI is already processed
7383 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7384 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7385#endif
7386 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7387 nal_count++;
7388 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7389 pdest_frame->nTimeStamp = h264_last_au_ts;
7390 pdest_frame->nFlags = h264_last_au_flags;
7391#ifdef PANSCAN_HDLR
7392 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7393 h264_parser->update_panscan_data(h264_last_au_ts);
7394#endif
7395 }
7396 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7397 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7398 h264_last_au_ts = h264_scratch.nTimeStamp;
7399 h264_last_au_flags = h264_scratch.nFlags;
7400#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7401 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7402 {
7403 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7404 if (!VALID_TS(h264_last_au_ts))
7405 h264_last_au_ts = ts_in_sei;
7406 }
7407#endif
7408 } else
7409 h264_last_au_ts = LLONG_MAX;
7410 }
7411
7412 if (!isNewFrame)
7413 {
7414 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7415 h264_scratch.nFilledLen)
7416 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007417 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007418 h264_scratch.nFilledLen);
7419 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7420 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7421 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7422 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7423 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7424 h264_scratch.nFilledLen = 0;
7425 }
7426 else
7427 {
7428 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7429 return OMX_ErrorBadParameter;
7430 }
7431 }
7432 else
7433 {
7434 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007435 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007436 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007437 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007438 pdest_frame->nFilledLen,frame_count++);
7439
7440 if (pdest_frame->nFilledLen == 0)
7441 {
7442 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7443 look_ahead_nal = false;
7444 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7445 h264_scratch.nFilledLen)
7446 {
7447 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7448 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7449 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7450 h264_scratch.nFilledLen = 0;
7451 }
7452 else
7453 {
7454 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7455 return OMX_ErrorBadParameter;
7456 }
7457 }
7458 else
7459 {
7460 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7461 {
7462 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7463 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7464 }
7465 /*Push the frame to the Decoder*/
7466 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7467 {
7468 return OMX_ErrorBadParameter;
7469 }
7470 //frame_count++;
7471 pdest_frame = NULL;
7472 if (m_input_free_q.m_size)
7473 {
7474 m_input_free_q.pop_entry(&address,&p2,&id);
7475 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7476 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7477 pdest_frame->nFilledLen = 0;
7478 pdest_frame->nFlags = 0;
7479 pdest_frame->nTimeStamp = LLONG_MAX;
7480 }
7481 }
7482 }
7483 }
7484 }
7485 else
7486 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007487 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 /*Check if Destination Buffer is full*/
7489 if (h264_scratch.nAllocLen ==
7490 h264_scratch.nFilledLen + h264_scratch.nOffset)
7491 {
7492 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7493 return OMX_ErrorStreamCorrupt;
7494 }
7495 }
7496
7497 if (!psource_frame->nFilledLen)
7498 {
7499 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7500
7501 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7502 {
7503 if (pdest_frame)
7504 {
7505 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7506 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7507 h264_scratch.nFilledLen)
7508 {
7509 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7510 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7511 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7512 h264_scratch.nFilledLen = 0;
7513 }
7514 else
7515 {
7516 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7517 return OMX_ErrorBadParameter;
7518 }
7519 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7520 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7521
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007522 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007523 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7524 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7525#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7526 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7527 {
7528 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7529 if (!VALID_TS(pdest_frame->nTimeStamp))
7530 pdest_frame->nTimeStamp = ts_in_sei;
7531 }
7532#endif
7533 /*Push the frame to the Decoder*/
7534 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7535 {
7536 return OMX_ErrorBadParameter;
7537 }
7538 frame_count++;
7539 pdest_frame = NULL;
7540 }
7541 else
7542 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007543 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544 pdest_frame,h264_scratch.nFilledLen);
7545 generate_ebd = OMX_FALSE;
7546 }
7547 }
7548 }
7549 if(generate_ebd && !psource_frame->nFilledLen)
7550 {
7551 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7552 psource_frame = NULL;
7553 if (m_input_pending_q.m_size)
7554 {
7555 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7556 m_input_pending_q.pop_entry(&address,&p2,&id);
7557 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007558 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007559 psource_frame->nFlags,psource_frame->nFilledLen);
7560 }
7561 }
7562 return OMX_ErrorNone;
7563}
7564
7565OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7566{
7567 OMX_U8 *buf, *pdest;
7568 OMX_U32 partial_frame = 1;
7569 OMX_U32 buf_len, dest_len;
7570
7571 if(first_frame == 0)
7572 {
7573 first_frame = 1;
7574 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7575 if(!m_vendor_config.pData)
7576 {
7577 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7578 buf = psource_frame->pBuffer;
7579 buf_len = psource_frame->nFilledLen;
7580
7581 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7582 VC1_SP_MP_START_CODE)
7583 {
7584 m_vc1_profile = VC1_SP_MP_RCV;
7585 }
7586 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7587 {
7588 m_vc1_profile = VC1_AP;
7589 }
7590 else
7591 {
7592 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7593 return OMX_ErrorStreamCorrupt;
7594 }
7595 }
7596 else
7597 {
7598 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7599 pdest_frame->nOffset;
7600 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7601 pdest_frame->nOffset);
7602
7603 if(dest_len < m_vendor_config.nDataSize)
7604 {
7605 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7606 return OMX_ErrorBadParameter;
7607 }
7608 else
7609 {
7610 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7611 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7612 }
7613 }
7614 }
7615
7616 switch(m_vc1_profile)
7617 {
7618 case VC1_AP:
7619 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7620 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7621 {
7622 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7623 return OMX_ErrorBadParameter;
7624 }
7625 break;
7626
7627 case VC1_SP_MP_RCV:
7628 default:
7629 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7630 return OMX_ErrorBadParameter;
7631 }
7632 return OMX_ErrorNone;
7633}
7634
David Ng38e2d232013-03-15 20:05:58 -07007635#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007636bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7637 OMX_U32 alignment)
7638{
7639 struct pmem_allocation allocation;
7640 allocation.size = buffer_size;
7641 allocation.align = clip2(alignment);
7642 if (allocation.align < 4096)
7643 {
7644 allocation.align = 4096;
7645 }
7646 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7647 {
7648 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7649 allocation.align, allocation.size);
7650 return false;
7651 }
7652 return true;
7653}
David Ng38e2d232013-03-15 20:05:58 -07007654#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007655#ifdef USE_ION
7656int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7657 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7658 struct ion_fd_data *fd_data, int flag)
7659{
7660 int fd = -EINVAL;
7661 int rc = -EINVAL;
7662 int ion_dev_flag;
7663 struct vdec_ion ion_buf_info;
7664 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7665 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7666 return -EINVAL;
7667 }
Arun Menon737de532012-09-14 14:48:18 -07007668 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007669 fd = open (MEM_DEVICE, ion_dev_flag);
7670 if (fd < 0) {
7671 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7672 return fd;
7673 }
Arun Menon737de532012-09-14 14:48:18 -07007674 alloc_data->flags = 0;
7675 if(!secure_mode && (flag & ION_FLAG_CACHED))
7676 {
7677 alloc_data->flags |= ION_FLAG_CACHED;
7678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007679 alloc_data->len = buffer_size;
7680 alloc_data->align = clip2(alignment);
7681 if (alloc_data->align < 4096)
7682 {
7683 alloc_data->align = 4096;
7684 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007685 if ((secure_mode) && (flag & ION_SECURE))
7686 alloc_data->flags |= ION_SECURE;
7687
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007688 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7689 if (secure_mode)
7690 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007691 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7692 if (rc || !alloc_data->handle) {
7693 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7694 alloc_data->handle = NULL;
7695 close(fd);
7696 fd = -ENOMEM;
7697 return fd;
7698 }
7699 fd_data->handle = alloc_data->handle;
7700 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7701 if (rc) {
7702 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7703 ion_buf_info.ion_alloc_data = *alloc_data;
7704 ion_buf_info.ion_device_fd = fd;
7705 ion_buf_info.fd_ion_data = *fd_data;
7706 free_ion_memory(&ion_buf_info);
7707 fd_data->fd =-1;
7708 close(fd);
7709 fd = -ENOMEM;
7710 }
7711
7712 return fd;
7713}
7714
7715void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7716
7717 if(!buf_ion_info) {
7718 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7719 return;
7720 }
7721 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7722 &buf_ion_info->ion_alloc_data.handle)) {
7723 DEBUG_PRINT_ERROR("\n ION: free failed" );
7724 }
7725 close(buf_ion_info->ion_device_fd);
7726 buf_ion_info->ion_device_fd = -1;
7727 buf_ion_info->ion_alloc_data.handle = NULL;
7728 buf_ion_info->fd_ion_data.fd = -1;
7729}
7730#endif
7731void omx_vdec::free_output_buffer_header()
7732{
7733 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7734 output_use_buffer = false;
7735 ouput_egl_buffers = false;
7736
7737 if (m_out_mem_ptr)
7738 {
7739 free (m_out_mem_ptr);
7740 m_out_mem_ptr = NULL;
7741 }
7742
7743 if(m_platform_list)
7744 {
7745 free(m_platform_list);
7746 m_platform_list = NULL;
7747 }
7748
7749 if (drv_ctx.ptr_respbuffer)
7750 {
7751 free (drv_ctx.ptr_respbuffer);
7752 drv_ctx.ptr_respbuffer = NULL;
7753 }
7754 if (drv_ctx.ptr_outputbuffer)
7755 {
7756 free (drv_ctx.ptr_outputbuffer);
7757 drv_ctx.ptr_outputbuffer = NULL;
7758 }
7759#ifdef USE_ION
7760 if (drv_ctx.op_buf_ion_info) {
7761 DEBUG_PRINT_LOW("\n Free o/p ion context");
7762 free(drv_ctx.op_buf_ion_info);
7763 drv_ctx.op_buf_ion_info = NULL;
7764 }
7765#endif
7766}
7767
7768void omx_vdec::free_input_buffer_header()
7769{
7770 input_use_buffer = false;
7771 if (arbitrary_bytes)
7772 {
7773 if (m_frame_parser.mutils)
7774 {
7775 DEBUG_PRINT_LOW("\n Free utils parser");
7776 delete (m_frame_parser.mutils);
7777 m_frame_parser.mutils = NULL;
7778 }
7779
7780 if (m_inp_heap_ptr)
7781 {
7782 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7783 free (m_inp_heap_ptr);
7784 m_inp_heap_ptr = NULL;
7785 }
7786
7787 if (m_phdr_pmem_ptr)
7788 {
7789 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7790 free (m_phdr_pmem_ptr);
7791 m_phdr_pmem_ptr = NULL;
7792 }
7793 }
7794 if (m_inp_mem_ptr)
7795 {
7796 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7797 free (m_inp_mem_ptr);
7798 m_inp_mem_ptr = NULL;
7799 }
7800 if (drv_ctx.ptr_inputbuffer)
7801 {
7802 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7803 free (drv_ctx.ptr_inputbuffer);
7804 drv_ctx.ptr_inputbuffer = NULL;
7805 }
7806#ifdef USE_ION
7807 if (drv_ctx.ip_buf_ion_info) {
7808 DEBUG_PRINT_LOW("\n Free ion context");
7809 free(drv_ctx.ip_buf_ion_info);
7810 drv_ctx.ip_buf_ion_info = NULL;
7811 }
7812#endif
7813}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007814
7815int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007816{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007817 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007818 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007819 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007820
7821 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7822 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7823 v4l2_port = OUTPUT_PORT;
7824 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7825 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7826 v4l2_port = CAPTURE_PORT;
7827 } else if (port == OMX_ALL) {
7828 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7829 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7830
7831 if (!rc_input)
7832 return rc_input;
7833 else
7834 return rc_output;
7835 }
7836
7837 if (!streaming[v4l2_port]) {
7838 // already streamed off, warn and move on
7839 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7840 " which is already streamed off", v4l2_port);
7841 return 0;
7842 }
7843
7844 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7845
Shalaj Jain273b3e02012-06-22 19:08:03 -07007846 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7847 if (rc) {
7848 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007849 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007850 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007851 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007852 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007853
7854 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007855}
7856
7857OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7858{
7859 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7860 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007861 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007862 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007863 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007864 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7865 buffer_prop->actualcount, buffer_prop->buffer_size);
7866 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007867 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007868 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7869 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7870 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7871 fmt.fmt.pix_mp.pixelformat = output_capability;
7872 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7873 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7874 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7875 fmt.fmt.pix_mp.pixelformat = capture_capability;
7876 }else {eRet = OMX_ErrorBadParameter;}
7877 if(eRet==OMX_ErrorNone){
7878 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7879 }
7880 if(ret)
7881 {
7882 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7883 /*TODO: How to handle this case */
7884 eRet = OMX_ErrorInsufficientResources;
7885 return eRet;
7886 }
7887 else
7888 {
7889 buffer_prop->actualcount = bufreq.count;
7890 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007891 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007892 }
7893 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7894 buffer_prop->actualcount, buffer_prop->buffer_size);
7895
7896 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7897 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7898
7899 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7900
Vinay Kalia21649b32013-03-18 17:28:07 -07007901 update_resolution(fmt.fmt.pix_mp.width,
7902 fmt.fmt.pix_mp.height,
7903 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7904 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007905 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7906 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007907 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007908
7909 if(ret)
7910 {
7911 /*TODO: How to handle this case */
7912 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7913 eRet = OMX_ErrorInsufficientResources;
7914 }
7915 else
7916 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007917 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08007918
7919 eRet = is_video_session_supported();
7920 if (eRet)
7921 return eRet;
7922
Shalaj Jain273b3e02012-06-22 19:08:03 -07007923 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7924 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007925 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7926 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7927 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7928 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7929 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7930 return OMX_ErrorBadParameter;
7931 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007932 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7933 {
7934 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007935 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007936 }
7937 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7938 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007939 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940 }
7941 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7942 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007943 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7944 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7945 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007946 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007947 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007948 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007949 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007950 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7951 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007952 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7953 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7954 drv_ctx.extradata_info.buffer_size = extra_data_size;
7955 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7957 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007958 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007959 if (in_reconfig) // BufReq will be set to driver when port is disabled
7960 buffer_prop->buffer_size = buf_size;
7961 else if (buf_size != buffer_prop->buffer_size)
7962 {
7963 buffer_prop->buffer_size = buf_size;
7964 eRet = set_buffer_req(buffer_prop);
7965 }
7966 }
7967 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7968 buffer_prop->actualcount, buffer_prop->buffer_size);
7969 return eRet;
7970}
7971
7972OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7973{
7974 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7975 unsigned buf_size = 0;
7976 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007977 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007978 int ret;
7979 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7980 buffer_prop->actualcount, buffer_prop->buffer_size);
7981 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7982 if (buf_size != buffer_prop->buffer_size)
7983 {
7984 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7985 buffer_prop->buffer_size, buf_size);
7986 eRet = OMX_ErrorBadParameter;
7987 }
7988 else
7989 {
7990 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7991 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007992
7993 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7994 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7995 fmt.fmt.pix_mp.pixelformat = output_capability;
7996 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7997 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7998 fmt.fmt.pix_mp.pixelformat = capture_capability;
7999 } else {eRet = OMX_ErrorBadParameter;}
8000
8001 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8002 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008003 {
8004 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008005 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008006 eRet = OMX_ErrorInsufficientResources;
8007 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008008
8009 bufreq.memory = V4L2_MEMORY_USERPTR;
8010 bufreq.count = buffer_prop->actualcount;
8011 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8012 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8013 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8014 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8015 } else {eRet = OMX_ErrorBadParameter;}
8016
8017 if (eRet==OMX_ErrorNone) {
8018 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8019 }
8020
8021 if (ret)
8022 {
8023 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8024 /*TODO: How to handle this case */
8025 eRet = OMX_ErrorInsufficientResources;
8026 } else if (bufreq.count < buffer_prop->actualcount) {
8027 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8028 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8029 buffer_prop->actualcount, bufreq.count);
8030 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008031 } else {
8032 if (!client_buffers.update_buffer_req()) {
8033 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8034 eRet = OMX_ErrorInsufficientResources;
8035 }
8036 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008037 }
8038 return eRet;
8039}
8040
Shalaj Jain273b3e02012-06-22 19:08:03 -07008041OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8042{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008043 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008044 return eRet;
8045}
8046
8047OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8048{
8049 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8050 if (!portDefn)
8051 {
8052 return OMX_ErrorBadParameter;
8053 }
8054 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8055 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8056 portDefn->nSize = sizeof(portDefn);
8057 portDefn->eDomain = OMX_PortDomainVideo;
8058 if (drv_ctx.frame_rate.fps_denominator > 0)
8059 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8060 drv_ctx.frame_rate.fps_denominator;
8061 else {
8062 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8063 return OMX_ErrorBadParameter;
8064 }
8065 if (0 == portDefn->nPortIndex)
8066 {
8067 portDefn->eDir = OMX_DirInput;
8068 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8069 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8070 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8071 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8072 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8073 portDefn->bEnabled = m_inp_bEnabled;
8074 portDefn->bPopulated = m_inp_bPopulated;
8075 }
8076 else if (1 == portDefn->nPortIndex)
8077 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008078 unsigned int buf_size = 0;
8079 if (!client_buffers.update_buffer_req()) {
8080 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8081 return OMX_ErrorHardware;
8082 }
8083 if (!client_buffers.get_buffer_req(buf_size)) {
8084 DEBUG_PRINT_ERROR("\n update buffer requirements");
8085 return OMX_ErrorHardware;
8086 }
8087 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008088 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008089 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8090 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008091 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8092 portDefn->bEnabled = m_out_bEnabled;
8093 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008094 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8095 DEBUG_PRINT_ERROR("\n Error in getting color format");
8096 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008097 }
8098 }
8099 else
8100 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008101 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008102 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8103 (int)portDefn->nPortIndex);
8104 eRet = OMX_ErrorBadPortIndex;
8105 }
8106 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8107 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8108 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8109 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008110 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8111 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008112 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008113 portDefn->format.video.nStride,
8114 portDefn->format.video.nSliceHeight);
8115 return eRet;
8116
8117}
8118
8119OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8120{
8121 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8122 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8123 unsigned i= 0;
8124
8125 if(!m_out_mem_ptr) {
8126 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8127 int nBufHdrSize = 0;
8128 int nPlatformEntrySize = 0;
8129 int nPlatformListSize = 0;
8130 int nPMEMInfoSize = 0;
8131 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8132 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8133 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8134
8135 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8136 drv_ctx.op_buf.actualcount);
8137 nBufHdrSize = drv_ctx.op_buf.actualcount *
8138 sizeof(OMX_BUFFERHEADERTYPE);
8139
8140 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8141 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8142 nPlatformListSize = drv_ctx.op_buf.actualcount *
8143 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8144 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8145 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8146
8147 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8148 sizeof(OMX_BUFFERHEADERTYPE),
8149 nPMEMInfoSize,
8150 nPlatformListSize);
8151 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8152 m_out_bm_count);
8153 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8154 // Alloc mem for platform specific info
8155 char *pPtr=NULL;
8156 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8157 nPMEMInfoSize,1);
8158 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8159 calloc (sizeof(struct vdec_bufferpayload),
8160 drv_ctx.op_buf.actualcount);
8161 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8162 calloc (sizeof (struct vdec_output_frameinfo),
8163 drv_ctx.op_buf.actualcount);
8164#ifdef USE_ION
8165 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8166 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8167#endif
8168
8169 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8170 && drv_ctx.ptr_respbuffer)
8171 {
8172 bufHdr = m_out_mem_ptr;
8173 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8174 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8175 (((char *) m_platform_list) + nPlatformListSize);
8176 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8177 (((char *) m_platform_entry) + nPlatformEntrySize);
8178 pPlatformList = m_platform_list;
8179 pPlatformEntry = m_platform_entry;
8180 pPMEMInfo = m_pmem_info;
8181
8182 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8183
8184 // Settting the entire storage nicely
8185 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8186 m_out_mem_ptr,pPlatformEntry);
8187 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8188 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8189 {
8190 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8191 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8192 // Set the values when we determine the right HxW param
8193 bufHdr->nAllocLen = 0;
8194 bufHdr->nFilledLen = 0;
8195 bufHdr->pAppPrivate = NULL;
8196 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8197 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8198 pPlatformEntry->entry = pPMEMInfo;
8199 // Initialize the Platform List
8200 pPlatformList->nEntries = 1;
8201 pPlatformList->entryList = pPlatformEntry;
8202 // Keep pBuffer NULL till vdec is opened
8203 bufHdr->pBuffer = NULL;
8204 pPMEMInfo->offset = 0;
8205 pPMEMInfo->pmem_fd = 0;
8206 bufHdr->pPlatformPrivate = pPlatformList;
8207 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8208#ifdef USE_ION
8209 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8210#endif
8211 /*Create a mapping between buffers*/
8212 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8213 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8214 &drv_ctx.ptr_outputbuffer[i];
8215 // Move the buffer and buffer header pointers
8216 bufHdr++;
8217 pPMEMInfo++;
8218 pPlatformEntry++;
8219 pPlatformList++;
8220 }
8221 }
8222 else
8223 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008224 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008225 m_out_mem_ptr, pPtr);
8226 if(m_out_mem_ptr)
8227 {
8228 free(m_out_mem_ptr);
8229 m_out_mem_ptr = NULL;
8230 }
8231 if(pPtr)
8232 {
8233 free(pPtr);
8234 pPtr = NULL;
8235 }
8236 if(drv_ctx.ptr_outputbuffer)
8237 {
8238 free(drv_ctx.ptr_outputbuffer);
8239 drv_ctx.ptr_outputbuffer = NULL;
8240 }
8241 if(drv_ctx.ptr_respbuffer)
8242 {
8243 free(drv_ctx.ptr_respbuffer);
8244 drv_ctx.ptr_respbuffer = NULL;
8245 }
8246#ifdef USE_ION
8247 if (drv_ctx.op_buf_ion_info) {
8248 DEBUG_PRINT_LOW("\n Free o/p ion context");
8249 free(drv_ctx.op_buf_ion_info);
8250 drv_ctx.op_buf_ion_info = NULL;
8251 }
8252#endif
8253 eRet = OMX_ErrorInsufficientResources;
8254 }
8255 } else {
8256 eRet = OMX_ErrorInsufficientResources;
8257 }
8258 return eRet;
8259}
8260
8261void omx_vdec::complete_pending_buffer_done_cbs()
8262{
8263 unsigned p1;
8264 unsigned p2;
8265 unsigned ident;
8266 omx_cmd_queue tmp_q, pending_bd_q;
8267 pthread_mutex_lock(&m_lock);
8268 // pop all pending GENERATE FDB from ftb queue
8269 while (m_ftb_q.m_size)
8270 {
8271 m_ftb_q.pop_entry(&p1,&p2,&ident);
8272 if(ident == OMX_COMPONENT_GENERATE_FBD)
8273 {
8274 pending_bd_q.insert_entry(p1,p2,ident);
8275 }
8276 else
8277 {
8278 tmp_q.insert_entry(p1,p2,ident);
8279 }
8280 }
8281 //return all non GENERATE FDB to ftb queue
8282 while(tmp_q.m_size)
8283 {
8284 tmp_q.pop_entry(&p1,&p2,&ident);
8285 m_ftb_q.insert_entry(p1,p2,ident);
8286 }
8287 // pop all pending GENERATE EDB from etb queue
8288 while (m_etb_q.m_size)
8289 {
8290 m_etb_q.pop_entry(&p1,&p2,&ident);
8291 if(ident == OMX_COMPONENT_GENERATE_EBD)
8292 {
8293 pending_bd_q.insert_entry(p1,p2,ident);
8294 }
8295 else
8296 {
8297 tmp_q.insert_entry(p1,p2,ident);
8298 }
8299 }
8300 //return all non GENERATE FDB to etb queue
8301 while(tmp_q.m_size)
8302 {
8303 tmp_q.pop_entry(&p1,&p2,&ident);
8304 m_etb_q.insert_entry(p1,p2,ident);
8305 }
8306 pthread_mutex_unlock(&m_lock);
8307 // process all pending buffer dones
8308 while(pending_bd_q.m_size)
8309 {
8310 pending_bd_q.pop_entry(&p1,&p2,&ident);
8311 switch(ident)
8312 {
8313 case OMX_COMPONENT_GENERATE_EBD:
8314 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8315 {
8316 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8317 omx_report_error ();
8318 }
8319 break;
8320
8321 case OMX_COMPONENT_GENERATE_FBD:
8322 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8323 {
8324 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8325 omx_report_error ();
8326 }
8327 break;
8328 }
8329 }
8330}
8331
8332void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8333{
8334 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008335 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8336 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8337 {
8338 new_frame_interval = (act_timestamp > prev_ts)?
8339 act_timestamp - prev_ts :
8340 prev_ts - act_timestamp;
8341 if (new_frame_interval < frm_int || frm_int == 0)
8342 {
8343 frm_int = new_frame_interval;
8344 if(frm_int)
8345 {
8346 drv_ctx.frame_rate.fps_numerator = 1e6;
8347 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008348 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008349 frm_int, drv_ctx.frame_rate.fps_numerator /
8350 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07008351 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008352 }
8353 }
8354 }
8355 prev_ts = act_timestamp;
8356}
8357
8358void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8359{
8360 if (rst_prev_ts && VALID_TS(act_timestamp))
8361 {
8362 prev_ts = act_timestamp;
8363 rst_prev_ts = false;
8364 }
8365 else if (VALID_TS(prev_ts))
8366 {
8367 bool codec_cond = (drv_ctx.timestamp_adjust)?
8368 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8369 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8370 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8371 if(frm_int > 0 && codec_cond)
8372 {
8373 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8374 act_timestamp = prev_ts + frm_int;
8375 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8376 prev_ts = act_timestamp;
8377 }
8378 else
8379 set_frame_rate(act_timestamp);
8380 }
8381 else if (frm_int > 0) // In this case the frame rate was set along
8382 { // with the port definition, start ts with 0
8383 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8384 rst_prev_ts = true;
8385 }
8386}
8387
8388void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8389{
8390 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8391 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008392 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008393 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008394 OMX_U32 num_MB_in_frame;
8395 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008396 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008397 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008398 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8399 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008400 if (!drv_ctx.extradata_info.uaddr) {
8401 return;
8402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008403 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008404 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8405 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8406 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008407 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008408 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008409 if (data) {
8410 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008411 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008412 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008413 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008414 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008415 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008416 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008417 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008418 struct msm_vidc_interlace_payload *payload;
8419 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008420 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8421 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008422 OMX_U32 mbaff = 0;
8423 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8424 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8425 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8426 else
8427 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8428 if(m_enable_android_native_buffers)
8429 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008430 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008431 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008432 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8433 append_interlace_extradata(p_extra, payload->format);
8434 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8435 }
8436 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008437 case EXTRADATA_FRAME_RATE:
8438 struct msm_vidc_framerate_payload *frame_rate_payload;
8439 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8440 frame_rate = frame_rate_payload->frame_rate;
8441 break;
8442 case EXTRADATA_TIMESTAMP:
8443 struct msm_vidc_ts_payload *time_stamp_payload;
8444 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008445 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008446 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008447 break;
8448 case EXTRADATA_NUM_CONCEALED_MB:
8449 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8450 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8451 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8452 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8453 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8454 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008455 case EXTRADATA_ASPECT_RATIO:
8456 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8457 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8458 ((struct vdec_output_frameinfo *)
8459 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8460 ((struct vdec_output_frameinfo *)
8461 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8462 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008463 case EXTRADATA_RECOVERY_POINT_SEI:
8464 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8465 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8466 recovery_sei_flags = recovery_sei_payload->flags;
8467 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8468 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008469 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008470 }
8471 break;
8472 case EXTRADATA_PANSCAN_WINDOW:
8473 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8474 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008475 default:
8476 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008477 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008478 consumed_len += data->nSize;
8479 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008480 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008481 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008482 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008483 append_frame_info_extradata(p_extra,
8484 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008485 panscan_payload,&((struct vdec_output_frameinfo *)
8486 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008487 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008488unrecognized_extradata:
8489 if(!secure_mode && client_extradata)
8490 append_terminator_extradata(p_extra);
8491 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008492}
8493
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008494OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8495 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008496{
8497 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008498 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008499 if(m_state != OMX_StateLoaded)
8500 {
8501 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8502 return OMX_ErrorIncorrectStateOperation;
8503 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008504 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008505 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008506
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008507 if (!is_internal) {
8508 if (enable)
8509 client_extradata |= requested_extradata;
8510 else
8511 client_extradata = client_extradata & ~requested_extradata;
8512 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008513
8514 if (enable) {
8515 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8516 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8517 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8518 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8519 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8520 " Quality of interlaced clips might be impacted.\n");
8521 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008522 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8523 {
8524 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8525 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8526 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8527 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8528 }
8529 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8530 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8531 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8532 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8533 }
8534 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8535 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8536 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8537 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8538 }
8539 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8540 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8541 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8542 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8543 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008544 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8545 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8546 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8547 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8548 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008549 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8550 {
8551 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8552 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8553 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8554 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8555 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008556 }
8557 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008558 return ret;
8559}
8560
8561OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8562{
8563 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8564 OMX_U8 *data_ptr = extra->data, data = 0;
8565 while (byte_count < extra->nDataSize)
8566 {
8567 data = *data_ptr;
8568 while (data)
8569 {
8570 num_MB += (data&0x01);
8571 data >>= 1;
8572 }
8573 data_ptr++;
8574 byte_count++;
8575 }
8576 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8577 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8578 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8579}
8580
8581void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8582{
8583 if (!m_debug_extradata)
8584 return;
8585
8586 DEBUG_PRINT_HIGH(
8587 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008588 " Size: %lu \n"
8589 " Version: %lu \n"
8590 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008591 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008592 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008593 extra->nSize, extra->nVersion.nVersion,
8594 extra->nPortIndex, extra->eType, extra->nDataSize);
8595
Shalaj Jain286b0062013-02-21 20:35:48 -08008596 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008597 {
8598 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8599 DEBUG_PRINT_HIGH(
8600 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008601 " Size: %lu \n"
8602 " Version: %lu \n"
8603 " PortIndex: %lu \n"
8604 " Is Interlace Format: %d \n"
8605 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008606 "=========== End of Interlace ===========\n",
8607 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8608 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8609 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008610 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008611 {
8612 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8613
8614 DEBUG_PRINT_HIGH(
8615 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008616 " Picture Type: %d \n"
8617 " Interlace Type: %d \n"
8618 " Pan Scan Total Frame Num: %lu \n"
8619 " Concealed Macro Blocks: %lu \n"
8620 " frame rate: %lu \n"
8621 " Aspect Ratio X: %lu \n"
8622 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008623 fminfo->ePicType,
8624 fminfo->interlaceType,
8625 fminfo->panScan.numWindows,
8626 fminfo->nConcealedMacroblocks,
8627 fminfo->nFrameRate,
8628 fminfo->aspectRatio.aspectRatioX,
8629 fminfo->aspectRatio.aspectRatioY);
8630
Praneeth Paladugu32284302013-02-14 22:53:06 -08008631 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008632 {
8633 DEBUG_PRINT_HIGH(
8634 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008635 " Pan Scan Frame Num: %lu \n"
8636 " Rectangle x: %ld \n"
8637 " Rectangle y: %ld \n"
8638 " Rectangle dx: %ld \n"
8639 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008640 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8641 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8642 }
8643
8644 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8645 }
8646 else if (extra->eType == OMX_ExtraDataNone)
8647 {
8648 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8649 }
8650 else
8651 {
8652 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8653 }
8654}
8655
8656void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8657 OMX_U32 interlaced_format_type)
8658{
8659 OMX_STREAMINTERLACEFORMAT *interlace_format;
8660 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008661 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8662 return;
8663 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008664 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8665 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8666 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8667 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8668 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8669 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8670 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8671 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8672 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8673 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008674 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008675 {
8676 interlace_format->bInterlaceFormat = OMX_FALSE;
8677 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8678 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8679 }
8680 else
8681 {
8682 interlace_format->bInterlaceFormat = OMX_TRUE;
8683 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8684 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8685 }
8686 print_debug_extradata(extra);
8687}
8688
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008689void omx_vdec::fill_aspect_ratio_info(
8690 struct vdec_aspectratioinfo *aspect_ratio_info,
8691 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8692{
8693 m_extradata = frame_info;
8694 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8695 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008696 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008697 m_extradata->aspectRatio.aspectRatioY);
8698}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008699
8700void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008701 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008702 struct msm_vidc_panscan_window_payload *panscan_payload,
8703 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008704{
8705 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008706 struct msm_vidc_panscan_window *panscan_window;
8707 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8708 return;
8709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008710 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8711 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8712 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8713 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8714 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8715 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8716 switch (picture_type)
8717 {
8718 case PICTURE_TYPE_I:
8719 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8720 break;
8721 case PICTURE_TYPE_P:
8722 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8723 break;
8724 case PICTURE_TYPE_B:
8725 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8726 break;
8727 default:
8728 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8729 }
8730 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8731 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8732 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8733 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8734 else
8735 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008736 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008737 frame_info->nConcealedMacroblocks = num_conceal_mb;
8738 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008739 frame_info->panScan.numWindows = 0;
8740 if(panscan_payload) {
8741 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8742 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008743 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008744 {
8745 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8746 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8747 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8748 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8749 panscan_window++;
8750 }
8751 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008752 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008753 print_debug_extradata(extra);
8754}
8755
8756void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8757{
8758 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8759 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8760 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8761 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8762 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8763 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8764 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8765 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008766 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8767 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008768 portDefn->format.video.nFrameWidth,
8769 portDefn->format.video.nStride,
8770 portDefn->format.video.nSliceHeight);
8771}
8772
8773void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8774{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008775 if (!client_extradata) {
8776 return;
8777 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008778 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8779 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8780 extra->eType = OMX_ExtraDataNone;
8781 extra->nDataSize = 0;
8782 extra->data[0] = 0;
8783
8784 print_debug_extradata(extra);
8785}
8786
8787OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8788{
8789 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8790 if (index >= drv_ctx.ip_buf.actualcount)
8791 {
8792 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8793 return OMX_ErrorInsufficientResources;
8794 }
8795 if (m_desc_buffer_ptr == NULL)
8796 {
8797 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8798 calloc( (sizeof(desc_buffer_hdr)),
8799 drv_ctx.ip_buf.actualcount);
8800 if (m_desc_buffer_ptr == NULL)
8801 {
8802 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8803 return OMX_ErrorInsufficientResources;
8804 }
8805 }
8806
8807 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8808 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8809 {
8810 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8811 return OMX_ErrorInsufficientResources;
8812 }
8813
8814 return eRet;
8815}
8816
8817void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8818{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008819 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008820 if (m_demux_entries < 8192)
8821 {
8822 m_demux_offsets[m_demux_entries++] = address_offset;
8823 }
8824 return;
8825}
8826
8827void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8828{
8829 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8830 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8831 OMX_U32 index = 0;
8832
8833 m_demux_entries = 0;
8834
8835 while (index < bytes_to_parse)
8836 {
8837 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8838 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8839 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8840 (buf[index+2] == 0x01)) )
8841 {
8842 //Found start code, insert address offset
8843 insert_demux_addr_offset(index);
8844 if (buf[index+2] == 0x01) // 3 byte start code
8845 index += 3;
8846 else //4 byte start code
8847 index += 4;
8848 }
8849 else
8850 index++;
8851 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008852 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008853 return;
8854}
8855
8856OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8857{
8858 //fix this, handle 3 byte start code, vc1 terminator entry
8859 OMX_U8 *p_demux_data = NULL;
8860 OMX_U32 desc_data = 0;
8861 OMX_U32 start_addr = 0;
8862 OMX_U32 nal_size = 0;
8863 OMX_U32 suffix_byte = 0;
8864 OMX_U32 demux_index = 0;
8865 OMX_U32 buffer_index = 0;
8866
8867 if (m_desc_buffer_ptr == NULL)
8868 {
8869 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8870 return OMX_ErrorBadParameter;
8871 }
8872
8873 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8874 if (buffer_index > drv_ctx.ip_buf.actualcount)
8875 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008876 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008877 return OMX_ErrorBadParameter;
8878 }
8879
8880 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8881
8882 if ( ((OMX_U8*)p_demux_data == NULL) ||
8883 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8884 {
8885 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8886 return OMX_ErrorBadParameter;
8887 }
8888 else
8889 {
8890 for (; demux_index < m_demux_entries; demux_index++)
8891 {
8892 desc_data = 0;
8893 start_addr = m_demux_offsets[demux_index];
8894 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8895 {
8896 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8897 }
8898 else
8899 {
8900 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8901 }
8902 if (demux_index < (m_demux_entries - 1))
8903 {
8904 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8905 }
8906 else
8907 {
8908 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8909 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008910 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8911 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008912 suffix_byte,
8913 nal_size,
8914 demux_index);
8915 desc_data = (start_addr >> 3) << 1;
8916 desc_data |= (start_addr & 7) << 21;
8917 desc_data |= suffix_byte << 24;
8918
8919 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8920 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8921 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8922 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8923
8924 p_demux_data += 16;
8925 }
8926 if (codec_type_parse == CODEC_TYPE_VC1)
8927 {
8928 DEBUG_PRINT_LOW("VC1 terminator entry");
8929 desc_data = 0;
8930 desc_data = 0x82 << 24;
8931 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8932 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8933 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8934 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8935 p_demux_data += 16;
8936 m_demux_entries++;
8937 }
8938 //Add zero word to indicate end of descriptors
8939 memset(p_demux_data, 0, sizeof(OMX_U32));
8940
8941 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008942 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008943 }
8944 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8945 m_demux_entries = 0;
8946 DEBUG_PRINT_LOW("Demux table complete!");
8947 return OMX_ErrorNone;
8948}
8949
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008950OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008951{
8952 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008953 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008954 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008955 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8956 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008957 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008958 delete iDivXDrmDecrypt;
8959 iDivXDrmDecrypt = NULL;
8960 }
8961 }
8962 else {
8963 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008964 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008965 }
8966 return err;
8967}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008968
Vinay Kaliada4f4422013-01-09 10:45:03 -08008969omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8970{
8971 enabled = false;
8972 omx = NULL;
8973 init_members();
8974 ColorFormat = OMX_COLOR_FormatMax;
8975}
8976
8977void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8978{
8979 omx = reinterpret_cast<omx_vdec*>(client);
8980}
8981
8982void omx_vdec::allocate_color_convert_buf::init_members() {
8983 allocated_count = 0;
8984 buffer_size_req = 0;
8985 buffer_alignment_req = 0;
8986 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8987 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8988 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8989 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
8990#ifdef USE_ION
8991 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
8992#endif
8993 for (int i = 0; i < MAX_COUNT;i++)
8994 pmem_fd[i] = -1;
8995}
8996
8997omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
8998 c2d.destroy();
8999}
9000
9001bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9002{
9003 bool status = true;
9004 unsigned int src_size = 0, destination_size = 0;
9005 OMX_COLOR_FORMATTYPE drv_color_format;
9006 if (!omx){
9007 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9008 return false;
9009 }
9010 if (!enabled){
9011 DEBUG_PRINT_ERROR("\n No color conversion required");
9012 return status;
9013 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009014 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009015 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9016 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9017 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009018 status = false;
9019 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009020 }
9021 c2d.close();
9022 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9023 omx->drv_ctx.video_resolution.frame_width,
9024 NV12_128m,YCbCr420P);
9025 if (status) {
9026 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9027 if (status)
9028 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9029 }
9030 if (status) {
9031 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9032 !destination_size) {
9033 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9034 "driver size %d destination size %d",
9035 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9036 status = false;
9037 c2d.close();
9038 buffer_size_req = 0;
9039 } else {
9040 buffer_size_req = destination_size;
9041 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9042 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9043 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9044 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9045 }
9046 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009047fail_update_buf_req:
9048 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009049 return status;
9050}
9051
9052bool omx_vdec::allocate_color_convert_buf::set_color_format(
9053 OMX_COLOR_FORMATTYPE dest_color_format)
9054{
9055 bool status = true;
9056 OMX_COLOR_FORMATTYPE drv_color_format;
9057 if (!omx){
9058 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9059 return false;
9060 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009061 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009062 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9063 drv_color_format = (OMX_COLOR_FORMATTYPE)
9064 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9065 else {
9066 DEBUG_PRINT_ERROR("\n Incorrect color format");
9067 status = false;
9068 }
9069 if (status && (drv_color_format != dest_color_format)) {
9070 DEBUG_PRINT_LOW("Enabling C2D\n");
9071 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9072 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9073 status = false;
9074 } else {
9075 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9076 if (enabled)
9077 c2d.destroy();
9078 enabled = false;
9079 if (!c2d.init()) {
9080 DEBUG_PRINT_ERROR("\n open failed for c2d");
9081 status = false;
9082 } else
9083 enabled = true;
9084 }
9085 } else {
9086 if (enabled)
9087 c2d.destroy();
9088 enabled = false;
9089 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009090 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009091 return status;
9092}
9093
9094OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9095{
9096 if (!omx){
9097 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9098 return NULL;
9099 }
9100 if (!enabled)
9101 return omx->m_out_mem_ptr;
9102 return m_out_mem_ptr_client;
9103}
9104
9105OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9106 (OMX_BUFFERHEADERTYPE *bufadd)
9107{
9108 if (!omx){
9109 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9110 return NULL;
9111 }
9112 if (!enabled)
9113 return bufadd;
9114
9115 unsigned index = 0;
9116 index = bufadd - omx->m_out_mem_ptr;
9117 if (index < omx->drv_ctx.op_buf.actualcount) {
9118 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9119 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9120 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009121 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009122 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009123 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9124 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009125 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009126 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9127 if (!status){
9128 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009129 m_out_mem_ptr_client[index].nFilledLen = 0;
9130 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009131 }
9132 } else
9133 m_out_mem_ptr_client[index].nFilledLen = 0;
9134 return &m_out_mem_ptr_client[index];
9135 }
9136 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9137 return NULL;
9138}
9139
9140OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9141 (OMX_BUFFERHEADERTYPE *bufadd)
9142{
9143 if (!omx){
9144 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9145 return NULL;
9146 }
9147 if (!enabled)
9148 return bufadd;
9149 unsigned index = 0;
9150 index = bufadd - m_out_mem_ptr_client;
9151 if (index < omx->drv_ctx.op_buf.actualcount) {
9152 return &omx->m_out_mem_ptr[index];
9153 }
9154 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9155 return NULL;
9156}
9157bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9158 (unsigned int &buffer_size)
9159{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009160 bool status = true;
9161 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009162 if (!enabled)
9163 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009164 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009165 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9166 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009167 status = false;
9168 goto fail_get_buffer_size;
9169 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009170 }
9171 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9172 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9173 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9174 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009175fail_get_buffer_size:
9176 pthread_mutex_unlock(&omx->c_lock);
9177 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009178}
9179OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9180 OMX_BUFFERHEADERTYPE *bufhdr) {
9181 unsigned int index = 0;
9182
9183 if (!enabled)
9184 return omx->free_output_buffer(bufhdr);
9185 if (enabled && omx->is_component_secure())
9186 return OMX_ErrorNone;
9187 if (!allocated_count || !bufhdr) {
9188 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9189 return OMX_ErrorBadParameter;
9190 }
9191 index = bufhdr - m_out_mem_ptr_client;
9192 if (index >= omx->drv_ctx.op_buf.actualcount){
9193 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9194 return OMX_ErrorBadParameter;
9195 }
9196 if (pmem_fd[index] > 0) {
9197 munmap(pmem_baseaddress[index], buffer_size_req);
9198 close(pmem_fd[index]);
9199 }
9200 pmem_fd[index] = -1;
9201#ifdef USE_ION
9202 omx->free_ion_memory(&op_buf_ion_info[index]);
9203#endif
9204 m_heap_ptr[index].video_heap_ptr = NULL;
9205 if (allocated_count > 0)
9206 allocated_count--;
9207 else
9208 allocated_count = 0;
9209 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009210 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009211 c2d.close();
9212 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009213 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009214 }
9215 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9216}
9217
9218OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9219 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9220{
9221 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9222 if (!enabled){
9223 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9224 return eRet;
9225 }
9226 if (enabled && omx->is_component_secure()) {
9227 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9228 omx->is_component_secure());
9229 return OMX_ErrorUnsupportedSetting;
9230 }
9231 if (!bufferHdr || bytes > buffer_size_req) {
9232 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009233 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009234 buffer_size_req,bytes);
9235 return OMX_ErrorBadParameter;
9236 }
9237 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9238 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9239 return OMX_ErrorInsufficientResources;
9240 }
9241 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9242 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9243 port,appData,omx->drv_ctx.op_buf.buffer_size);
9244 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9245 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9246 return eRet;
9247 }
9248 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9249 omx->drv_ctx.op_buf.actualcount) {
9250 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9251 (temp_bufferHdr - omx->m_out_mem_ptr));
9252 return OMX_ErrorUndefined;
9253 }
9254 unsigned int i = allocated_count;
9255#ifdef USE_ION
9256 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9257 buffer_size_req,buffer_alignment_req,
9258 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009259 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009260 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9261 if (op_buf_ion_info[i].ion_device_fd < 0) {
9262 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9263 return OMX_ErrorInsufficientResources;
9264 }
9265 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9266 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9267
9268 if (pmem_baseaddress[i] == MAP_FAILED) {
9269 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9270 close(pmem_fd[i]);
9271 omx->free_ion_memory(&op_buf_ion_info[i]);
9272 return OMX_ErrorInsufficientResources;
9273 }
9274 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9275 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9276 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9277#endif
9278 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9279 m_pmem_info_client[i].offset = 0;
9280 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9281 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9282 m_platform_list_client[i].nEntries = 1;
9283 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9284 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9285 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9286 m_out_mem_ptr_client[i].nFilledLen = 0;
9287 m_out_mem_ptr_client[i].nFlags = 0;
9288 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9289 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9290 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9291 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9292 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9293 m_out_mem_ptr_client[i].pAppPrivate = appData;
9294 *bufferHdr = &m_out_mem_ptr_client[i];
9295 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9296 allocated_count++;
9297 return eRet;
9298}
9299
9300bool omx_vdec::is_component_secure()
9301{
9302 return secure_mode;
9303}
9304
9305bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9306{
9307 bool status = true;
9308 if (!enabled) {
9309 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9310 dest_color_format = (OMX_COLOR_FORMATTYPE)
9311 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9312 else
9313 status = false;
9314 } else {
9315 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9316 status = false;
9317 } else
9318 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9319 }
9320 return status;
9321}
Praneeth Paladugu53478562013-03-12 14:49:46 -07009322
9323void omx_vdec::enableAdditionalCores(int frame_interval)
9324{
9325 DEBUG_PRINT_LOW("Setting frame rate to 1/(%dusec)", frame_interval);
9326 if (frame_interval < 33000)
9327 {
9328 DEBUG_PRINT_HIGH("Turning on additional CPU cores");
9329 if (NULL == opt_handle) {
9330 char opt_lib_path[PATH_MAX] = {0};
9331
9332 if (property_get("ro.vendor.extension_library", opt_lib_path, NULL) != 0) {
9333 if ((opt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
9334 DEBUG_PRINT_ERROR("Unable to open %s: %s\n", opt_lib_path, dlerror());
9335 } else {
9336 perf_lock_acq = (int(*)(int, int, int*,int))dlsym(opt_handle, "perf_lock_acq");
9337 if (perf_lock_acq == NULL) {
9338 DEBUG_PRINT_ERROR("failed to get lock_acq sym");
9339 }
9340
9341 perf_lock_rel = (int(*)(int))dlsym(opt_handle, "perf_lock_rel");
9342 if (perf_lock_rel == NULL) {
9343 DEBUG_PRINT_ERROR("failed to get lock_rel sym");
9344 }
9345 }
9346 } else {
9347 DEBUG_PRINT_ERROR("Property ro.vendor.extension_library does not exist.");
9348 }
9349 }
9350
9351 int decode_opts[1] = {0x704}; //value of last nibble == # of cores
9352 if (perf_lock_acq && perf_lock_handle < 0) {
9353 DEBUG_PRINT_LOW("Lock acquired");
9354 perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, decode_opts, 1);
9355 }
9356 }
9357}