blob: 6c68e302ea5d6e0a61bb6a4c4740c86fa1fbd5c5 [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;
Vinay Kaliab9e98102013-04-02 19:31:43 -0700208 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700209 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_FLUSH_DONE) {
214 struct vdec_msginfo vdec_msg;
215 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
216 vdec_msg.status_code=VDEC_S_SUCCESS;
217 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
218 if (omx->async_message_process(input,&vdec_msg) < 0) {
219 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
220 break;
221 }
222 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
223 vdec_msg.status_code=VDEC_S_SUCCESS;
224 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
225 if (omx->async_message_process(input,&vdec_msg) < 0) {
226 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
227 break;
228 }
229 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
230 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
231 break;
232 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
233 struct vdec_msginfo vdec_msg;
234 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
235 vdec_msg.status_code=VDEC_S_SUCCESS;
236 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
237 if (omx->async_message_process(input,&vdec_msg) < 0) {
238 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
239 break;
240 }
241 } else {
242 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
243 continue;
244 }
245 }
246 }
247 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
248 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700249}
250
251void* message_thread(void *input)
252{
253 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
254 unsigned char id;
255 int n;
256
257 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
258 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
259 while (1)
260 {
261
262 n = read(omx->m_pipe_in, &id, 1);
263
264 if(0 == n)
265 {
266 break;
267 }
268
269 if (1 == n)
270 {
271 omx->process_event_cb(omx, id);
272 }
273 if ((n < 0) && (errno != EINTR))
274 {
275 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
276 break;
277 }
278 }
279 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
280 return 0;
281}
282
283void post_message(omx_vdec *omx, unsigned char id)
284{
285 int ret_value;
286 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
287 ret_value = write(omx->m_pipe_out, &id, 1);
288 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
289}
290
291// omx_cmd_queue destructor
292omx_vdec::omx_cmd_queue::~omx_cmd_queue()
293{
294 // Nothing to do
295}
296
297// omx cmd queue constructor
298omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
299{
300 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
301}
302
303// omx cmd queue insert
304bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
305{
306 bool ret = true;
307 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
308 {
309 m_q[m_write].id = id;
310 m_q[m_write].param1 = p1;
311 m_q[m_write].param2 = p2;
312 m_write++;
313 m_size ++;
314 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
315 {
316 m_write = 0;
317 }
318 }
319 else
320 {
321 ret = false;
322 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
323 }
324 return ret;
325}
326
327// omx cmd queue pop
328bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
329{
330 bool ret = true;
331 if (m_size > 0)
332 {
333 *id = m_q[m_read].id;
334 *p1 = m_q[m_read].param1;
335 *p2 = m_q[m_read].param2;
336 // Move the read pointer ahead
337 ++m_read;
338 --m_size;
339 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
340 {
341 m_read = 0;
342 }
343 }
344 else
345 {
346 ret = false;
347 }
348 return ret;
349}
350
351// Retrieve the first mesg type in the queue
352unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
353{
354 return m_q[m_read].id;
355}
356
357#ifdef _ANDROID_
358omx_vdec::ts_arr_list::ts_arr_list()
359{
360 //initialize timestamps array
361 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
362}
363omx_vdec::ts_arr_list::~ts_arr_list()
364{
365 //free m_ts_arr_list?
366}
367
368bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
369{
370 bool ret = true;
371 bool duplicate_ts = false;
372 int idx = 0;
373
374 //insert at the first available empty location
375 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
376 {
377 if (!m_ts_arr_list[idx].valid)
378 {
379 //found invalid or empty entry, save timestamp
380 m_ts_arr_list[idx].valid = true;
381 m_ts_arr_list[idx].timestamp = ts;
382 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
383 ts, idx);
384 break;
385 }
386 }
387
388 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
389 {
390 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
391 ret = false;
392 }
393 return ret;
394}
395
396bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
397{
398 bool ret = true;
399 int min_idx = -1;
400 OMX_TICKS min_ts = 0;
401 int idx = 0;
402
403 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
404 {
405
406 if (m_ts_arr_list[idx].valid)
407 {
408 //found valid entry, save index
409 if (min_idx < 0)
410 {
411 //first valid entry
412 min_ts = m_ts_arr_list[idx].timestamp;
413 min_idx = idx;
414 }
415 else if (m_ts_arr_list[idx].timestamp < min_ts)
416 {
417 min_ts = m_ts_arr_list[idx].timestamp;
418 min_idx = idx;
419 }
420 }
421
422 }
423
424 if (min_idx < 0)
425 {
426 //no valid entries found
427 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
428 ts = 0;
429 ret = false;
430 }
431 else
432 {
433 ts = m_ts_arr_list[min_idx].timestamp;
434 m_ts_arr_list[min_idx].valid = false;
435 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
436 ts, min_idx);
437 }
438
439 return ret;
440
441}
442
443
444bool omx_vdec::ts_arr_list::reset_ts_list()
445{
446 bool ret = true;
447 int idx = 0;
448
449 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
450 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
451 {
452 m_ts_arr_list[idx].valid = false;
453 }
454 return ret;
455}
456#endif
457
458// factory function executed by the core to create instances
459void *get_omx_component_factory_fn(void)
460{
461 return (new omx_vdec);
462}
463
464#ifdef _ANDROID_
465#ifdef USE_ION
466VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
467 struct ion_handle *handle, int ionMapfd)
468{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700469// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700470}
471#else
472VideoHeap::VideoHeap(int fd, size_t size, void* base)
473{
474 // dup file descriptor, map once, use pmem
475 init(dup(fd), base, size, 0 , MEM_DEVICE);
476}
477#endif
478#endif // _ANDROID_
479/* ======================================================================
480FUNCTION
481 omx_vdec::omx_vdec
482
483DESCRIPTION
484 Constructor
485
486PARAMETERS
487 None
488
489RETURN VALUE
490 None.
491========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800492omx_vdec::omx_vdec(): m_error_propogated(false),
493 m_state(OMX_StateInvalid),
494 m_app_data(NULL),
495 m_inp_mem_ptr(NULL),
496 m_out_mem_ptr(NULL),
497 m_inp_err_count(0),
498 input_flush_progress (false),
499 output_flush_progress (false),
500 input_use_buffer (false),
501 output_use_buffer (false),
502 ouput_egl_buffers(false),
503 m_use_output_pmem(OMX_FALSE),
504 m_out_mem_region_smi(OMX_FALSE),
505 m_out_pvt_entry_pmem(OMX_FALSE),
506 pending_input_buffers(0),
507 pending_output_buffers(0),
508 m_out_bm_count(0),
509 m_inp_bm_count(0),
510 m_inp_bPopulated(OMX_FALSE),
511 m_out_bPopulated(OMX_FALSE),
512 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700513#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800514 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700515#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800516 m_inp_bEnabled(OMX_TRUE),
517 m_out_bEnabled(OMX_TRUE),
518 m_in_alloc_cnt(0),
519 m_platform_list(NULL),
520 m_platform_entry(NULL),
521 m_pmem_info(NULL),
522 arbitrary_bytes (true),
523 psource_frame (NULL),
524 pdest_frame (NULL),
525 m_inp_heap_ptr (NULL),
526 m_phdr_pmem_ptr(NULL),
527 m_heap_inp_bm_count (0),
528 codec_type_parse ((codec_type)0),
529 first_frame_meta (true),
530 frame_count (0),
531 nal_count (0),
532 nal_length(0),
533 look_ahead_nal (false),
534 first_frame(0),
535 first_buffer(NULL),
536 first_frame_size (0),
537 m_device_file_ptr(NULL),
538 m_vc1_profile((vc1_profile_type)0),
539 h264_last_au_ts(LLONG_MAX),
540 h264_last_au_flags(0),
541 prev_ts(LLONG_MAX),
542 rst_prev_ts(true),
543 frm_int(0),
544 in_reconfig(false),
545 m_display_id(NULL),
546 h264_parser(NULL),
547 client_extradata(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700548#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800549 m_enable_android_native_buffers(OMX_FALSE),
550 m_use_android_native_buffers(OMX_FALSE),
551 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700552#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800553 m_desc_buffer_ptr(NULL),
Praneeth Paladugu53478562013-03-12 14:49:46 -0700554 secure_mode(false),
555 opt_handle(NULL),
556 perf_lock_acq(NULL),
557 perf_lock_rel(NULL),
558 perf_lock_handle(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700559{
560 /* Assumption is that , to begin with , we have all the frames with decoder */
561 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
562#ifdef _ANDROID_
563 char property_value[PROPERTY_VALUE_MAX] = {0};
564 property_get("vidc.dec.debug.perf", property_value, "0");
565 perf_flag = atoi(property_value);
566 if (perf_flag)
567 {
568 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
569 dec_time.start();
570 proc_frms = latency = 0;
571 }
Vinay Kaliab9e98102013-04-02 19:31:43 -0700572 prev_n_filled_len = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -0800573 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700574 property_get("vidc.dec.debug.ts", property_value, "0");
575 m_debug_timestamp = atoi(property_value);
576 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
577 if (m_debug_timestamp)
578 {
579 time_stamp_dts.set_timestamp_reorder_mode(true);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800580 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700581 }
582
Shalaj Jain286b0062013-02-21 20:35:48 -0800583 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700584 property_get("vidc.dec.debug.concealedmb", property_value, "0");
585 m_debug_concealedmb = atoi(property_value);
586 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
587
588#endif
589 memset(&m_cmp,0,sizeof(m_cmp));
590 memset(&m_cb,0,sizeof(m_cb));
591 memset (&drv_ctx,0,sizeof(drv_ctx));
592 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
593 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700594 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
595 m_demux_entries = 0;
596#ifdef _ANDROID_ICS_
597 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
598#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700599 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700600 drv_ctx.timestamp_adjust = false;
601 drv_ctx.video_driver_fd = -1;
602 m_vendor_config.pData = NULL;
603 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800604 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700605 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800606 streaming[CAPTURE_PORT] =
607 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700608#ifdef _ANDROID_
609 char extradata_value[PROPERTY_VALUE_MAX] = {0};
610 property_get("vidc.dec.debug.extradata", extradata_value, "0");
611 m_debug_extradata = atoi(extradata_value);
612 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
613#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800614 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
615 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700616}
617
Vinay Kalia85793762012-06-14 19:12:34 -0700618static const int event_type[] = {
619 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
620 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
621 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700622 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
623 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700624};
625
626static OMX_ERRORTYPE subscribe_to_events(int fd)
627{
628 OMX_ERRORTYPE eRet = OMX_ErrorNone;
629 struct v4l2_event_subscription sub;
630 int array_sz = sizeof(event_type)/sizeof(int);
631 int i,rc;
632 if (fd < 0) {
633 printf("Invalid input: %d\n", fd);
634 return OMX_ErrorBadParameter;
635 }
636
637 for (i = 0; i < array_sz; ++i) {
638 memset(&sub, 0, sizeof(sub));
639 sub.type = event_type[i];
640 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
641 if (rc) {
642 printf("Failed to subscribe event: 0x%x\n", sub.type);
643 break;
644 }
645 }
646 if (i < array_sz) {
647 for (--i; i >=0 ; i--) {
648 memset(&sub, 0, sizeof(sub));
649 sub.type = event_type[i];
650 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
651 if (rc)
652 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
653 }
654 eRet = OMX_ErrorNotImplemented;
655 }
656 return eRet;
657}
658
659
660static OMX_ERRORTYPE unsubscribe_to_events(int fd)
661{
662 OMX_ERRORTYPE eRet = OMX_ErrorNone;
663 struct v4l2_event_subscription sub;
664 int array_sz = sizeof(event_type)/sizeof(int);
665 int i,rc;
666 if (fd < 0) {
667 printf("Invalid input: %d\n", fd);
668 return OMX_ErrorBadParameter;
669 }
670
671 for (i = 0; i < array_sz; ++i) {
672 memset(&sub, 0, sizeof(sub));
673 sub.type = event_type[i];
674 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
675 if (rc) {
676 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
677 break;
678 }
679 }
680 return eRet;
681}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700682
683/* ======================================================================
684FUNCTION
685 omx_vdec::~omx_vdec
686
687DESCRIPTION
688 Destructor
689
690PARAMETERS
691 None
692
693RETURN VALUE
694 None.
695========================================================================== */
696omx_vdec::~omx_vdec()
697{
698 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700699 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700700 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
701 if(m_pipe_in) close(m_pipe_in);
702 if(m_pipe_out) close(m_pipe_out);
703 m_pipe_in = -1;
704 m_pipe_out = -1;
705 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
706 pthread_join(msg_thread_id,NULL);
707 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700708 dec.cmd = V4L2_DEC_CMD_STOP;
709 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
710 {
711 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
712 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700713 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700714 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700715 close(drv_ctx.video_driver_fd);
716 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800717 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700718 sem_destroy(&m_cmd_lock);
Praneeth Paladugu53478562013-03-12 14:49:46 -0700719 if (perf_lock_handle >= 0 && perf_lock_rel) {
720 DEBUG_PRINT_LOW("Lock released");
721 perf_lock_rel(perf_lock_handle);
722 perf_lock_handle = -1;
723 }
724 if (opt_handle) {
725 dlclose(opt_handle);
726 opt_handle = NULL;
727 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728 if (perf_flag)
729 {
730 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
731 dec_time.end();
732 }
733 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
734}
735
Vinay Kaliafeef7032012-09-25 19:23:33 -0700736int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
737 struct v4l2_requestbuffers bufreq;
738 int rc = 0;
739 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
740 bufreq.memory = V4L2_MEMORY_USERPTR;
741 bufreq.count = 0;
742 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
743 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
744 }
745 return rc;
746}
747
Shalaj Jain273b3e02012-06-22 19:08:03 -0700748/* ======================================================================
749FUNCTION
750 omx_vdec::OMXCntrlProcessMsgCb
751
752DESCRIPTION
753 IL Client callbacks are generated through this routine. The decoder
754 provides the thread context for this routine.
755
756PARAMETERS
757 ctxt -- Context information related to the self.
758 id -- Event identifier. This could be any of the following:
759 1. Command completion event
760 2. Buffer done callback event
761 3. Frame done callback event
762
763RETURN VALUE
764 None.
765
766========================================================================== */
767void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
768{
Shalaj Jain286b0062013-02-21 20:35:48 -0800769 signed p1; // Parameter - 1
770 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700771 unsigned ident;
772 unsigned qsize=0; // qsize
773 omx_vdec *pThis = (omx_vdec *) ctxt;
774
775 if(!pThis)
776 {
777 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
778 __func__);
779 return;
780 }
781
782 // Protect the shared queue data structure
783 do
784 {
785 /*Read the message id's from the queue*/
786 pthread_mutex_lock(&pThis->m_lock);
787 qsize = pThis->m_cmd_q.m_size;
788 if(qsize)
789 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800790 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700791 }
792
793 if (qsize == 0 && pThis->m_state != OMX_StatePause)
794 {
795 qsize = pThis->m_ftb_q.m_size;
796 if (qsize)
797 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800798 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799 }
800 }
801
802 if (qsize == 0 && pThis->m_state != OMX_StatePause)
803 {
804 qsize = pThis->m_etb_q.m_size;
805 if (qsize)
806 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800807 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700808 }
809 }
810 pthread_mutex_unlock(&pThis->m_lock);
811
812 /*process message if we have one*/
813 if(qsize > 0)
814 {
815 id = ident;
816 switch (id)
817 {
818 case OMX_COMPONENT_GENERATE_EVENT:
819 if (pThis->m_cb.EventHandler)
820 {
821 switch (p1)
822 {
823 case OMX_CommandStateSet:
824 pThis->m_state = (OMX_STATETYPE) p2;
825 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
826 pThis->m_state);
827 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
828 OMX_EventCmdComplete, p1, p2, NULL);
829 break;
830
831 case OMX_EventError:
832 if(p2 == OMX_StateInvalid)
833 {
834 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
835 pThis->m_state = (OMX_STATETYPE) p2;
836 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
837 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
838 }
839 else if (p2 == OMX_ErrorHardware)
840 {
841 pThis->omx_report_error();
842 }
843 else
844 {
845 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800846 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700847 }
848 break;
849
850 case OMX_CommandPortDisable:
851 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
852 if (BITMASK_PRESENT(&pThis->m_flags,
853 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
854 {
855 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
856 break;
857 }
858 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
859 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700860 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700861 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700862 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
863 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
864 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700865 pThis->in_reconfig = false;
866 if(eRet != OMX_ErrorNone)
867 {
868 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
869 pThis->omx_report_error();
870 break;
871 }
872 }
873 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
874 OMX_EventCmdComplete, p1, p2, NULL );
875 break;
876 case OMX_CommandPortEnable:
877 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
878 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
879 OMX_EventCmdComplete, p1, p2, NULL );
880 break;
881
882 default:
883 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
884 OMX_EventCmdComplete, p1, p2, NULL );
885 break;
886
887 }
888 }
889 else
890 {
891 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
892 }
893 break;
894 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
895 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
896 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
897 {
898 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
899 pThis->omx_report_error ();
900 }
901 break;
902 case OMX_COMPONENT_GENERATE_ETB:
903 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
904 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
905 {
906 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
907 pThis->omx_report_error ();
908 }
909 break;
910
911 case OMX_COMPONENT_GENERATE_FTB:
912 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
913 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
914 {
915 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
916 pThis->omx_report_error ();
917 }
918 break;
919
920 case OMX_COMPONENT_GENERATE_COMMAND:
921 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
922 (OMX_U32)p2,(OMX_PTR)NULL);
923 break;
924
925 case OMX_COMPONENT_GENERATE_EBD:
926
927 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
928 {
929 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
930 pThis->omx_report_error ();
931 }
932 else
933 {
934 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
935 {
936 pThis->m_inp_err_count++;
937 pThis->time_stamp_dts.remove_time_stamp(
938 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
939 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
940 ?true:false);
941 }
942 else
943 {
944 pThis->m_inp_err_count = 0;
945 }
946 if ( pThis->empty_buffer_done(&pThis->m_cmp,
947 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
948 {
949 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
950 pThis->omx_report_error ();
951 }
952 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
953 {
954 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
955 pThis->omx_report_error ();
956 }
957 }
958 break;
959 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
960 {
961 int64_t *timestamp = (int64_t *)p1;
962 if (p1)
963 {
964 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
965 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
966 ?true:false);
967 free(timestamp);
968 }
969 }
970 break;
971 case OMX_COMPONENT_GENERATE_FBD:
972 if (p2 != VDEC_S_SUCCESS)
973 {
974 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
975 pThis->omx_report_error ();
976 }
977 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
978 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
979 {
980 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
986 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
987 if (!pThis->input_flush_progress)
988 {
989 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
990 }
991 else
992 {
993 pThis->execute_input_flush();
994 if (pThis->m_cb.EventHandler)
995 {
996 if (p2 != VDEC_S_SUCCESS)
997 {
998 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
999 pThis->omx_report_error ();
1000 }
1001 else
1002 {
1003 /*Check if we need generate event for Flush done*/
1004 if(BITMASK_PRESENT(&pThis->m_flags,
1005 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1006 {
1007 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1008 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1009 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1010 OMX_EventCmdComplete,OMX_CommandFlush,
1011 OMX_CORE_INPUT_PORT_INDEX,NULL );
1012 }
1013 if (BITMASK_PRESENT(&pThis->m_flags,
1014 OMX_COMPONENT_IDLE_PENDING))
1015 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001016 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001017 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1018 pThis->omx_report_error ();
1019 } else {
1020 pThis->streaming[OUTPUT_PORT] = false;
1021 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001022 if (!pThis->output_flush_progress)
1023 {
Vinay Kalia22046272012-09-28 20:16:05 -07001024 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001025 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001026 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001027 }
1028 }
1029 }
1030 }
1031 else
1032 {
1033 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1034 }
1035 }
1036 break;
1037
1038 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1039 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1040 if (!pThis->output_flush_progress)
1041 {
1042 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1043 }
1044 else
1045 {
1046 pThis->execute_output_flush();
1047 if (pThis->m_cb.EventHandler)
1048 {
1049 if (p2 != VDEC_S_SUCCESS)
1050 {
1051 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1052 pThis->omx_report_error ();
1053 }
1054 else
1055 {
1056 /*Check if we need generate event for Flush done*/
1057 if(BITMASK_PRESENT(&pThis->m_flags,
1058 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1059 {
1060 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1061 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1062 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1063 OMX_EventCmdComplete,OMX_CommandFlush,
1064 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1065 }
1066 if(BITMASK_PRESENT(&pThis->m_flags,
1067 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1068 {
1069 DEBUG_PRINT_LOW("\n Internal flush complete");
1070 BITMASK_CLEAR (&pThis->m_flags,
1071 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1072 if (BITMASK_PRESENT(&pThis->m_flags,
1073 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1074 {
1075 pThis->post_event(OMX_CommandPortDisable,
1076 OMX_CORE_OUTPUT_PORT_INDEX,
1077 OMX_COMPONENT_GENERATE_EVENT);
1078 BITMASK_CLEAR (&pThis->m_flags,
1079 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1080
1081 }
1082 }
1083
1084 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1085 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001086 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001087 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1088 pThis->omx_report_error ();
1089 break;
1090 }
1091 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001092 if (!pThis->input_flush_progress)
1093 {
Vinay Kalia22046272012-09-28 20:16:05 -07001094 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001095 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001096 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001097 }
1098 }
1099 }
1100 }
1101 else
1102 {
1103 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1104 }
1105 }
1106 break;
1107
1108 case OMX_COMPONENT_GENERATE_START_DONE:
1109 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1110
1111 if (pThis->m_cb.EventHandler)
1112 {
1113 if (p2 != VDEC_S_SUCCESS)
1114 {
1115 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1116 pThis->omx_report_error ();
1117 }
1118 else
1119 {
1120 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1121 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1122 {
1123 DEBUG_PRINT_LOW("\n Move to executing");
1124 // Send the callback now
1125 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1126 pThis->m_state = OMX_StateExecuting;
1127 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1128 OMX_EventCmdComplete,OMX_CommandStateSet,
1129 OMX_StateExecuting, NULL);
1130 }
1131 else if (BITMASK_PRESENT(&pThis->m_flags,
1132 OMX_COMPONENT_PAUSE_PENDING))
1133 {
1134 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1135 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1136 {
1137 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1138 pThis->omx_report_error ();
1139 }
1140 }
1141 }
1142 }
1143 else
1144 {
1145 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1146 }
1147 break;
1148
1149 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1150 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1151 if (pThis->m_cb.EventHandler)
1152 {
1153 if (p2 != VDEC_S_SUCCESS)
1154 {
1155 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1156 pThis->omx_report_error ();
1157 }
1158 else
1159 {
1160 pThis->complete_pending_buffer_done_cbs();
1161 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1162 {
1163 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1164 //Send the callback now
1165 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1166 pThis->m_state = OMX_StatePause;
1167 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1168 OMX_EventCmdComplete,OMX_CommandStateSet,
1169 OMX_StatePause, NULL);
1170 }
1171 }
1172 }
1173 else
1174 {
1175 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1176 }
1177
1178 break;
1179
1180 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1181 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1182 if (pThis->m_cb.EventHandler)
1183 {
1184 if (p2 != VDEC_S_SUCCESS)
1185 {
1186 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1187 pThis->omx_report_error ();
1188 }
1189 else
1190 {
1191 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1192 {
1193 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1194 // Send the callback now
1195 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1196 pThis->m_state = OMX_StateExecuting;
1197 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1198 OMX_EventCmdComplete,OMX_CommandStateSet,
1199 OMX_StateExecuting,NULL);
1200 }
1201 }
1202 }
1203 else
1204 {
1205 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1206 }
1207
1208 break;
1209
1210 case OMX_COMPONENT_GENERATE_STOP_DONE:
1211 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1212 if (pThis->m_cb.EventHandler)
1213 {
1214 if (p2 != VDEC_S_SUCCESS)
1215 {
1216 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1217 pThis->omx_report_error ();
1218 }
1219 else
1220 {
1221 pThis->complete_pending_buffer_done_cbs();
1222 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1223 {
1224 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1225 // Send the callback now
1226 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1227 pThis->m_state = OMX_StateIdle;
1228 DEBUG_PRINT_LOW("\n Move to Idle State");
1229 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1230 OMX_EventCmdComplete,OMX_CommandStateSet,
1231 OMX_StateIdle,NULL);
1232 }
1233 }
1234 }
1235 else
1236 {
1237 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1238 }
1239
1240 break;
1241
1242 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1243 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001244
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 if (p2 == OMX_IndexParamPortDefinition) {
1246 pThis->in_reconfig = true;
1247 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001248 if (pThis->m_cb.EventHandler) {
1249 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001250 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001251 } else {
1252 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1253 }
1254
1255 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001256 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001257 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1258 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1259 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1260 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1261 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1262 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1263 else //unsupported interlace format; raise a error
1264 event = OMX_EventError;
1265 if (pThis->m_cb.EventHandler) {
1266 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1267 event, format, 0, NULL );
1268 } else {
1269 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001270 }
1271 }
1272 break;
1273
1274 case OMX_COMPONENT_GENERATE_EOS_DONE:
1275 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1276 if (pThis->m_cb.EventHandler) {
1277 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1278 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1279 } else {
1280 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1281 }
1282 pThis->prev_ts = LLONG_MAX;
1283 pThis->rst_prev_ts = true;
1284 break;
1285
1286 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1287 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1288 pThis->omx_report_error ();
1289 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001290
1291 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1292 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1293 pThis->omx_report_unsupported_setting();
1294 break;
1295
Shalaj Jain273b3e02012-06-22 19:08:03 -07001296 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1297 {
1298 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1299 if (pThis->m_cb.EventHandler) {
1300 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1301 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1302 } else {
1303 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1304 }
1305 }
1306 default:
1307 break;
1308 }
1309 }
1310 pthread_mutex_lock(&pThis->m_lock);
1311 qsize = pThis->m_cmd_q.m_size;
1312 if (pThis->m_state != OMX_StatePause)
1313 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1314 pthread_mutex_unlock(&pThis->m_lock);
1315 }
1316 while(qsize>0);
1317
1318}
1319
Vinay Kaliab9e98102013-04-02 19:31:43 -07001320int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001321{
Vinay Kaliab9e98102013-04-02 19:31:43 -07001322 int format_changed = 0;
1323 if ((height != drv_ctx.video_resolution.frame_height) ||
Vinay Kalia0321dc12013-04-08 20:45:54 -07001324 (width != drv_ctx.video_resolution.frame_width)) {
1325 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1326 width, drv_ctx.video_resolution.frame_width,
1327 height,drv_ctx.video_resolution.frame_height);
Vinay Kaliab9e98102013-04-02 19:31:43 -07001328 format_changed = 1;
Vinay Kalia0321dc12013-04-08 20:45:54 -07001329 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001330 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;
Vinay Kaliab9e98102013-04-02 19:31:43 -07001338 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001339}
1340
Arun Menon6836ba02013-02-19 20:37:40 -08001341OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1342{
1343 if (drv_ctx.video_resolution.frame_width < m_decoder_capability.min_width ||
1344 drv_ctx.video_resolution.frame_width > m_decoder_capability.max_width ||
1345 drv_ctx.video_resolution.frame_height < m_decoder_capability.min_height ||
1346 drv_ctx.video_resolution.frame_height > m_decoder_capability.max_height) {
1347 DEBUG_PRINT_ERROR("\n Unsupported video resolution width = %u height = %u\n",
1348 drv_ctx.video_resolution.frame_width,
1349 drv_ctx.video_resolution.frame_height);
1350 DEBUG_PRINT_ERROR("\n supported range width - min(%u) max(%u\n",
1351 m_decoder_capability.min_width,
1352 m_decoder_capability.max_width);
1353 DEBUG_PRINT_ERROR("\n supported range height - min(%u) max(%u)\n",
1354 m_decoder_capability.min_height,
1355 m_decoder_capability.max_height);
1356 return OMX_ErrorUnsupportedSetting;
1357 }
1358 DEBUG_PRINT_HIGH("\n video session supported\n");
1359 return OMX_ErrorNone;
1360}
1361
Shalaj Jain273b3e02012-06-22 19:08:03 -07001362/* ======================================================================
1363FUNCTION
1364 omx_vdec::ComponentInit
1365
1366DESCRIPTION
1367 Initialize the component.
1368
1369PARAMETERS
1370 ctxt -- Context information related to the self.
1371 id -- Event identifier. This could be any of the following:
1372 1. Command completion event
1373 2. Buffer done callback event
1374 3. Frame done callback event
1375
1376RETURN VALUE
1377 None.
1378
1379========================================================================== */
1380OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1381{
1382
1383 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001384 struct v4l2_fmtdesc fdesc;
1385 struct v4l2_format fmt;
1386 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001387 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001388 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001389 unsigned int alignment = 0,buffer_size = 0;
1390 int fds[2];
1391 int r,ret=0;
1392 bool codec_ambiguous = false;
Sachin Shahc82a18f2013-03-29 14:45:38 -07001393 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
1394
1395#ifdef _ANDROID_
1396 char platform_name[64];
1397 property_get("ro.board.platform", platform_name, "0");
1398 if (!strncmp(platform_name, "msm8610", 7)) {
1399 device_name = (OMX_STRING)"/dev/video/q6_dec";
1400 }
1401#endif
1402
Vinay Kalia53fa6832012-10-11 17:55:30 -07001403 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1404 struct v4l2_control control;
1405 secure_mode = true;
1406 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001407 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001408 }
1409
Sachin Shahc82a18f2013-03-29 14:45:38 -07001410 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001411
1412 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1413 drv_ctx.video_driver_fd, errno);
1414
1415 if(drv_ctx.video_driver_fd == 0){
Sachin Shahc82a18f2013-03-29 14:45:38 -07001416 DEBUG_PRINT_ERROR("Omx_vdec:: Got fd as 0 for msm_vidc_dec, Opening again\n");
1417 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418 }
1419
1420 if(drv_ctx.video_driver_fd < 0)
1421 {
1422 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1423 return OMX_ErrorInsufficientResources;
1424 }
1425 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1426 drv_ctx.frame_rate.fps_denominator = 1;
1427
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001428 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1429 if(ret < 0) {
1430 close(drv_ctx.video_driver_fd);
1431 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1432 return OMX_ErrorInsufficientResources;
1433 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001434
1435#ifdef INPUT_BUFFER_LOG
1436 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1437#endif
1438#ifdef OUTPUT_BUFFER_LOG
1439 outputBufferFile1 = fopen (outputfilename, "ab");
1440#endif
1441#ifdef OUTPUT_EXTRADATA_LOG
1442 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1443#endif
1444
1445 // Copy the role information which provides the decoder kind
1446 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001447
Shalaj Jain273b3e02012-06-22 19:08:03 -07001448 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1449 OMX_MAX_STRINGNAME_SIZE))
1450 {
1451 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1452 OMX_MAX_STRINGNAME_SIZE);
1453 drv_ctx.timestamp_adjust = true;
1454 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1455 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001456 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457 /*Initialize Start Code for MPEG4*/
1458 codec_type_parse = CODEC_TYPE_MPEG4;
1459 m_frame_parser.init_start_codes (codec_type_parse);
1460#ifdef INPUT_BUFFER_LOG
1461 strcat(inputfilename, "m4v");
1462#endif
1463 }
1464 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1465 OMX_MAX_STRINGNAME_SIZE))
1466 {
1467 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1468 OMX_MAX_STRINGNAME_SIZE);
1469 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001470 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001471 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1472 /*Initialize Start Code for MPEG2*/
1473 codec_type_parse = CODEC_TYPE_MPEG2;
1474 m_frame_parser.init_start_codes (codec_type_parse);
1475#ifdef INPUT_BUFFER_LOG
1476 strcat(inputfilename, "mpg");
1477#endif
1478 }
1479 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1480 OMX_MAX_STRINGNAME_SIZE))
1481 {
1482 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1483 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1484 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1485 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001486 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001487 codec_type_parse = CODEC_TYPE_H263;
1488 m_frame_parser.init_start_codes (codec_type_parse);
1489#ifdef INPUT_BUFFER_LOG
1490 strcat(inputfilename, "263");
1491#endif
1492 }
1493 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1494 OMX_MAX_STRINGNAME_SIZE))
1495 {
1496 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1497 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1498 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1499 output_capability = V4L2_PIX_FMT_DIVX_311;
1500 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1501 codec_type_parse = CODEC_TYPE_DIVX;
1502 m_frame_parser.init_start_codes (codec_type_parse);
1503
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001504 eRet = createDivxDrmContext();
1505 if (eRet != OMX_ErrorNone) {
1506 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1507 return eRet;
1508 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001509 }
1510 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1511 OMX_MAX_STRINGNAME_SIZE))
1512 {
1513 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1514 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1515 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1516 output_capability = V4L2_PIX_FMT_DIVX;
1517 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1518 codec_type_parse = CODEC_TYPE_DIVX;
1519 codec_ambiguous = true;
1520 m_frame_parser.init_start_codes (codec_type_parse);
1521
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001522 eRet = createDivxDrmContext();
1523 if (eRet != OMX_ErrorNone) {
1524 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1525 return eRet;
1526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001527 }
1528 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1529 OMX_MAX_STRINGNAME_SIZE))
1530 {
1531 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1532 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1533 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1534 output_capability = V4L2_PIX_FMT_DIVX;
1535 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1536 codec_type_parse = CODEC_TYPE_DIVX;
1537 codec_ambiguous = true;
1538 m_frame_parser.init_start_codes (codec_type_parse);
1539
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001540 eRet = createDivxDrmContext();
1541 if (eRet != OMX_ErrorNone) {
1542 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1543 return eRet;
1544 }
1545
Shalaj Jain273b3e02012-06-22 19:08:03 -07001546 }
1547 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1548 OMX_MAX_STRINGNAME_SIZE))
1549 {
1550 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1551 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1552 output_capability=V4L2_PIX_FMT_H264;
1553 eCompressionFormat = OMX_VIDEO_CodingAVC;
1554 codec_type_parse = CODEC_TYPE_H264;
1555 m_frame_parser.init_start_codes (codec_type_parse);
1556 m_frame_parser.init_nal_length(nal_length);
1557#ifdef INPUT_BUFFER_LOG
1558 strcat(inputfilename, "264");
1559#endif
1560 }
1561 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1562 OMX_MAX_STRINGNAME_SIZE))
1563 {
1564 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1565 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1566 eCompressionFormat = OMX_VIDEO_CodingWMV;
1567 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001568 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001569 m_frame_parser.init_start_codes (codec_type_parse);
1570#ifdef INPUT_BUFFER_LOG
1571 strcat(inputfilename, "vc1");
1572#endif
1573 }
1574 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1575 OMX_MAX_STRINGNAME_SIZE))
1576 {
1577 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1578 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1579 eCompressionFormat = OMX_VIDEO_CodingWMV;
1580 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001581 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001582 m_frame_parser.init_start_codes (codec_type_parse);
1583#ifdef INPUT_BUFFER_LOG
1584 strcat(inputfilename, "vc1");
1585#endif
1586 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001587 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1588 OMX_MAX_STRINGNAME_SIZE))
1589 {
1590 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1591 output_capability=V4L2_PIX_FMT_VP8;
1592 eCompressionFormat = OMX_VIDEO_CodingVPX;
1593 codec_type_parse = CODEC_TYPE_VP8;
1594 arbitrary_bytes = false;
1595 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001596 else
1597 {
1598 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1599 eRet = OMX_ErrorInvalidComponentName;
1600 }
1601#ifdef INPUT_BUFFER_LOG
1602 inputBufferFile1 = fopen (inputfilename, "ab");
1603#endif
1604 if (eRet == OMX_ErrorNone)
1605 {
1606
Vinay Kaliada4f4422013-01-09 10:45:03 -08001607 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1608 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1609 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1610 if (!client_buffers.set_color_format(dest_color_format)) {
1611 DEBUG_PRINT_ERROR("\n Setting color format failed");
1612 eRet = OMX_ErrorInsufficientResources;
1613 }
1614
Shalaj Jain273b3e02012-06-22 19:08:03 -07001615 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001616 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001617 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001618 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1619 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001620 }
1621
1622 struct v4l2_capability cap;
1623 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1624 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001625 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001626 /*TODO: How to handle this case */
1627 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001628 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001629 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1630 cap.bus_info, cap.version, cap.capabilities);
1631 }
1632 ret=0;
1633 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1634 fdesc.index=0;
1635 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001636 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637 fdesc.pixelformat, fdesc.flags);
1638 fdesc.index++;
1639 }
1640 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1641 fdesc.index=0;
1642 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1643
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001644 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645 fdesc.pixelformat, fdesc.flags);
1646 fdesc.index++;
1647 }
Vinay Kalia21649b32013-03-18 17:28:07 -07001648 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001649 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1650 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1651 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1652 fmt.fmt.pix_mp.pixelformat = output_capability;
1653 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1654 if (ret) {
1655 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001656 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001657 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001658 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001659 if (codec_ambiguous) {
1660 if (output_capability == V4L2_PIX_FMT_DIVX) {
1661 struct v4l2_control divx_ctrl;
1662
1663 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001664 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001666 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001667 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001668 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001669 }
1670
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001671 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001672 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673 if (ret) {
1674 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1675 }
1676 } else {
1677 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1678 }
1679 }
1680
Arun Menon6836ba02013-02-19 20:37:40 -08001681 //Get the hardware capabilities
1682 memset((void *)&frmsize,0,sizeof(frmsize));
1683 frmsize.index = 0;
1684 frmsize.pixel_format = output_capability;
1685 ret = ioctl(drv_ctx.video_driver_fd,
1686 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1687 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1688 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1689 return OMX_ErrorHardware;
1690 }
1691
1692 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1693 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1694 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1695 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1696 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1697 }
1698
Shalaj Jain273b3e02012-06-22 19:08:03 -07001699 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1700 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1701 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001702 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001703 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1704 if (ret) {
1705 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001706 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001707 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001708 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001709 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001710 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1711 control.value = 1;
1712 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1713 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1714 if (ret) {
1715 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1716 close(drv_ctx.video_driver_fd);
1717 return OMX_ErrorInsufficientResources;
1718 }
1719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001720
1721 /*Get the Buffer requirements for input and output ports*/
1722 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1723 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001724 if (secure_mode) {
1725 drv_ctx.op_buf.alignment=SZ_1M;
1726 drv_ctx.ip_buf.alignment=SZ_1M;
1727 } else {
1728 drv_ctx.op_buf.alignment=SZ_4K;
1729 drv_ctx.ip_buf.alignment=SZ_4K;
1730 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001731 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1732 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001733 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1734 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1735 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1736 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001737 drv_ctx.idr_only_decoding = 0;
1738
Vinay Kalia5713bb32013-01-16 18:39:59 -08001739 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001740#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001741 if (eRet == OMX_ErrorNone && !secure_mode)
1742 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001743#endif
Praneeth Paladugu1d654b02013-04-02 10:28:29 -07001744 if (output_capability != V4L2_PIX_FMT_VC1_ANNEX_L &&
1745 output_capability != V4L2_PIX_FMT_VC1_ANNEX_G ) {
1746 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
1747 control.value = 1;
1748 DEBUG_PRINT_HIGH("Enabling smooth streaming!\n");
1749 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
1750 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming");
1751 }
1752 }
Vinay Kalia5713bb32013-01-16 18:39:59 -08001753 eRet=get_buffer_req(&drv_ctx.ip_buf);
1754 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1755 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001756 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1757 {
1758 if (m_frame_parser.mutils == NULL)
1759 {
1760 m_frame_parser.mutils = new H264_Utils();
1761
1762 if (m_frame_parser.mutils == NULL)
1763 {
1764 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1765 eRet = OMX_ErrorInsufficientResources;
1766 }
1767 else
1768 {
1769 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1770 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1771 h264_scratch.nFilledLen = 0;
1772 h264_scratch.nOffset = 0;
1773
1774 if (h264_scratch.pBuffer == NULL)
1775 {
1776 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1777 return OMX_ErrorInsufficientResources;
1778 }
1779 m_frame_parser.mutils->initialize_frame_checking_environment();
1780 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1781 }
1782 }
1783
1784 h264_parser = new h264_stream_parser();
1785 if (!h264_parser)
1786 {
1787 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1788 eRet = OMX_ErrorInsufficientResources;
1789 }
1790 }
1791
1792 if(pipe(fds))
1793 {
1794 DEBUG_PRINT_ERROR("pipe creation failed\n");
1795 eRet = OMX_ErrorInsufficientResources;
1796 }
1797 else
1798 {
1799 int temp1[2];
1800 if(fds[0] == 0 || fds[1] == 0)
1801 {
1802 if (pipe (temp1))
1803 {
1804 DEBUG_PRINT_ERROR("pipe creation failed\n");
1805 return OMX_ErrorInsufficientResources;
1806 }
1807 //close (fds[0]);
1808 //close (fds[1]);
1809 fds[0] = temp1 [0];
1810 fds[1] = temp1 [1];
1811 }
1812 m_pipe_in = fds[0];
1813 m_pipe_out = fds[1];
1814 r = pthread_create(&msg_thread_id,0,message_thread,this);
1815
1816 if(r < 0)
1817 {
1818 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1819 eRet = OMX_ErrorInsufficientResources;
1820 }
1821 }
1822 }
1823
1824 if (eRet != OMX_ErrorNone)
1825 {
1826 DEBUG_PRINT_ERROR("\n Component Init Failed");
1827 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1828 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1829 NULL);
1830 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1831 close (drv_ctx.video_driver_fd);
1832 drv_ctx.video_driver_fd = -1;
1833 }
1834 else
1835 {
1836 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1837 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001838 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1839 return eRet;
1840}
1841
1842/* ======================================================================
1843FUNCTION
1844 omx_vdec::GetComponentVersion
1845
1846DESCRIPTION
1847 Returns the component version.
1848
1849PARAMETERS
1850 TBD.
1851
1852RETURN VALUE
1853 OMX_ErrorNone.
1854
1855========================================================================== */
1856OMX_ERRORTYPE omx_vdec::get_component_version
1857 (
1858 OMX_IN OMX_HANDLETYPE hComp,
1859 OMX_OUT OMX_STRING componentName,
1860 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1861 OMX_OUT OMX_VERSIONTYPE* specVersion,
1862 OMX_OUT OMX_UUIDTYPE* componentUUID
1863 )
1864{
1865 if(m_state == OMX_StateInvalid)
1866 {
1867 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1868 return OMX_ErrorInvalidState;
1869 }
1870 /* TBD -- Return the proper version */
1871 if (specVersion)
1872 {
1873 specVersion->nVersion = OMX_SPEC_VERSION;
1874 }
1875 return OMX_ErrorNone;
1876}
1877/* ======================================================================
1878FUNCTION
1879 omx_vdec::SendCommand
1880
1881DESCRIPTION
1882 Returns zero if all the buffers released..
1883
1884PARAMETERS
1885 None.
1886
1887RETURN VALUE
1888 true/false
1889
1890========================================================================== */
1891OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1892 OMX_IN OMX_COMMANDTYPE cmd,
1893 OMX_IN OMX_U32 param1,
1894 OMX_IN OMX_PTR cmdData
1895 )
1896{
1897 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1898 if(m_state == OMX_StateInvalid)
1899 {
1900 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1901 return OMX_ErrorInvalidState;
1902 }
1903 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1904 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1905 {
1906 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001907 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001908 return OMX_ErrorBadPortIndex;
1909 }
1910 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1911 sem_wait(&m_cmd_lock);
1912 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1913 return OMX_ErrorNone;
1914}
1915
1916/* ======================================================================
1917FUNCTION
1918 omx_vdec::SendCommand
1919
1920DESCRIPTION
1921 Returns zero if all the buffers released..
1922
1923PARAMETERS
1924 None.
1925
1926RETURN VALUE
1927 true/false
1928
1929========================================================================== */
1930OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1931 OMX_IN OMX_COMMANDTYPE cmd,
1932 OMX_IN OMX_U32 param1,
1933 OMX_IN OMX_PTR cmdData
1934 )
1935{
1936 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1937 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1938 int bFlag = 1,sem_posted = 0,ret=0;
1939
1940 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1941 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1942 m_state, eState);
1943
1944 if(cmd == OMX_CommandStateSet)
1945 {
1946 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1947 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1948 /***************************/
1949 /* Current State is Loaded */
1950 /***************************/
1951 if(m_state == OMX_StateLoaded)
1952 {
1953 if(eState == OMX_StateIdle)
1954 {
1955 //if all buffers are allocated or all ports disabled
1956 if(allocate_done() ||
1957 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1958 {
1959 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1960 }
1961 else
1962 {
1963 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1964 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1965 // Skip the event notification
1966 bFlag = 0;
1967 }
1968 }
1969 /* Requesting transition from Loaded to Loaded */
1970 else if(eState == OMX_StateLoaded)
1971 {
1972 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1973 post_event(OMX_EventError,OMX_ErrorSameState,\
1974 OMX_COMPONENT_GENERATE_EVENT);
1975 eRet = OMX_ErrorSameState;
1976 }
1977 /* Requesting transition from Loaded to WaitForResources */
1978 else if(eState == OMX_StateWaitForResources)
1979 {
1980 /* Since error is None , we will post an event
1981 at the end of this function definition */
1982 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1983 }
1984 /* Requesting transition from Loaded to Executing */
1985 else if(eState == OMX_StateExecuting)
1986 {
1987 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1988 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1989 OMX_COMPONENT_GENERATE_EVENT);
1990 eRet = OMX_ErrorIncorrectStateTransition;
1991 }
1992 /* Requesting transition from Loaded to Pause */
1993 else if(eState == OMX_StatePause)
1994 {
1995 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1996 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1997 OMX_COMPONENT_GENERATE_EVENT);
1998 eRet = OMX_ErrorIncorrectStateTransition;
1999 }
2000 /* Requesting transition from Loaded to Invalid */
2001 else if(eState == OMX_StateInvalid)
2002 {
2003 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
2004 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2005 eRet = OMX_ErrorInvalidState;
2006 }
2007 else
2008 {
2009 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
2010 eState);
2011 eRet = OMX_ErrorBadParameter;
2012 }
2013 }
2014
2015 /***************************/
2016 /* Current State is IDLE */
2017 /***************************/
2018 else if(m_state == OMX_StateIdle)
2019 {
2020 if(eState == OMX_StateLoaded)
2021 {
2022 if(release_done())
2023 {
2024 /*
2025 Since error is None , we will post an event at the end
2026 of this function definition
2027 */
2028 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2029 }
2030 else
2031 {
2032 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2033 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2034 // Skip the event notification
2035 bFlag = 0;
2036 }
2037 }
2038 /* Requesting transition from Idle to Executing */
2039 else if(eState == OMX_StateExecuting)
2040 {
2041 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2042 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2043 bFlag = 1;
2044 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2045 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002046 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002047 }
2048 /* Requesting transition from Idle to Idle */
2049 else if(eState == OMX_StateIdle)
2050 {
2051 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2052 post_event(OMX_EventError,OMX_ErrorSameState,\
2053 OMX_COMPONENT_GENERATE_EVENT);
2054 eRet = OMX_ErrorSameState;
2055 }
2056 /* Requesting transition from Idle to WaitForResources */
2057 else if(eState == OMX_StateWaitForResources)
2058 {
2059 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2060 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2061 OMX_COMPONENT_GENERATE_EVENT);
2062 eRet = OMX_ErrorIncorrectStateTransition;
2063 }
2064 /* Requesting transition from Idle to Pause */
2065 else if(eState == OMX_StatePause)
2066 {
2067 /*To pause the Video core we need to start the driver*/
2068 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2069 NULL) < */0)
2070 {
2071 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2072 omx_report_error ();
2073 eRet = OMX_ErrorHardware;
2074 }
2075 else
2076 {
2077 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2078 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2079 bFlag = 0;
2080 }
2081 }
2082 /* Requesting transition from Idle to Invalid */
2083 else if(eState == OMX_StateInvalid)
2084 {
2085 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2086 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2087 eRet = OMX_ErrorInvalidState;
2088 }
2089 else
2090 {
2091 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2092 eRet = OMX_ErrorBadParameter;
2093 }
2094 }
2095
2096 /******************************/
2097 /* Current State is Executing */
2098 /******************************/
2099 else if(m_state == OMX_StateExecuting)
2100 {
2101 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2102 /* Requesting transition from Executing to Idle */
2103 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002104 {
2105 /* Since error is None , we will post an event
2106 at the end of this function definition
2107 */
2108 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002109 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002110 if(!sem_posted)
2111 {
2112 sem_posted = 1;
2113 sem_post (&m_cmd_lock);
2114 execute_omx_flush(OMX_ALL);
2115 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002116 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002117 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002118 /* Requesting transition from Executing to Paused */
2119 else if(eState == OMX_StatePause)
2120 {
2121 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002122 m_state = OMX_StatePause;
2123 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002124 }
2125 /* Requesting transition from Executing to Loaded */
2126 else if(eState == OMX_StateLoaded)
2127 {
2128 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2129 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2130 OMX_COMPONENT_GENERATE_EVENT);
2131 eRet = OMX_ErrorIncorrectStateTransition;
2132 }
2133 /* Requesting transition from Executing to WaitForResources */
2134 else if(eState == OMX_StateWaitForResources)
2135 {
2136 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2137 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2138 OMX_COMPONENT_GENERATE_EVENT);
2139 eRet = OMX_ErrorIncorrectStateTransition;
2140 }
2141 /* Requesting transition from Executing to Executing */
2142 else if(eState == OMX_StateExecuting)
2143 {
2144 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2145 post_event(OMX_EventError,OMX_ErrorSameState,\
2146 OMX_COMPONENT_GENERATE_EVENT);
2147 eRet = OMX_ErrorSameState;
2148 }
2149 /* Requesting transition from Executing to Invalid */
2150 else if(eState == OMX_StateInvalid)
2151 {
2152 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2153 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2154 eRet = OMX_ErrorInvalidState;
2155 }
2156 else
2157 {
2158 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2159 eRet = OMX_ErrorBadParameter;
2160 }
2161 }
2162 /***************************/
2163 /* Current State is Pause */
2164 /***************************/
2165 else if(m_state == OMX_StatePause)
2166 {
2167 /* Requesting transition from Pause to Executing */
2168 if(eState == OMX_StateExecuting)
2169 {
2170 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002171 m_state = OMX_StateExecuting;
2172 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002173 }
2174 /* Requesting transition from Pause to Idle */
2175 else if(eState == OMX_StateIdle)
2176 {
2177 /* Since error is None , we will post an event
2178 at the end of this function definition */
2179 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2180 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2181 if(!sem_posted)
2182 {
2183 sem_posted = 1;
2184 sem_post (&m_cmd_lock);
2185 execute_omx_flush(OMX_ALL);
2186 }
2187 bFlag = 0;
2188 }
2189 /* Requesting transition from Pause to loaded */
2190 else if(eState == OMX_StateLoaded)
2191 {
2192 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2193 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2194 OMX_COMPONENT_GENERATE_EVENT);
2195 eRet = OMX_ErrorIncorrectStateTransition;
2196 }
2197 /* Requesting transition from Pause to WaitForResources */
2198 else if(eState == OMX_StateWaitForResources)
2199 {
2200 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2201 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2202 OMX_COMPONENT_GENERATE_EVENT);
2203 eRet = OMX_ErrorIncorrectStateTransition;
2204 }
2205 /* Requesting transition from Pause to Pause */
2206 else if(eState == OMX_StatePause)
2207 {
2208 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2209 post_event(OMX_EventError,OMX_ErrorSameState,\
2210 OMX_COMPONENT_GENERATE_EVENT);
2211 eRet = OMX_ErrorSameState;
2212 }
2213 /* Requesting transition from Pause to Invalid */
2214 else if(eState == OMX_StateInvalid)
2215 {
2216 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2217 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2218 eRet = OMX_ErrorInvalidState;
2219 }
2220 else
2221 {
2222 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2223 eRet = OMX_ErrorBadParameter;
2224 }
2225 }
2226 /***************************/
2227 /* Current State is WaitForResources */
2228 /***************************/
2229 else if(m_state == OMX_StateWaitForResources)
2230 {
2231 /* Requesting transition from WaitForResources to Loaded */
2232 if(eState == OMX_StateLoaded)
2233 {
2234 /* Since error is None , we will post an event
2235 at the end of this function definition */
2236 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2237 }
2238 /* Requesting transition from WaitForResources to WaitForResources */
2239 else if (eState == OMX_StateWaitForResources)
2240 {
2241 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2242 post_event(OMX_EventError,OMX_ErrorSameState,
2243 OMX_COMPONENT_GENERATE_EVENT);
2244 eRet = OMX_ErrorSameState;
2245 }
2246 /* Requesting transition from WaitForResources to Executing */
2247 else if(eState == OMX_StateExecuting)
2248 {
2249 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2250 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2251 OMX_COMPONENT_GENERATE_EVENT);
2252 eRet = OMX_ErrorIncorrectStateTransition;
2253 }
2254 /* Requesting transition from WaitForResources to Pause */
2255 else if(eState == OMX_StatePause)
2256 {
2257 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2258 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2259 OMX_COMPONENT_GENERATE_EVENT);
2260 eRet = OMX_ErrorIncorrectStateTransition;
2261 }
2262 /* Requesting transition from WaitForResources to Invalid */
2263 else if(eState == OMX_StateInvalid)
2264 {
2265 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2266 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2267 eRet = OMX_ErrorInvalidState;
2268 }
2269 /* Requesting transition from WaitForResources to Loaded -
2270 is NOT tested by Khronos TS */
2271
2272 }
2273 else
2274 {
2275 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2276 eRet = OMX_ErrorBadParameter;
2277 }
2278 }
2279 /********************************/
2280 /* Current State is Invalid */
2281 /*******************************/
2282 else if(m_state == OMX_StateInvalid)
2283 {
2284 /* State Transition from Inavlid to any state */
2285 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2286 || OMX_StateIdle || OMX_StateExecuting
2287 || OMX_StatePause || OMX_StateInvalid))
2288 {
2289 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2290 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2291 OMX_COMPONENT_GENERATE_EVENT);
2292 eRet = OMX_ErrorInvalidState;
2293 }
2294 }
2295 else if (cmd == OMX_CommandFlush)
2296 {
2297 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002298 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002299 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2300 {
2301 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2302 }
2303 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2304 {
2305 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2306 }
2307 if (!sem_posted){
2308 sem_posted = 1;
2309 DEBUG_PRINT_LOW("\n Set the Semaphore");
2310 sem_post (&m_cmd_lock);
2311 execute_omx_flush(param1);
2312 }
2313 bFlag = 0;
2314 }
2315 else if ( cmd == OMX_CommandPortEnable)
2316 {
2317 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002318 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002319 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2320 {
2321 m_inp_bEnabled = OMX_TRUE;
2322
2323 if( (m_state == OMX_StateLoaded &&
2324 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2325 || allocate_input_done())
2326 {
2327 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2328 OMX_COMPONENT_GENERATE_EVENT);
2329 }
2330 else
2331 {
2332 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2333 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2334 // Skip the event notification
2335 bFlag = 0;
2336 }
2337 }
2338 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2339 {
2340 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2341 m_out_bEnabled = OMX_TRUE;
2342
2343 if( (m_state == OMX_StateLoaded &&
2344 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2345 || (allocate_output_done()))
2346 {
2347 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2348 OMX_COMPONENT_GENERATE_EVENT);
2349
2350 }
2351 else
2352 {
2353 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2354 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2355 // Skip the event notification
2356 bFlag = 0;
2357 }
2358 }
2359 }
2360 else if (cmd == OMX_CommandPortDisable)
2361 {
2362 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002363 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002364 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2365 {
2366 m_inp_bEnabled = OMX_FALSE;
2367 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2368 && release_input_done())
2369 {
2370 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2371 OMX_COMPONENT_GENERATE_EVENT);
2372 }
2373 else
2374 {
2375 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2376 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2377 {
2378 if(!sem_posted)
2379 {
2380 sem_posted = 1;
2381 sem_post (&m_cmd_lock);
2382 }
2383 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2384 }
2385
2386 // Skip the event notification
2387 bFlag = 0;
2388 }
2389 }
2390 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2391 {
2392 m_out_bEnabled = OMX_FALSE;
2393 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2394 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2395 && release_output_done())
2396 {
2397 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2398 OMX_COMPONENT_GENERATE_EVENT);
2399 }
2400 else
2401 {
2402 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2403 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2404 {
2405 if (!sem_posted)
2406 {
2407 sem_posted = 1;
2408 sem_post (&m_cmd_lock);
2409 }
2410 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2411 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2412 }
2413 // Skip the event notification
2414 bFlag = 0;
2415
2416 }
2417 }
2418 }
2419 else
2420 {
2421 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2422 eRet = OMX_ErrorNotImplemented;
2423 }
2424 if(eRet == OMX_ErrorNone && bFlag)
2425 {
2426 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2427 }
2428 if(!sem_posted)
2429 {
2430 sem_post(&m_cmd_lock);
2431 }
2432
2433 return eRet;
2434}
2435
2436/* ======================================================================
2437FUNCTION
2438 omx_vdec::ExecuteOmxFlush
2439
2440DESCRIPTION
2441 Executes the OMX flush.
2442
2443PARAMETERS
2444 flushtype - input flush(1)/output flush(0)/ both.
2445
2446RETURN VALUE
2447 true/false
2448
2449========================================================================== */
2450bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2451{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002452 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002453 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002454 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002455 struct v4l2_decoder_cmd dec;
2456 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002457 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002458 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459 switch (flushType)
2460 {
2461 case OMX_CORE_INPUT_PORT_INDEX:
2462 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002463 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002464 break;
2465 case OMX_CORE_OUTPUT_PORT_INDEX:
2466 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002467 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002468 break;
2469 default:
2470 input_flush_progress = true;
2471 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002472 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2473 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002474 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002475
2476 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002477 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002478 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002479 bRet = false;
2480 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002481
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482 return bRet;
2483}
2484/*=========================================================================
2485FUNCTION : execute_output_flush
2486
2487DESCRIPTION
2488 Executes the OMX flush at OUTPUT PORT.
2489
2490PARAMETERS
2491 None.
2492
2493RETURN VALUE
2494 true/false
2495==========================================================================*/
2496bool omx_vdec::execute_output_flush()
2497{
2498 unsigned p1 = 0; // Parameter - 1
2499 unsigned p2 = 0; // Parameter - 2
2500 unsigned ident = 0;
2501 bool bRet = true;
2502
2503 /*Generate FBD for all Buffers in the FTBq*/
2504 pthread_mutex_lock(&m_lock);
2505 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2506 while (m_ftb_q.m_size)
2507 {
2508 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2509 m_ftb_q.m_size,pending_output_buffers);
2510 m_ftb_q.pop_entry(&p1,&p2,&ident);
2511 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002512 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002513 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002514 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002515 }
2516 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2517 {
2518 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2519 }
2520 }
2521 pthread_mutex_unlock(&m_lock);
2522 output_flush_progress = false;
2523
2524 if (arbitrary_bytes)
2525 {
2526 prev_ts = LLONG_MAX;
2527 rst_prev_ts = true;
2528 }
2529 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2530 return bRet;
2531}
2532/*=========================================================================
2533FUNCTION : execute_input_flush
2534
2535DESCRIPTION
2536 Executes the OMX flush at INPUT PORT.
2537
2538PARAMETERS
2539 None.
2540
2541RETURN VALUE
2542 true/false
2543==========================================================================*/
2544bool omx_vdec::execute_input_flush()
2545{
2546 unsigned i =0;
2547 unsigned p1 = 0; // Parameter - 1
2548 unsigned p2 = 0; // Parameter - 2
2549 unsigned ident = 0;
2550 bool bRet = true;
2551
2552 /*Generate EBD for all Buffers in the ETBq*/
2553 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2554
2555 pthread_mutex_lock(&m_lock);
2556 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2557 while (m_etb_q.m_size)
2558 {
2559 m_etb_q.pop_entry(&p1,&p2,&ident);
2560
2561 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2562 {
2563 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2564 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2565 }
2566 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2567 {
2568 pending_input_buffers++;
2569 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2570 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2571 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2572 }
2573 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2574 {
2575 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2576 (OMX_BUFFERHEADERTYPE *)p1);
2577 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2578 }
2579 }
2580 time_stamp_dts.flush_timestamp();
2581 /*Check if Heap Buffers are to be flushed*/
2582 if (arbitrary_bytes)
2583 {
2584 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2585 h264_scratch.nFilledLen = 0;
2586 nal_count = 0;
2587 look_ahead_nal = false;
2588 frame_count = 0;
2589 h264_last_au_ts = LLONG_MAX;
2590 h264_last_au_flags = 0;
2591 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2592 m_demux_entries = 0;
2593 DEBUG_PRINT_LOW("\n Initialize parser");
2594 if (m_frame_parser.mutils)
2595 {
2596 m_frame_parser.mutils->initialize_frame_checking_environment();
2597 }
2598
2599 while (m_input_pending_q.m_size)
2600 {
2601 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2602 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2603 }
2604
2605 if (psource_frame)
2606 {
2607 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2608 psource_frame = NULL;
2609 }
2610
2611 if (pdest_frame)
2612 {
2613 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002614 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2615 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002616 pdest_frame = NULL;
2617 }
2618 m_frame_parser.flush();
2619 }
2620 pthread_mutex_unlock(&m_lock);
2621 input_flush_progress = false;
2622 if (!arbitrary_bytes)
2623 {
2624 prev_ts = LLONG_MAX;
2625 rst_prev_ts = true;
2626 }
2627#ifdef _ANDROID_
2628 if (m_debug_timestamp)
2629 {
2630 m_timestamp_list.reset_ts_list();
2631 }
2632#endif
2633 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2634 return bRet;
2635}
2636
2637
2638/* ======================================================================
2639FUNCTION
2640 omx_vdec::SendCommandEvent
2641
2642DESCRIPTION
2643 Send the event to decoder pipe. This is needed to generate the callbacks
2644 in decoder thread context.
2645
2646PARAMETERS
2647 None.
2648
2649RETURN VALUE
2650 true/false
2651
2652========================================================================== */
2653bool omx_vdec::post_event(unsigned int p1,
2654 unsigned int p2,
2655 unsigned int id)
2656{
2657 bool bRet = false;
2658
2659
2660 pthread_mutex_lock(&m_lock);
2661
Vinay Kaliada4f4422013-01-09 10:45:03 -08002662 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002663 id == OMX_COMPONENT_GENERATE_FBD)
2664 {
2665 m_ftb_q.insert_entry(p1,p2,id);
2666 }
2667 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2668 id == OMX_COMPONENT_GENERATE_EBD ||
2669 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2670 {
2671 m_etb_q.insert_entry(p1,p2,id);
2672 }
2673 else
2674 {
2675 m_cmd_q.insert_entry(p1,p2,id);
2676 }
2677
2678 bRet = true;
2679 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2680 post_message(this, id);
2681
2682 pthread_mutex_unlock(&m_lock);
2683
2684 return bRet;
2685}
2686
2687OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2688{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002689 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002690 if(!profileLevelType)
2691 return OMX_ErrorBadParameter;
2692
2693 if(profileLevelType->nPortIndex == 0) {
2694 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2695 {
2696 if (profileLevelType->nProfileIndex == 0)
2697 {
2698 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2699 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2700
2701 }
2702 else if (profileLevelType->nProfileIndex == 1)
2703 {
2704 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2705 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2706 }
2707 else if(profileLevelType->nProfileIndex == 2)
2708 {
2709 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2710 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2711 }
2712 else
2713 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002714 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002715 profileLevelType->nProfileIndex);
2716 eRet = OMX_ErrorNoMore;
2717 }
2718 }
2719 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2720 {
2721 if (profileLevelType->nProfileIndex == 0)
2722 {
2723 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2724 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2725 }
2726 else
2727 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002728 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002729 eRet = OMX_ErrorNoMore;
2730 }
2731 }
2732 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2733 {
2734 if (profileLevelType->nProfileIndex == 0)
2735 {
2736 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2737 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2738 }
2739 else if(profileLevelType->nProfileIndex == 1)
2740 {
2741 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2742 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2743 }
2744 else
2745 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002746 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002747 eRet = OMX_ErrorNoMore;
2748 }
2749 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002750 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2751 {
2752 eRet = OMX_ErrorNoMore;
2753 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002754 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2755 {
2756 if (profileLevelType->nProfileIndex == 0)
2757 {
2758 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2759 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2760 }
2761 else if(profileLevelType->nProfileIndex == 1)
2762 {
2763 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2764 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2765 }
2766 else
2767 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002768 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002769 eRet = OMX_ErrorNoMore;
2770 }
2771 }
2772 }
2773 else
2774 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002775 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 -07002776 eRet = OMX_ErrorBadPortIndex;
2777 }
2778 return eRet;
2779}
2780
2781/* ======================================================================
2782FUNCTION
2783 omx_vdec::GetParameter
2784
2785DESCRIPTION
2786 OMX Get Parameter method implementation
2787
2788PARAMETERS
2789 <TBD>.
2790
2791RETURN VALUE
2792 Error None if successful.
2793
2794========================================================================== */
2795OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2796 OMX_IN OMX_INDEXTYPE paramIndex,
2797 OMX_INOUT OMX_PTR paramData)
2798{
2799 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2800
2801 DEBUG_PRINT_LOW("get_parameter: \n");
2802 if(m_state == OMX_StateInvalid)
2803 {
2804 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2805 return OMX_ErrorInvalidState;
2806 }
2807 if(paramData == NULL)
2808 {
2809 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2810 return OMX_ErrorBadParameter;
2811 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002812 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813 {
2814 case OMX_IndexParamPortDefinition:
2815 {
2816 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2817 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2818 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2819 eRet = update_portdef(portDefn);
2820 if (eRet == OMX_ErrorNone)
2821 m_port_def = *portDefn;
2822 break;
2823 }
2824 case OMX_IndexParamVideoInit:
2825 {
2826 OMX_PORT_PARAM_TYPE *portParamType =
2827 (OMX_PORT_PARAM_TYPE *) paramData;
2828 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2829
2830 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2831 portParamType->nSize = sizeof(portParamType);
2832 portParamType->nPorts = 2;
2833 portParamType->nStartPortNumber = 0;
2834 break;
2835 }
2836 case OMX_IndexParamVideoPortFormat:
2837 {
2838 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2839 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2840 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2841
2842 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2843 portFmt->nSize = sizeof(portFmt);
2844
2845 if (0 == portFmt->nPortIndex)
2846 {
2847 if (0 == portFmt->nIndex)
2848 {
2849 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2850 portFmt->eCompressionFormat = eCompressionFormat;
2851 }
2852 else
2853 {
2854 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2855 " NoMore compression formats\n");
2856 eRet = OMX_ErrorNoMore;
2857 }
2858 }
2859 else if (1 == portFmt->nPortIndex)
2860 {
2861 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2862
2863 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002864 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2865 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2866 else if (1 == portFmt->nIndex)
2867 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002868 else
2869 {
2870 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2871 " NoMore Color formats\n");
2872 eRet = OMX_ErrorNoMore;
2873 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002874 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002875 }
2876 else
2877 {
2878 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2879 (int)portFmt->nPortIndex);
2880 eRet = OMX_ErrorBadPortIndex;
2881 }
2882 break;
2883 }
2884 /*Component should support this port definition*/
2885 case OMX_IndexParamAudioInit:
2886 {
2887 OMX_PORT_PARAM_TYPE *audioPortParamType =
2888 (OMX_PORT_PARAM_TYPE *) paramData;
2889 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2890 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2891 audioPortParamType->nSize = sizeof(audioPortParamType);
2892 audioPortParamType->nPorts = 0;
2893 audioPortParamType->nStartPortNumber = 0;
2894 break;
2895 }
2896 /*Component should support this port definition*/
2897 case OMX_IndexParamImageInit:
2898 {
2899 OMX_PORT_PARAM_TYPE *imagePortParamType =
2900 (OMX_PORT_PARAM_TYPE *) paramData;
2901 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2902 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2903 imagePortParamType->nSize = sizeof(imagePortParamType);
2904 imagePortParamType->nPorts = 0;
2905 imagePortParamType->nStartPortNumber = 0;
2906 break;
2907
2908 }
2909 /*Component should support this port definition*/
2910 case OMX_IndexParamOtherInit:
2911 {
2912 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2913 paramIndex);
2914 eRet =OMX_ErrorUnsupportedIndex;
2915 break;
2916 }
2917 case OMX_IndexParamStandardComponentRole:
2918 {
2919 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2920 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2921 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2922 comp_role->nSize = sizeof(*comp_role);
2923
2924 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2925 paramIndex);
2926 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2927 OMX_MAX_STRINGNAME_SIZE);
2928 break;
2929 }
2930 /* Added for parameter test */
2931 case OMX_IndexParamPriorityMgmt:
2932 {
2933
2934 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2935 (OMX_PRIORITYMGMTTYPE *) paramData;
2936 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2937 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2938 priorityMgmType->nSize = sizeof(priorityMgmType);
2939
2940 break;
2941 }
2942 /* Added for parameter test */
2943 case OMX_IndexParamCompBufferSupplier:
2944 {
2945 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2946 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2947 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2948
2949 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2950 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2951 if(0 == bufferSupplierType->nPortIndex)
2952 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2953 else if (1 == bufferSupplierType->nPortIndex)
2954 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2955 else
2956 eRet = OMX_ErrorBadPortIndex;
2957
2958
2959 break;
2960 }
2961 case OMX_IndexParamVideoAvc:
2962 {
2963 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2964 paramIndex);
2965 break;
2966 }
2967 case OMX_IndexParamVideoH263:
2968 {
2969 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2970 paramIndex);
2971 break;
2972 }
2973 case OMX_IndexParamVideoMpeg4:
2974 {
2975 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2976 paramIndex);
2977 break;
2978 }
2979 case OMX_IndexParamVideoMpeg2:
2980 {
2981 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2982 paramIndex);
2983 break;
2984 }
2985 case OMX_IndexParamVideoProfileLevelQuerySupported:
2986 {
2987 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2988 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2989 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2990 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2991 break;
2992 }
2993#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2994 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2995 {
2996 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2997 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2998 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2999
3000 if(secure_mode) {
3001 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05303002 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003003 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08003004 nativeBuffersUsage->nUsage =
3005 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
3006 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003007 }
3008 } else {
3009 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
3010 eRet = OMX_ErrorBadParameter;
3011 }
3012 }
3013 break;
3014#endif
3015
3016 default:
3017 {
3018 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
3019 eRet =OMX_ErrorUnsupportedIndex;
3020 }
3021
3022 }
3023
3024 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3025 drv_ctx.video_resolution.frame_width,
3026 drv_ctx.video_resolution.frame_height,
3027 drv_ctx.video_resolution.stride,
3028 drv_ctx.video_resolution.scan_lines);
3029
3030 return eRet;
3031}
3032
3033#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3034OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3035{
3036 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3037 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3038 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3039
3040 if((params == NULL) ||
3041 (params->nativeBuffer == NULL) ||
3042 (params->nativeBuffer->handle == NULL) ||
3043 !m_enable_android_native_buffers)
3044 return OMX_ErrorBadParameter;
3045 m_use_android_native_buffers = OMX_TRUE;
3046 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3047 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3048 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3049 OMX_U8 *buffer = NULL;
3050 if(!secure_mode) {
3051 buffer = (OMX_U8*)mmap(0, handle->size,
3052 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3053 if(buffer == MAP_FAILED) {
3054 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3055 return OMX_ErrorInsufficientResources;
3056 }
3057 }
3058 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3059 } else {
3060 eRet = OMX_ErrorBadParameter;
3061 }
3062 return eRet;
3063}
3064#endif
3065/* ======================================================================
3066FUNCTION
3067 omx_vdec::Setparameter
3068
3069DESCRIPTION
3070 OMX Set Parameter method implementation.
3071
3072PARAMETERS
3073 <TBD>.
3074
3075RETURN VALUE
3076 OMX Error None if successful.
3077
3078========================================================================== */
3079OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3080 OMX_IN OMX_INDEXTYPE paramIndex,
3081 OMX_IN OMX_PTR paramData)
3082{
3083 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003084 int ret=0;
3085 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003086 if(m_state == OMX_StateInvalid)
3087 {
3088 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3089 return OMX_ErrorInvalidState;
3090 }
3091 if(paramData == NULL)
3092 {
3093 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3094 return OMX_ErrorBadParameter;
3095 }
3096 if((m_state != OMX_StateLoaded) &&
3097 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3098 (m_out_bEnabled == OMX_TRUE) &&
3099 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3100 (m_inp_bEnabled == OMX_TRUE)) {
3101 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3102 return OMX_ErrorIncorrectStateOperation;
3103 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003104 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003105 {
3106 case OMX_IndexParamPortDefinition:
3107 {
3108 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3109 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3110 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3111 //been called.
3112 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3113 (int)portDefn->format.video.nFrameHeight,
3114 (int)portDefn->format.video.nFrameWidth);
3115 if(OMX_DirOutput == portDefn->eDir)
3116 {
3117 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3118 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003119 unsigned int buffer_size;
3120 if (!client_buffers.get_buffer_req(buffer_size)) {
3121 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003122 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003123 } else {
3124 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3125 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3126 {
3127 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3128 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3129 eRet = set_buffer_req(&drv_ctx.op_buf);
3130 if (eRet == OMX_ErrorNone)
3131 m_port_def = *portDefn;
3132 }
3133 else
3134 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003135 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003136 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3137 portDefn->nBufferCountActual, portDefn->nBufferSize);
3138 eRet = OMX_ErrorBadParameter;
3139 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003140 }
3141 }
3142 else if(OMX_DirInput == portDefn->eDir)
3143 {
3144 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3145 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3146 {
3147 // Frame rate only should be set if this is a "known value" or to
3148 // activate ts prediction logic (arbitrary mode only) sending input
3149 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003150 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003151 portDefn->format.video.xFramerate >> 16);
3152 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3153 drv_ctx.frame_rate.fps_denominator);
3154 if(!drv_ctx.frame_rate.fps_numerator)
3155 {
3156 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3157 drv_ctx.frame_rate.fps_numerator = 30;
3158 }
3159 if(drv_ctx.frame_rate.fps_denominator)
3160 drv_ctx.frame_rate.fps_numerator = (int)
3161 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3162 drv_ctx.frame_rate.fps_denominator = 1;
3163 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3164 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003165 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003166 frm_int, drv_ctx.frame_rate.fps_numerator /
3167 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07003168 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003169 }
3170 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3171 if(drv_ctx.video_resolution.frame_height !=
3172 portDefn->format.video.nFrameHeight ||
3173 drv_ctx.video_resolution.frame_width !=
3174 portDefn->format.video.nFrameWidth)
3175 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003176 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003177 portDefn->format.video.nFrameWidth,
3178 portDefn->format.video.nFrameHeight);
3179 if (portDefn->format.video.nFrameHeight != 0x0 &&
3180 portDefn->format.video.nFrameWidth != 0x0)
3181 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003182 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003183 portDefn->format.video.nFrameHeight,
3184 portDefn->format.video.nFrameWidth,
3185 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003186 eRet = is_video_session_supported();
3187 if (eRet)
3188 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003189 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3190 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3191 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3192 fmt.fmt.pix_mp.pixelformat = output_capability;
3193 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);
3194 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003195 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003196 {
3197 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3198 eRet = OMX_ErrorUnsupportedSetting;
3199 }
3200 else
3201 eRet = get_buffer_req(&drv_ctx.op_buf);
3202 }
3203 }
3204 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003205 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003206 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003207 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003208 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003209 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3210 (~(buffer_prop->alignment - 1));
3211 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003212 }
3213 else
3214 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003215 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003216 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3217 portDefn->nBufferCountActual, portDefn->nBufferSize);
3218 eRet = OMX_ErrorBadParameter;
3219 }
3220 }
3221 else if (portDefn->eDir == OMX_DirMax)
3222 {
3223 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3224 (int)portDefn->nPortIndex);
3225 eRet = OMX_ErrorBadPortIndex;
3226 }
3227 }
3228 break;
3229 case OMX_IndexParamVideoPortFormat:
3230 {
3231 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3232 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3233 int ret=0;
3234 struct v4l2_format fmt;
3235 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3236 portFmt->eColorFormat);
3237
3238 if(1 == portFmt->nPortIndex)
3239 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003240 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3241 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3242 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3243 fmt.fmt.pix_mp.pixelformat = capture_capability;
3244 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003245 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3246 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003247 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003248 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003249 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003250 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003251 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3252 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3253 else
3254 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003255
Vinay Kaliada4f4422013-01-09 10:45:03 -08003256 if(eRet == OMX_ErrorNone)
3257 {
3258 drv_ctx.output_format = op_format;
3259 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3260 if(ret)
3261 {
3262 DEBUG_PRINT_ERROR("\n Set output format failed");
3263 eRet = OMX_ErrorUnsupportedSetting;
3264 /*TODO: How to handle this case */
3265 }
3266 else
3267 {
3268 eRet = get_buffer_req(&drv_ctx.op_buf);
3269 }
3270 }
3271 if (eRet == OMX_ErrorNone){
3272 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3273 DEBUG_PRINT_ERROR("\n Set color format failed");
3274 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003275 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003276 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003277 }
3278 }
3279 break;
3280
3281 case OMX_QcomIndexPortDefn:
3282 {
3283 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3284 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003285 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003286 portFmt->nFramePackingFormat);
3287
3288 /* Input port */
3289 if (portFmt->nPortIndex == 0)
3290 {
3291 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3292 {
3293 if(secure_mode) {
3294 arbitrary_bytes = false;
3295 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3296 eRet = OMX_ErrorUnsupportedSetting;
3297 } else {
3298 arbitrary_bytes = true;
3299 }
3300 }
3301 else if (portFmt->nFramePackingFormat ==
3302 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3303 {
3304 arbitrary_bytes = false;
3305 }
3306 else
3307 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003308 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003309 portFmt->nFramePackingFormat);
3310 eRet = OMX_ErrorUnsupportedSetting;
3311 }
3312 }
3313 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3314 {
3315 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3316 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3317 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3318 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3319 {
3320 m_out_mem_region_smi = OMX_TRUE;
3321 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3322 {
3323 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3324 m_use_output_pmem = OMX_TRUE;
3325 }
3326 }
3327 }
3328 }
3329 break;
3330
3331 case OMX_IndexParamStandardComponentRole:
3332 {
3333 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3334 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3335 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3336 comp_role->cRole);
3337
3338 if((m_state == OMX_StateLoaded)&&
3339 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3340 {
3341 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3342 }
3343 else
3344 {
3345 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3346 return OMX_ErrorIncorrectStateOperation;
3347 }
3348
3349 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3350 {
3351 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3352 {
3353 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3354 }
3355 else
3356 {
3357 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3358 eRet =OMX_ErrorUnsupportedSetting;
3359 }
3360 }
3361 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3362 {
3363 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3364 {
3365 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3366 }
3367 else
3368 {
3369 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3370 eRet = OMX_ErrorUnsupportedSetting;
3371 }
3372 }
3373 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3374 {
3375 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3376 {
3377 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3378 }
3379 else
3380 {
3381 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3382 eRet =OMX_ErrorUnsupportedSetting;
3383 }
3384 }
3385 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3386 {
3387 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3388 {
3389 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3390 }
3391 else
3392 {
3393 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3394 eRet = OMX_ErrorUnsupportedSetting;
3395 }
3396 }
3397 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3398 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3399 )
3400 {
3401 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3402 {
3403 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3404 }
3405 else
3406 {
3407 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3408 eRet =OMX_ErrorUnsupportedSetting;
3409 }
3410 }
3411 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3412 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3413 )
3414 {
3415 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3416 {
3417 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3418 }
3419 else
3420 {
3421 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3422 eRet =OMX_ErrorUnsupportedSetting;
3423 }
3424 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003425 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3426 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003427 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3428 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003429 {
3430 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3431 }
3432 else
3433 {
3434 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3435 eRet = OMX_ErrorUnsupportedSetting;
3436 }
3437 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003438 else
3439 {
3440 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3441 eRet = OMX_ErrorInvalidComponentName;
3442 }
3443 break;
3444 }
3445
3446 case OMX_IndexParamPriorityMgmt:
3447 {
3448 if(m_state != OMX_StateLoaded)
3449 {
3450 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3451 return OMX_ErrorIncorrectStateOperation;
3452 }
3453 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003454 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003455 priorityMgmtype->nGroupID);
3456
Shalaj Jainaf08f302013-03-18 13:15:35 -07003457 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003458 priorityMgmtype->nGroupPriority);
3459
3460 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3461 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3462
3463 break;
3464 }
3465
3466 case OMX_IndexParamCompBufferSupplier:
3467 {
3468 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3469 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3470 bufferSupplierType->eBufferSupplier);
3471 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3472 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3473
3474 else
3475
3476 eRet = OMX_ErrorBadPortIndex;
3477
3478 break;
3479
3480 }
3481 case OMX_IndexParamVideoAvc:
3482 {
3483 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3484 paramIndex);
3485 break;
3486 }
3487 case OMX_IndexParamVideoH263:
3488 {
3489 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3490 paramIndex);
3491 break;
3492 }
3493 case OMX_IndexParamVideoMpeg4:
3494 {
3495 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3496 paramIndex);
3497 break;
3498 }
3499 case OMX_IndexParamVideoMpeg2:
3500 {
3501 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3502 paramIndex);
3503 break;
3504 }
3505 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3506 {
3507 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3508 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003509 struct v4l2_control control;
3510 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003511 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3512 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003513 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3514 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3515 }
3516 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3517 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003518 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003519 }
3520 else
3521 eRet = OMX_ErrorBadParameter;
3522 if (eRet == OMX_ErrorNone)
3523 {
3524 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3525 control.value = pic_order;
3526 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3527 if(rc)
3528 {
3529 DEBUG_PRINT_ERROR("\n Set picture order failed");
3530 eRet = OMX_ErrorUnsupportedSetting;
3531 }
3532 }
3533 break;
3534 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003535 case OMX_QcomIndexParamConcealMBMapExtraData:
3536 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003537 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, 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_QcomIndexParamFrameInfoExtraData:
3545 {
3546 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003547 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003548 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3549 else {
3550 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3551 eRet = OMX_ErrorUnsupportedSetting;
3552 }
3553 break;
3554 }
3555 case OMX_QcomIndexParamInterlaceExtraData:
3556 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003557 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003558 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3559 else {
3560 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3561 eRet = OMX_ErrorUnsupportedSetting;
3562 }
3563 break;
3564 case OMX_QcomIndexParamH264TimeInfo:
3565 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003566 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003567 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3568 else {
3569 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3570 eRet = OMX_ErrorUnsupportedSetting;
3571 }
3572 break;
3573 case OMX_QcomIndexParamVideoDivx:
3574 {
3575 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003576 }
3577 break;
3578 case OMX_QcomIndexPlatformPvt:
3579 {
3580 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3581 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3582 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3583 {
3584 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3585 eRet = OMX_ErrorUnsupportedSetting;
3586 }
3587 else
3588 {
3589 m_out_pvt_entry_pmem = OMX_TRUE;
3590 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3591 {
3592 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3593 m_use_output_pmem = OMX_TRUE;
3594 }
3595 }
3596
3597 }
3598 break;
3599 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3600 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003601 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3602 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3603 struct v4l2_control control;
3604 int rc;
3605 drv_ctx.idr_only_decoding = 1;
3606 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3607 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3608 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3609 if(rc)
3610 {
3611 DEBUG_PRINT_ERROR("\n Set picture order failed");
3612 eRet = OMX_ErrorUnsupportedSetting;
3613 } else {
3614 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3615 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3616 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3617 if(rc)
3618 {
3619 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3620 eRet = OMX_ErrorUnsupportedSetting;
3621 }
3622 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003623 }
3624 break;
3625
3626 case OMX_QcomIndexParamIndexExtraDataType:
3627 {
3628 if(!secure_mode) {
3629 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3630 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3631 (extradataIndexType->bEnabled == OMX_TRUE) &&
3632 (extradataIndexType->nPortIndex == 1))
3633 {
3634 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003635 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003636
Shalaj Jain273b3e02012-06-22 19:08:03 -07003637 }
3638 }
3639 }
3640 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003641 case OMX_QcomIndexParamEnableSmoothStreaming:
3642 {
3643 struct v4l2_control control;
3644 struct v4l2_format fmt;
3645 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3646 control.value = 1;
3647 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3648 if(rc < 0) {
3649 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3650 eRet = OMX_ErrorHardware;
3651 }
3652 }
3653 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003654#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3655 /* Need to allow following two set_parameters even in Idle
3656 * state. This is ANDROID architecture which is not in sync
3657 * with openmax standard. */
3658 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3659 {
3660 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3661 if(enableNativeBuffers) {
3662 m_enable_android_native_buffers = enableNativeBuffers->enable;
3663 }
3664 }
3665 break;
3666 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3667 {
3668 eRet = use_android_native_buffer(hComp, paramData);
3669 }
3670 break;
3671#endif
3672 case OMX_QcomIndexParamEnableTimeStampReorder:
3673 {
3674 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003675 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003676 if (reorder->bEnable == OMX_TRUE) {
3677 frm_int =0;
3678 time_stamp_dts.set_timestamp_reorder_mode(true);
3679 }
3680 else
3681 time_stamp_dts.set_timestamp_reorder_mode(false);
3682 } else {
3683 time_stamp_dts.set_timestamp_reorder_mode(false);
3684 if (reorder->bEnable == OMX_TRUE)
3685 {
3686 eRet = OMX_ErrorUnsupportedSetting;
3687 }
3688 }
3689 }
3690 break;
3691 default:
3692 {
3693 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3694 eRet = OMX_ErrorUnsupportedIndex;
3695 }
3696 }
3697 return eRet;
3698}
3699
3700/* ======================================================================
3701FUNCTION
3702 omx_vdec::GetConfig
3703
3704DESCRIPTION
3705 OMX Get Config Method implementation.
3706
3707PARAMETERS
3708 <TBD>.
3709
3710RETURN VALUE
3711 OMX Error None if successful.
3712
3713========================================================================== */
3714OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3715 OMX_IN OMX_INDEXTYPE configIndex,
3716 OMX_INOUT OMX_PTR configData)
3717{
3718 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3719
3720 if (m_state == OMX_StateInvalid)
3721 {
3722 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3723 return OMX_ErrorInvalidState;
3724 }
3725
Shalaj Jain286b0062013-02-21 20:35:48 -08003726 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003727 {
3728 case OMX_QcomIndexConfigInterlaced:
3729 {
3730 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3731 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3732 if (configFmt->nPortIndex == 1)
3733 {
3734 if (configFmt->nIndex == 0)
3735 {
3736 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3737 }
3738 else if (configFmt->nIndex == 1)
3739 {
3740 configFmt->eInterlaceType =
3741 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3742 }
3743 else if (configFmt->nIndex == 2)
3744 {
3745 configFmt->eInterlaceType =
3746 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3747 }
3748 else
3749 {
3750 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3751 " NoMore Interlaced formats\n");
3752 eRet = OMX_ErrorNoMore;
3753 }
3754
3755 }
3756 else
3757 {
3758 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3759 (int)configFmt->nPortIndex);
3760 eRet = OMX_ErrorBadPortIndex;
3761 }
3762 break;
3763 }
3764 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3765 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003766 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3767 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003768 decoderinstances->nNumOfInstances = 16;
3769 /*TODO: How to handle this case */
3770 break;
3771 }
3772 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3773 {
3774 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3775 {
3776 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3777 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3778 h264_parser->get_frame_pack_data(configFmt);
3779 }
3780 else
3781 {
3782 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3783 }
3784 break;
3785 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003786 case OMX_IndexConfigCommonOutputCrop:
3787 {
3788 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3789 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3790 break;
3791 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003792 default:
3793 {
3794 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3795 eRet = OMX_ErrorBadParameter;
3796 }
3797
3798 }
3799
3800 return eRet;
3801}
3802
3803/* ======================================================================
3804FUNCTION
3805 omx_vdec::SetConfig
3806
3807DESCRIPTION
3808 OMX Set Config method implementation
3809
3810PARAMETERS
3811 <TBD>.
3812
3813RETURN VALUE
3814 OMX Error None if successful.
3815========================================================================== */
3816OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3817 OMX_IN OMX_INDEXTYPE configIndex,
3818 OMX_IN OMX_PTR configData)
3819{
3820 if(m_state == OMX_StateInvalid)
3821 {
3822 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3823 return OMX_ErrorInvalidState;
3824 }
3825
3826 OMX_ERRORTYPE ret = OMX_ErrorNone;
3827 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3828
3829 DEBUG_PRINT_LOW("\n Set Config Called");
3830
3831 if (m_state == OMX_StateExecuting)
3832 {
3833 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3834 return ret;
3835 }
3836
Shalaj Jain286b0062013-02-21 20:35:48 -08003837 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003838 {
3839 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3840 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3841 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3842 {
3843 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3844 OMX_U32 extra_size;
3845 // Parsing done here for the AVC atom is definitely not generic
3846 // Currently this piece of code is working, but certainly
3847 // not tested with all .mp4 files.
3848 // Incase of failure, we might need to revisit this
3849 // for a generic piece of code.
3850
3851 // Retrieve size of NAL length field
3852 // byte #4 contains the size of NAL lenght field
3853 nal_length = (config->pData[4] & 0x03) + 1;
3854
3855 extra_size = 0;
3856 if (nal_length > 2)
3857 {
3858 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3859 extra_size = (nal_length - 2) * 2;
3860 }
3861
3862 // SPS starts from byte #6
3863 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3864 OMX_U8 *pDestBuf;
3865 m_vendor_config.nPortIndex = config->nPortIndex;
3866
3867 // minus 6 --> SPS starts from byte #6
3868 // minus 1 --> picture param set byte to be ignored from avcatom
3869 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3870 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3871 OMX_U32 len;
3872 OMX_U8 index = 0;
3873 // case where SPS+PPS is sent as part of set_config
3874 pDestBuf = m_vendor_config.pData;
3875
Shalaj Jainaf08f302013-03-18 13:15:35 -07003876 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003877 m_vendor_config.nPortIndex,
3878 m_vendor_config.nDataSize,
3879 m_vendor_config.pData);
3880 while (index < 2)
3881 {
3882 uint8 *psize;
3883 len = *pSrcBuf;
3884 len = len << 8;
3885 len |= *(pSrcBuf + 1);
3886 psize = (uint8 *) & len;
3887 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003888 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003889 {
3890 pDestBuf[i] = psize[nal_length - 1 - i];
3891 }
3892 //memcpy(pDestBuf,pSrcBuf,(len+2));
3893 pDestBuf += len + nal_length;
3894 pSrcBuf += len + 2;
3895 index++;
3896 pSrcBuf++; // skip picture param set
3897 len = 0;
3898 }
3899 }
3900 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3901 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3902 {
3903 m_vendor_config.nPortIndex = config->nPortIndex;
3904 m_vendor_config.nDataSize = config->nDataSize;
3905 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3906 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3907 }
3908 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3909 {
3910 if(m_vendor_config.pData)
3911 {
3912 free(m_vendor_config.pData);
3913 m_vendor_config.pData = NULL;
3914 m_vendor_config.nDataSize = 0;
3915 }
3916
3917 if (((*((OMX_U32 *) config->pData)) &
3918 VC1_SP_MP_START_CODE_MASK) ==
3919 VC1_SP_MP_START_CODE)
3920 {
3921 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3922 m_vendor_config.nPortIndex = config->nPortIndex;
3923 m_vendor_config.nDataSize = config->nDataSize;
3924 m_vendor_config.pData =
3925 (OMX_U8 *) malloc(config->nDataSize);
3926 memcpy(m_vendor_config.pData, config->pData,
3927 config->nDataSize);
3928 m_vc1_profile = VC1_SP_MP_RCV;
3929 }
3930 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3931 {
3932 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3933 m_vendor_config.nPortIndex = config->nPortIndex;
3934 m_vendor_config.nDataSize = config->nDataSize;
3935 m_vendor_config.pData =
3936 (OMX_U8 *) malloc((config->nDataSize));
3937 memcpy(m_vendor_config.pData, config->pData,
3938 config->nDataSize);
3939 m_vc1_profile = VC1_AP;
3940 }
3941 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3942 {
3943 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3944 m_vendor_config.nPortIndex = config->nPortIndex;
3945 m_vendor_config.nDataSize = config->nDataSize;
3946 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3947 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3948 m_vc1_profile = VC1_SP_MP_RCV;
3949 }
3950 else
3951 {
3952 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3953 }
3954 }
3955 return ret;
3956 }
3957 else if (configIndex == OMX_IndexConfigVideoNalSize)
3958 {
3959
3960 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3961 nal_length = pNal->nNaluBytes;
3962 m_frame_parser.init_nal_length(nal_length);
3963 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3964 return ret;
3965 }
3966
3967 return OMX_ErrorNotImplemented;
3968}
3969
3970/* ======================================================================
3971FUNCTION
3972 omx_vdec::GetExtensionIndex
3973
3974DESCRIPTION
3975 OMX GetExtensionIndex method implementaion. <TBD>
3976
3977PARAMETERS
3978 <TBD>.
3979
3980RETURN VALUE
3981 OMX Error None if everything successful.
3982
3983========================================================================== */
3984OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3985 OMX_IN OMX_STRING paramName,
3986 OMX_OUT OMX_INDEXTYPE* indexType)
3987{
3988 if(m_state == OMX_StateInvalid)
3989 {
3990 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3991 return OMX_ErrorInvalidState;
3992 }
3993 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3994 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3995 }
3996 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3997 {
3998 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3999 }
4000#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4001 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
4002 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
4003 }
4004 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
4005 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
4006 }
4007 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
4008 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
4009 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
4010 }
4011 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
4012 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4013 }
4014#endif
4015 else {
4016 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
4017 return OMX_ErrorNotImplemented;
4018 }
4019 return OMX_ErrorNone;
4020}
4021
4022/* ======================================================================
4023FUNCTION
4024 omx_vdec::GetState
4025
4026DESCRIPTION
4027 Returns the state information back to the caller.<TBD>
4028
4029PARAMETERS
4030 <TBD>.
4031
4032RETURN VALUE
4033 Error None if everything is successful.
4034========================================================================== */
4035OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4036 OMX_OUT OMX_STATETYPE* state)
4037{
4038 *state = m_state;
4039 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4040 return OMX_ErrorNone;
4041}
4042
4043/* ======================================================================
4044FUNCTION
4045 omx_vdec::ComponentTunnelRequest
4046
4047DESCRIPTION
4048 OMX Component Tunnel Request method implementation. <TBD>
4049
4050PARAMETERS
4051 None.
4052
4053RETURN VALUE
4054 OMX Error None if everything successful.
4055
4056========================================================================== */
4057OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4058 OMX_IN OMX_U32 port,
4059 OMX_IN OMX_HANDLETYPE peerComponent,
4060 OMX_IN OMX_U32 peerPort,
4061 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4062{
4063 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4064 return OMX_ErrorNotImplemented;
4065}
4066
4067/* ======================================================================
4068FUNCTION
4069 omx_vdec::UseOutputBuffer
4070
4071DESCRIPTION
4072 Helper function for Use buffer in the input pin
4073
4074PARAMETERS
4075 None.
4076
4077RETURN VALUE
4078 true/false
4079
4080========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004081OMX_ERRORTYPE omx_vdec::allocate_extradata()
4082{
4083#ifdef USE_ION
4084 if (drv_ctx.extradata_info.buffer_size) {
4085 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4086 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4087 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4088 free_ion_memory(&drv_ctx.extradata_info.ion);
4089 }
4090 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4091 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4092 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4093 &drv_ctx.extradata_info.ion.ion_alloc_data,
4094 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4095 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4096 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4097 return OMX_ErrorInsufficientResources;
4098 }
4099 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4100 drv_ctx.extradata_info.size,
4101 PROT_READ|PROT_WRITE, MAP_SHARED,
4102 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4103 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4104 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4105 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4106 free_ion_memory(&drv_ctx.extradata_info.ion);
4107 return OMX_ErrorInsufficientResources;
4108 }
4109 }
4110#endif
4111 return OMX_ErrorNone;
4112}
4113
4114void omx_vdec::free_extradata() {
4115#ifdef USE_ION
4116 if (drv_ctx.extradata_info.uaddr) {
4117 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4118 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4119 free_ion_memory(&drv_ctx.extradata_info.ion);
4120 }
4121 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4122#endif
4123}
4124
Shalaj Jain273b3e02012-06-22 19:08:03 -07004125OMX_ERRORTYPE omx_vdec::use_output_buffer(
4126 OMX_IN OMX_HANDLETYPE hComp,
4127 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4128 OMX_IN OMX_U32 port,
4129 OMX_IN OMX_PTR appData,
4130 OMX_IN OMX_U32 bytes,
4131 OMX_IN OMX_U8* buffer)
4132{
4133 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4134 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4135 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004136 struct vdec_setbuffer_cmd setbuffers;
4137 OMX_PTR privateAppData = NULL;
4138 private_handle_t *handle = NULL;
4139 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004140 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004141 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4142 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004143
Shalaj Jain273b3e02012-06-22 19:08:03 -07004144 if (!m_out_mem_ptr) {
4145 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4146 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004147 if (eRet == OMX_ErrorNone)
4148 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004149 }
4150
4151 if (eRet == OMX_ErrorNone) {
4152 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4153 if(BITMASK_ABSENT(&m_out_bm_count,i))
4154 {
4155 break;
4156 }
4157 }
4158 }
4159
4160 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004161 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004162 eRet = OMX_ErrorInsufficientResources;
4163 }
4164
4165 if (eRet == OMX_ErrorNone) {
4166#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4167 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004168 if (m_use_android_native_buffers) {
4169 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4170 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4171 handle = (private_handle_t *)nBuf->handle;
4172 privateAppData = params->pAppPrivate;
4173 } else {
4174 handle = (private_handle_t *)buff;
4175 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004176 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004177
4178 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4179 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4180 " expected %u, got %lu",
4181 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4182 return OMX_ErrorBadParameter;
4183 }
4184
4185 if (!m_use_android_native_buffers) {
4186 if (!secure_mode) {
4187 buff = (OMX_U8*)mmap(0, handle->size,
4188 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4189 if (buff == MAP_FAILED) {
4190 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4191 return OMX_ErrorInsufficientResources;
4192 }
4193 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004194 }
4195#if defined(_ANDROID_ICS_)
4196 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004197 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004198#endif
4199 if(!handle) {
4200 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4201 return OMX_ErrorBadParameter;
4202 }
4203 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4204 drv_ctx.ptr_outputbuffer[i].offset = 0;
4205 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4206 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4207 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4208 } else
4209#endif
4210
4211 if (!ouput_egl_buffers && !m_use_output_pmem) {
4212#ifdef USE_ION
4213 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4214 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4215 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004216 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004217 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004218 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 -07004219 return OMX_ErrorInsufficientResources;
4220 }
4221 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4222 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4223#else
4224 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4225 open (MEM_DEVICE,O_RDWR);
4226
4227 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004228 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 -07004229 return OMX_ErrorInsufficientResources;
4230 }
4231
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004232 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004233 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4234 {
4235 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4236 open (MEM_DEVICE,O_RDWR);
4237 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004238 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 -07004239 return OMX_ErrorInsufficientResources;
4240 }
4241 }
4242
4243 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4244 drv_ctx.op_buf.buffer_size,
4245 drv_ctx.op_buf.alignment))
4246 {
4247 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4248 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4249 return OMX_ErrorInsufficientResources;
4250 }
4251#endif
4252 if(!secure_mode) {
4253 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4254 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4255 PROT_READ|PROT_WRITE, MAP_SHARED,
4256 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4257 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4258 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4259#ifdef USE_ION
4260 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4261#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004262 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004263 return OMX_ErrorInsufficientResources;
4264 }
4265 }
4266 drv_ctx.ptr_outputbuffer[i].offset = 0;
4267 privateAppData = appData;
4268 }
4269 else {
4270
4271 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4272 if (!appData || !bytes ) {
4273 if(!secure_mode && !buffer) {
4274 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4275 return OMX_ErrorBadParameter;
4276 }
4277 }
4278
4279 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4280 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4281 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4282 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4283 !pmem_list->nEntries ||
4284 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4285 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4286 return OMX_ErrorBadParameter;
4287 }
4288 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4289 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004290 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291 pmem_info->pmem_fd);
4292 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4293 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4294 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4295 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4296 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4297 privateAppData = appData;
4298 }
4299 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4300 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4301
4302 *bufferHdr = (m_out_mem_ptr + i );
4303 if(secure_mode)
4304 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4305 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4306 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4307 sizeof (vdec_bufferpayload));
4308
Shalaj Jain286b0062013-02-21 20:35:48 -08004309 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4310 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4311 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004312
4313 buf.index = i;
4314 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4315 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004316 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004317 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4318 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004319 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4320 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4321 plane[0].data_offset = 0;
4322 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4323 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4324 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4325 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4326#ifdef USE_ION
4327 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4328#endif
4329 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4330 plane[extra_idx].data_offset = 0;
4331 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4332 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4333 return OMX_ErrorBadParameter;
4334 }
4335 buf.m.planes = plane;
4336 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004337
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004338 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4339 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4340 /*TODO: How to handle this case */
4341 return OMX_ErrorInsufficientResources;
4342 }
4343
4344 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4345 enum v4l2_buf_type buf_type;
4346 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4347 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4348 return OMX_ErrorInsufficientResources;
4349 } else {
4350 streaming[CAPTURE_PORT] = true;
4351 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4352 }
4353 }
4354
Shalaj Jain273b3e02012-06-22 19:08:03 -07004355 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004356 if (m_enable_android_native_buffers) {
4357 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4358 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4359 } else {
4360 (*bufferHdr)->pBuffer = buff;
4361 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004362 (*bufferHdr)->pAppPrivate = privateAppData;
4363 BITMASK_SET(&m_out_bm_count,i);
4364 }
4365 return eRet;
4366}
4367
4368/* ======================================================================
4369FUNCTION
4370 omx_vdec::use_input_heap_buffers
4371
4372DESCRIPTION
4373 OMX Use Buffer Heap allocation method implementation.
4374
4375PARAMETERS
4376 <TBD>.
4377
4378RETURN VALUE
4379 OMX Error None , if everything successful.
4380
4381========================================================================== */
4382OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4383 OMX_IN OMX_HANDLETYPE hComp,
4384 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4385 OMX_IN OMX_U32 port,
4386 OMX_IN OMX_PTR appData,
4387 OMX_IN OMX_U32 bytes,
4388 OMX_IN OMX_U8* buffer)
4389{
4390 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4391 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4392 if(!m_inp_heap_ptr)
4393 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4394 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4395 drv_ctx.ip_buf.actualcount);
4396 if(!m_phdr_pmem_ptr)
4397 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4398 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4399 drv_ctx.ip_buf.actualcount);
4400 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4401 {
4402 DEBUG_PRINT_ERROR("Insufficent memory");
4403 eRet = OMX_ErrorInsufficientResources;
4404 }
4405 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4406 {
4407 input_use_buffer = true;
4408 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4409 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4410 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4411 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4412 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4413 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4414 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4415 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4416 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 -08004417 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4418 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004419 {
4420 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4421 return OMX_ErrorInsufficientResources;
4422 }
4423 m_in_alloc_cnt++;
4424 }
4425 else
4426 {
4427 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4428 eRet = OMX_ErrorInsufficientResources;
4429 }
4430 return eRet;
4431}
4432
4433/* ======================================================================
4434FUNCTION
4435 omx_vdec::UseBuffer
4436
4437DESCRIPTION
4438 OMX Use Buffer method implementation.
4439
4440PARAMETERS
4441 <TBD>.
4442
4443RETURN VALUE
4444 OMX Error None , if everything successful.
4445
4446========================================================================== */
4447OMX_ERRORTYPE omx_vdec::use_buffer(
4448 OMX_IN OMX_HANDLETYPE hComp,
4449 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4450 OMX_IN OMX_U32 port,
4451 OMX_IN OMX_PTR appData,
4452 OMX_IN OMX_U32 bytes,
4453 OMX_IN OMX_U8* buffer)
4454{
4455 OMX_ERRORTYPE error = OMX_ErrorNone;
4456 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004457
4458 if (bufferHdr == NULL || bytes == 0)
4459 {
4460 if(!secure_mode && buffer == NULL) {
4461 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4462 return OMX_ErrorBadParameter;
4463 }
4464 }
4465 if(m_state == OMX_StateInvalid)
4466 {
4467 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4468 return OMX_ErrorInvalidState;
4469 }
4470 if(port == OMX_CORE_INPUT_PORT_INDEX)
4471 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4472 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4473 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4474 else
4475 {
4476 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4477 error = OMX_ErrorBadPortIndex;
4478 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004479 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004480 if(error == OMX_ErrorNone)
4481 {
4482 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4483 {
4484 // Send the callback now
4485 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4486 post_event(OMX_CommandStateSet,OMX_StateIdle,
4487 OMX_COMPONENT_GENERATE_EVENT);
4488 }
4489 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4490 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4491 {
4492 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4493 post_event(OMX_CommandPortEnable,
4494 OMX_CORE_INPUT_PORT_INDEX,
4495 OMX_COMPONENT_GENERATE_EVENT);
4496 }
4497 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4498 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4499 {
4500 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4501 post_event(OMX_CommandPortEnable,
4502 OMX_CORE_OUTPUT_PORT_INDEX,
4503 OMX_COMPONENT_GENERATE_EVENT);
4504 }
4505 }
4506 return error;
4507}
4508
4509OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4510 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4511{
4512 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4513 {
4514 if(m_inp_heap_ptr[bufferindex].pBuffer)
4515 free(m_inp_heap_ptr[bufferindex].pBuffer);
4516 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4517 }
4518 if (pmem_bufferHdr)
4519 free_input_buffer(pmem_bufferHdr);
4520 return OMX_ErrorNone;
4521}
4522
4523OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4524{
4525 unsigned int index = 0;
4526 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4527 {
4528 return OMX_ErrorBadParameter;
4529 }
4530
4531 index = bufferHdr - m_inp_mem_ptr;
4532 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4533
4534 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4535 {
4536 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4537 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4538 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004539 struct vdec_setbuffer_cmd setbuffers;
4540 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4541 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4542 sizeof (vdec_bufferpayload));
Praveen Chavan212671f2013-04-05 20:00:42 -07004543 if(!secure_mode) {
4544 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4545 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4546 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4547 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4548 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4549 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4550 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4551 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4553 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4554 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4555 {
4556 free(m_desc_buffer_ptr[index].buf_addr);
4557 m_desc_buffer_ptr[index].buf_addr = NULL;
4558 m_desc_buffer_ptr[index].desc_data_size = 0;
4559 }
4560#ifdef USE_ION
4561 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4562#endif
4563 }
4564 }
4565
4566 return OMX_ErrorNone;
4567}
4568
4569OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4570{
4571 unsigned int index = 0;
4572
4573 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4574 {
4575 return OMX_ErrorBadParameter;
4576 }
4577
4578 index = bufferHdr - m_out_mem_ptr;
4579 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4580
4581 if (index < drv_ctx.op_buf.actualcount
4582 && drv_ctx.ptr_outputbuffer)
4583 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004584 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4586
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587 struct vdec_setbuffer_cmd setbuffers;
4588 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4589 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4590 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004591#ifdef _ANDROID_
4592 if(m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004593 if (!secure_mode) {
4594 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4595 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4596 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4597 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004598 }
4599 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4600 } else {
4601#endif
4602 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4603 {
Praveen Chavan212671f2013-04-05 20:00:42 -07004604 if (!secure_mode) {
4605 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4606 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4607 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4608 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4609 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4610 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4611 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4612 }
4613 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4614 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004615#ifdef USE_ION
Praveen Chavan212671f2013-04-05 20:00:42 -07004616 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004617#endif
4618 }
4619#ifdef _ANDROID_
4620 }
4621#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004622 if (release_output_done()) {
4623 free_extradata();
4624 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004625 }
4626
4627 return OMX_ErrorNone;
4628
4629}
4630
4631OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4632 OMX_BUFFERHEADERTYPE **bufferHdr,
4633 OMX_U32 port,
4634 OMX_PTR appData,
4635 OMX_U32 bytes)
4636{
4637 OMX_BUFFERHEADERTYPE *input = NULL;
4638 unsigned char *buf_addr = NULL;
4639 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4640 unsigned i = 0;
4641
4642 /* Sanity Check*/
4643 if (bufferHdr == NULL)
4644 {
4645 return OMX_ErrorBadParameter;
4646 }
4647
4648 if (m_inp_heap_ptr == NULL)
4649 {
4650 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4651 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4652 drv_ctx.ip_buf.actualcount);
4653 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4654 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4655 drv_ctx.ip_buf.actualcount);
4656
4657 if (m_inp_heap_ptr == NULL)
4658 {
4659 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4660 return OMX_ErrorInsufficientResources;
4661 }
4662 }
4663
4664 /*Find a Free index*/
4665 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4666 {
4667 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4668 {
4669 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4670 break;
4671 }
4672 }
4673
4674 if (i < drv_ctx.ip_buf.actualcount)
4675 {
4676 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4677
4678 if (buf_addr == NULL)
4679 {
4680 return OMX_ErrorInsufficientResources;
4681 }
4682
4683 *bufferHdr = (m_inp_heap_ptr + i);
4684 input = *bufferHdr;
4685 BITMASK_SET(&m_heap_inp_bm_count,i);
4686
4687 input->pBuffer = (OMX_U8 *)buf_addr;
4688 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4689 input->nVersion.nVersion = OMX_SPEC_VERSION;
4690 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4691 input->pAppPrivate = appData;
4692 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4693 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4694 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004695 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004696 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004697 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4698 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699 {
4700 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4701 return OMX_ErrorInsufficientResources;
4702 }
4703 }
4704 else
4705 {
4706 return OMX_ErrorBadParameter;
4707 }
4708
4709 return eRet;
4710
4711}
4712
4713
4714/* ======================================================================
4715FUNCTION
4716 omx_vdec::AllocateInputBuffer
4717
4718DESCRIPTION
4719 Helper function for allocate buffer in the input pin
4720
4721PARAMETERS
4722 None.
4723
4724RETURN VALUE
4725 true/false
4726
4727========================================================================== */
4728OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4729 OMX_IN OMX_HANDLETYPE hComp,
4730 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4731 OMX_IN OMX_U32 port,
4732 OMX_IN OMX_PTR appData,
4733 OMX_IN OMX_U32 bytes)
4734{
4735
4736 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4737 struct vdec_setbuffer_cmd setbuffers;
4738 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004739 unsigned i = 0;
4740 unsigned char *buf_addr = NULL;
4741 int pmem_fd = -1;
4742
4743 if(bytes != drv_ctx.ip_buf.buffer_size)
4744 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004745 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004746 bytes, drv_ctx.ip_buf.buffer_size);
4747 return OMX_ErrorBadParameter;
4748 }
4749
4750 if(!m_inp_mem_ptr)
4751 {
4752 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4753 drv_ctx.ip_buf.actualcount,
4754 drv_ctx.ip_buf.buffer_size);
4755
4756 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4757 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4758
4759 if (m_inp_mem_ptr == NULL)
4760 {
4761 return OMX_ErrorInsufficientResources;
4762 }
4763
4764 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4765 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4766
4767 if (drv_ctx.ptr_inputbuffer == NULL)
4768 {
4769 return OMX_ErrorInsufficientResources;
4770 }
4771#ifdef USE_ION
4772 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4773 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4774
4775 if (drv_ctx.ip_buf_ion_info == NULL)
4776 {
4777 return OMX_ErrorInsufficientResources;
4778 }
4779#endif
4780
4781 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4782 {
4783 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4784#ifdef USE_ION
4785 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4786#endif
4787 }
4788 }
4789
4790 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4791 {
4792 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4793 {
4794 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4795 break;
4796 }
4797 }
4798
4799 if(i < drv_ctx.ip_buf.actualcount)
4800 {
4801 struct v4l2_buffer buf;
4802 struct v4l2_plane plane;
4803 int rc;
4804 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4805#ifdef USE_ION
4806 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4807 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4808 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004809 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004810 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4811 return OMX_ErrorInsufficientResources;
4812 }
4813 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4814#else
4815 pmem_fd = open (MEM_DEVICE,O_RDWR);
4816
4817 if (pmem_fd < 0)
4818 {
4819 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4820 return OMX_ErrorInsufficientResources;
4821 }
4822
4823 if (pmem_fd == 0)
4824 {
4825 pmem_fd = open (MEM_DEVICE,O_RDWR);
4826
4827 if (pmem_fd < 0)
4828 {
4829 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4830 return OMX_ErrorInsufficientResources;
4831 }
4832 }
4833
4834 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4835 drv_ctx.ip_buf.alignment))
4836 {
4837 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4838 close(pmem_fd);
4839 return OMX_ErrorInsufficientResources;
4840 }
4841#endif
4842 if (!secure_mode) {
4843 buf_addr = (unsigned char *)mmap(NULL,
4844 drv_ctx.ip_buf.buffer_size,
4845 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4846
4847 if (buf_addr == MAP_FAILED)
4848 {
4849 close(pmem_fd);
4850#ifdef USE_ION
4851 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4852#endif
4853 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4854 return OMX_ErrorInsufficientResources;
4855 }
4856 }
4857 *bufferHdr = (m_inp_mem_ptr + i);
4858 if (secure_mode)
4859 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4860 else
4861 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4862 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4863 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4864 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4865 drv_ctx.ptr_inputbuffer [i].offset = 0;
4866
4867
4868 buf.index = i;
4869 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4870 buf.memory = V4L2_MEMORY_USERPTR;
4871 plane.bytesused = 0;
4872 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4873 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4874 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4875 plane.reserved[1] = 0;
4876 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4877 buf.m.planes = &plane;
4878 buf.length = 1;
4879
Shalaj Jainaf08f302013-03-18 13:15:35 -07004880 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4881 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004882
4883 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4884
4885 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004886 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004887 /*TODO: How to handle this case */
4888 return OMX_ErrorInsufficientResources;
4889 }
4890
4891 input = *bufferHdr;
4892 BITMASK_SET(&m_inp_bm_count,i);
4893 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4894 if (secure_mode)
4895 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4896 else
4897 input->pBuffer = (OMX_U8 *)buf_addr;
4898 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4899 input->nVersion.nVersion = OMX_SPEC_VERSION;
4900 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4901 input->pAppPrivate = appData;
4902 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4903 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4904
4905 if (drv_ctx.disable_dmx)
4906 {
4907 eRet = allocate_desc_buffer(i);
4908 }
4909 }
4910 else
4911 {
4912 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4913 eRet = OMX_ErrorInsufficientResources;
4914 }
4915 return eRet;
4916}
4917
4918
4919/* ======================================================================
4920FUNCTION
4921 omx_vdec::AllocateOutputBuffer
4922
4923DESCRIPTION
4924 Helper fn for AllocateBuffer in the output pin
4925
4926PARAMETERS
4927 <TBD>.
4928
4929RETURN VALUE
4930 OMX Error None if everything went well.
4931
4932========================================================================== */
4933OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4934 OMX_IN OMX_HANDLETYPE hComp,
4935 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4936 OMX_IN OMX_U32 port,
4937 OMX_IN OMX_PTR appData,
4938 OMX_IN OMX_U32 bytes)
4939{
4940 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4941 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4942 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004943 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004944 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004945#ifdef USE_ION
4946 int ion_device_fd =-1;
4947 struct ion_allocation_data ion_alloc_data;
4948 struct ion_fd_data fd_ion_data;
4949#endif
4950 if(!m_out_mem_ptr)
4951 {
4952 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4953 drv_ctx.op_buf.actualcount,
4954 drv_ctx.op_buf.buffer_size);
4955 int nBufHdrSize = 0;
4956 int nPlatformEntrySize = 0;
4957 int nPlatformListSize = 0;
4958 int nPMEMInfoSize = 0;
4959 int pmem_fd = -1;
4960 unsigned char *pmem_baseaddress = NULL;
4961
4962 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4963 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4964 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4965
4966 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4967 drv_ctx.op_buf.actualcount);
4968 nBufHdrSize = drv_ctx.op_buf.actualcount *
4969 sizeof(OMX_BUFFERHEADERTYPE);
4970
4971 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4972 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4973 nPlatformListSize = drv_ctx.op_buf.actualcount *
4974 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4975 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4976 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4977
4978 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4979 sizeof(OMX_BUFFERHEADERTYPE),
4980 nPMEMInfoSize,
4981 nPlatformListSize);
4982 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4983 drv_ctx.op_buf.actualcount);
4984#ifdef USE_ION
4985 ion_device_fd = alloc_map_ion_memory(
4986 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4987 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004988 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989 if (ion_device_fd < 0) {
4990 return OMX_ErrorInsufficientResources;
4991 }
4992 pmem_fd = fd_ion_data.fd;
4993#else
4994 pmem_fd = open (MEM_DEVICE,O_RDWR);
4995
4996 if (pmem_fd < 0)
4997 {
4998 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4999 drv_ctx.op_buf.buffer_size);
5000 return OMX_ErrorInsufficientResources;
5001 }
5002
5003 if(pmem_fd == 0)
5004 {
5005 pmem_fd = open (MEM_DEVICE,O_RDWR);
5006
5007 if (pmem_fd < 0)
5008 {
5009 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5010 drv_ctx.op_buf.buffer_size);
5011 return OMX_ErrorInsufficientResources;
5012 }
5013 }
5014
5015 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5016 drv_ctx.op_buf.actualcount,
5017 drv_ctx.op_buf.alignment))
5018 {
5019 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5020 close(pmem_fd);
5021 return OMX_ErrorInsufficientResources;
5022 }
5023#endif
5024 if (!secure_mode) {
5025 pmem_baseaddress = (unsigned char *)mmap(NULL,
5026 (drv_ctx.op_buf.buffer_size *
5027 drv_ctx.op_buf.actualcount),
5028 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5029 if (pmem_baseaddress == MAP_FAILED)
5030 {
5031 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5032 drv_ctx.op_buf.buffer_size);
5033 close(pmem_fd);
5034#ifdef USE_ION
5035 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5036#endif
5037 return OMX_ErrorInsufficientResources;
5038 }
5039 }
5040 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5041 // Alloc mem for platform specific info
5042 char *pPtr=NULL;
5043 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5044 nPMEMInfoSize,1);
5045 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5046 calloc (sizeof(struct vdec_bufferpayload),
5047 drv_ctx.op_buf.actualcount);
5048 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5049 calloc (sizeof (struct vdec_output_frameinfo),
5050 drv_ctx.op_buf.actualcount);
5051#ifdef USE_ION
5052 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5053 calloc (sizeof(struct vdec_ion),
5054 drv_ctx.op_buf.actualcount);
5055#endif
5056
5057 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5058 && drv_ctx.ptr_respbuffer)
5059 {
5060 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5061 (drv_ctx.op_buf.buffer_size *
5062 drv_ctx.op_buf.actualcount);
5063 bufHdr = m_out_mem_ptr;
5064 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5065 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5066 (((char *) m_platform_list) + nPlatformListSize);
5067 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5068 (((char *) m_platform_entry) + nPlatformEntrySize);
5069 pPlatformList = m_platform_list;
5070 pPlatformEntry = m_platform_entry;
5071 pPMEMInfo = m_pmem_info;
5072
5073 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5074
5075 // Settting the entire storage nicely
5076 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5077 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5078 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5079 {
5080 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5081 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5082 // Set the values when we determine the right HxW param
5083 bufHdr->nAllocLen = bytes;
5084 bufHdr->nFilledLen = 0;
5085 bufHdr->pAppPrivate = appData;
5086 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5087 // Platform specific PMEM Information
5088 // Initialize the Platform Entry
5089 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5090 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5091 pPlatformEntry->entry = pPMEMInfo;
5092 // Initialize the Platform List
5093 pPlatformList->nEntries = 1;
5094 pPlatformList->entryList = pPlatformEntry;
5095 // Keep pBuffer NULL till vdec is opened
5096 bufHdr->pBuffer = NULL;
5097 bufHdr->nOffset = 0;
5098
5099 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5100 pPMEMInfo->pmem_fd = 0;
5101 bufHdr->pPlatformPrivate = pPlatformList;
5102
5103 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005104 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005105#ifdef USE_ION
5106 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5107 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5108 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5109#endif
5110
5111 /*Create a mapping between buffers*/
5112 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5113 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5114 &drv_ctx.ptr_outputbuffer[i];
5115 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5116 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5117 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5118
5119 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5120 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5121 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5122 // Move the buffer and buffer header pointers
5123 bufHdr++;
5124 pPMEMInfo++;
5125 pPlatformEntry++;
5126 pPlatformList++;
5127 }
5128 }
5129 else
5130 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005131 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005132 m_out_mem_ptr, pPtr);
5133 if(m_out_mem_ptr)
5134 {
5135 free(m_out_mem_ptr);
5136 m_out_mem_ptr = NULL;
5137 }
5138 if(pPtr)
5139 {
5140 free(pPtr);
5141 pPtr = NULL;
5142 }
5143 if(drv_ctx.ptr_outputbuffer)
5144 {
5145 free(drv_ctx.ptr_outputbuffer);
5146 drv_ctx.ptr_outputbuffer = NULL;
5147 }
5148 if(drv_ctx.ptr_respbuffer)
5149 {
5150 free(drv_ctx.ptr_respbuffer);
5151 drv_ctx.ptr_respbuffer = NULL;
5152 }
5153#ifdef USE_ION
5154 if (drv_ctx.op_buf_ion_info) {
5155 DEBUG_PRINT_LOW("\n Free o/p ion context");
5156 free(drv_ctx.op_buf_ion_info);
5157 drv_ctx.op_buf_ion_info = NULL;
5158 }
5159#endif
5160 eRet = OMX_ErrorInsufficientResources;
5161 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005162 if (eRet == OMX_ErrorNone)
5163 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164 }
5165
5166 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5167 {
5168 if(BITMASK_ABSENT(&m_out_bm_count,i))
5169 {
5170 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5171 break;
5172 }
5173 }
5174
5175 if (eRet == OMX_ErrorNone)
5176 {
5177 if(i < drv_ctx.op_buf.actualcount)
5178 {
5179 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005180 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005181 int rc;
5182 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5183
5184 drv_ctx.ptr_outputbuffer[i].buffer_len =
5185 drv_ctx.op_buf.buffer_size;
5186
5187 *bufferHdr = (m_out_mem_ptr + i );
5188 if (secure_mode) {
5189 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5190 }
5191 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5192
5193 buf.index = i;
5194 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5195 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005196 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005197 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5198 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005199#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005200 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005202 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5203 plane[0].data_offset = 0;
5204 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5205 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5206 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5207 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5208#ifdef USE_ION
5209 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5210#endif
5211 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5212 plane[extra_idx].data_offset = 0;
5213 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5214 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5215 return OMX_ErrorBadParameter;
5216 }
5217 buf.m.planes = plane;
5218 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005219 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 -07005220 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5221 if (rc) {
5222 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005223 return OMX_ErrorInsufficientResources;
5224 }
5225
5226 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5227 enum v4l2_buf_type buf_type;
5228 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5229 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5230 if (rc) {
5231 return OMX_ErrorInsufficientResources;
5232 } else {
5233 streaming[CAPTURE_PORT] = true;
5234 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5235 }
5236 }
5237
5238 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5239 (*bufferHdr)->pAppPrivate = appData;
5240 BITMASK_SET(&m_out_bm_count,i);
5241 }
5242 else
5243 {
5244 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5245 eRet = OMX_ErrorInsufficientResources;
5246 }
5247 }
5248
5249 return eRet;
5250}
5251
5252
5253// AllocateBuffer -- API Call
5254/* ======================================================================
5255FUNCTION
5256 omx_vdec::AllocateBuffer
5257
5258DESCRIPTION
5259 Returns zero if all the buffers released..
5260
5261PARAMETERS
5262 None.
5263
5264RETURN VALUE
5265 true/false
5266
5267========================================================================== */
5268OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5269 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5270 OMX_IN OMX_U32 port,
5271 OMX_IN OMX_PTR appData,
5272 OMX_IN OMX_U32 bytes)
5273{
5274 unsigned i = 0;
5275 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5276
5277 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5278 if(m_state == OMX_StateInvalid)
5279 {
5280 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5281 return OMX_ErrorInvalidState;
5282 }
5283
5284 if(port == OMX_CORE_INPUT_PORT_INDEX)
5285 {
5286 if (arbitrary_bytes)
5287 {
5288 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5289 }
5290 else
5291 {
5292 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5293 }
5294 }
5295 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5296 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005297 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5298 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005299 }
5300 else
5301 {
5302 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5303 eRet = OMX_ErrorBadPortIndex;
5304 }
5305 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5306 if(eRet == OMX_ErrorNone)
5307 {
5308 if(allocate_done()){
5309 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5310 {
5311 // Send the callback now
5312 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5313 post_event(OMX_CommandStateSet,OMX_StateIdle,
5314 OMX_COMPONENT_GENERATE_EVENT);
5315 }
5316 }
5317 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5318 {
5319 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5320 {
5321 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5322 post_event(OMX_CommandPortEnable,
5323 OMX_CORE_INPUT_PORT_INDEX,
5324 OMX_COMPONENT_GENERATE_EVENT);
5325 }
5326 }
5327 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5328 {
5329 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5330 {
5331 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5332 post_event(OMX_CommandPortEnable,
5333 OMX_CORE_OUTPUT_PORT_INDEX,
5334 OMX_COMPONENT_GENERATE_EVENT);
5335 }
5336 }
5337 }
5338 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5339 return eRet;
5340}
5341
5342// Free Buffer - API call
5343/* ======================================================================
5344FUNCTION
5345 omx_vdec::FreeBuffer
5346
5347DESCRIPTION
5348
5349PARAMETERS
5350 None.
5351
5352RETURN VALUE
5353 true/false
5354
5355========================================================================== */
5356OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5357 OMX_IN OMX_U32 port,
5358 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5359{
5360 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5361 unsigned int nPortIndex;
5362 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5363
5364 if(m_state == OMX_StateIdle &&
5365 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5366 {
5367 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5368 }
5369 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5370 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5371 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005372 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005373 }
5374 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5375 {
5376 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5377 post_event(OMX_EventError,
5378 OMX_ErrorPortUnpopulated,
5379 OMX_COMPONENT_GENERATE_EVENT);
5380
5381 return OMX_ErrorIncorrectStateOperation;
5382 }
5383 else if (m_state != OMX_StateInvalid)
5384 {
5385 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5386 post_event(OMX_EventError,
5387 OMX_ErrorPortUnpopulated,
5388 OMX_COMPONENT_GENERATE_EVENT);
5389 }
5390
5391 if(port == OMX_CORE_INPUT_PORT_INDEX)
5392 {
5393 /*Check if arbitrary bytes*/
5394 if(!arbitrary_bytes && !input_use_buffer)
5395 nPortIndex = buffer - m_inp_mem_ptr;
5396 else
5397 nPortIndex = buffer - m_inp_heap_ptr;
5398
5399 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5400 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5401 {
5402 // Clear the bit associated with it.
5403 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5404 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5405 if (input_use_buffer == true)
5406 {
5407
5408 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5409 if(m_phdr_pmem_ptr)
5410 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5411 }
5412 else
5413 {
5414 if (arbitrary_bytes)
5415 {
5416 if(m_phdr_pmem_ptr)
5417 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5418 else
5419 free_input_buffer(nPortIndex,NULL);
5420 }
5421 else
5422 free_input_buffer(buffer);
5423 }
5424 m_inp_bPopulated = OMX_FALSE;
5425 /*Free the Buffer Header*/
5426 if (release_input_done())
5427 {
5428 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5429 free_input_buffer_header();
5430 }
5431 }
5432 else
5433 {
5434 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5435 eRet = OMX_ErrorBadPortIndex;
5436 }
5437
5438 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5439 && release_input_done())
5440 {
5441 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5442 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5443 post_event(OMX_CommandPortDisable,
5444 OMX_CORE_INPUT_PORT_INDEX,
5445 OMX_COMPONENT_GENERATE_EVENT);
5446 }
5447 }
5448 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5449 {
5450 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005451 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452 if(nPortIndex < drv_ctx.op_buf.actualcount)
5453 {
5454 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5455 // Clear the bit associated with it.
5456 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5457 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005458 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005459
5460 if (release_output_done())
5461 {
5462 free_output_buffer_header();
5463 }
5464 }
5465 else
5466 {
5467 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5468 eRet = OMX_ErrorBadPortIndex;
5469 }
5470 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5471 && release_output_done())
5472 {
5473 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5474
5475 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5476 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5477#ifdef _ANDROID_ICS_
5478 if (m_enable_android_native_buffers)
5479 {
5480 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5481 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5482 }
5483#endif
5484
5485 post_event(OMX_CommandPortDisable,
5486 OMX_CORE_OUTPUT_PORT_INDEX,
5487 OMX_COMPONENT_GENERATE_EVENT);
5488 }
5489 }
5490 else
5491 {
5492 eRet = OMX_ErrorBadPortIndex;
5493 }
5494 if((eRet == OMX_ErrorNone) &&
5495 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5496 {
5497 if(release_done())
5498 {
5499 // Send the callback now
5500 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5501 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5502 OMX_COMPONENT_GENERATE_EVENT);
5503 }
5504 }
5505 return eRet;
5506}
5507
5508
5509/* ======================================================================
5510FUNCTION
5511 omx_vdec::EmptyThisBuffer
5512
5513DESCRIPTION
5514 This routine is used to push the encoded video frames to
5515 the video decoder.
5516
5517PARAMETERS
5518 None.
5519
5520RETURN VALUE
5521 OMX Error None if everything went successful.
5522
5523========================================================================== */
5524OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5525 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5526{
5527 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5528 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5529
5530 if(m_state == OMX_StateInvalid)
5531 {
5532 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5533 return OMX_ErrorInvalidState;
5534 }
5535
5536 if (buffer == NULL)
5537 {
5538 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5539 return OMX_ErrorBadParameter;
5540 }
5541
5542 if (!m_inp_bEnabled)
5543 {
5544 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5545 return OMX_ErrorIncorrectStateOperation;
5546 }
5547
5548 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5549 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005550 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551 return OMX_ErrorBadPortIndex;
5552 }
5553
5554#ifdef _ANDROID_
5555 if(iDivXDrmDecrypt)
5556 {
5557 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5558 if(drmErr != OMX_ErrorNone) {
5559 // this error can be ignored
5560 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5561 }
5562 }
5563#endif //_ANDROID_
5564 if (perf_flag)
5565 {
5566 if (!latency)
5567 {
5568 dec_time.stop();
5569 latency = dec_time.processing_time_us();
5570 dec_time.start();
5571 }
5572 }
5573
5574 if (arbitrary_bytes)
5575 {
5576 nBufferIndex = buffer - m_inp_heap_ptr;
5577 }
5578 else
5579 {
5580 if (input_use_buffer == true)
5581 {
5582 nBufferIndex = buffer - m_inp_heap_ptr;
5583 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5584 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5585 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5586 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005587 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 -07005588 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5589 }
5590 else{
5591 nBufferIndex = buffer - m_inp_mem_ptr;
5592 }
5593 }
5594
5595 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5596 {
5597 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5598 return OMX_ErrorBadParameter;
5599 }
5600
5601 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5602 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5603 if (arbitrary_bytes)
5604 {
5605 post_event ((unsigned)hComp,(unsigned)buffer,
5606 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5607 }
5608 else
5609 {
5610 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5611 set_frame_rate(buffer->nTimeStamp);
5612 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5613 }
5614 return OMX_ErrorNone;
5615}
5616
5617/* ======================================================================
5618FUNCTION
5619 omx_vdec::empty_this_buffer_proxy
5620
5621DESCRIPTION
5622 This routine is used to push the encoded video frames to
5623 the video decoder.
5624
5625PARAMETERS
5626 None.
5627
5628RETURN VALUE
5629 OMX Error None if everything went successful.
5630
5631========================================================================== */
5632OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5633 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5634{
5635 int push_cnt = 0,i=0;
5636 unsigned nPortIndex = 0;
5637 OMX_ERRORTYPE ret = OMX_ErrorNone;
5638 struct vdec_input_frameinfo frameinfo;
5639 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640 struct vdec_seqheader seq_header;
5641 bool port_setting_changed = true;
5642 bool not_coded_vop = false;
5643
5644 /*Should we generate a Aync error event*/
5645 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5646 {
5647 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5648 return OMX_ErrorBadParameter;
5649 }
5650
5651 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5652
5653 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5654 {
5655 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5656 nPortIndex);
5657 return OMX_ErrorBadParameter;
5658 }
5659
5660 pending_input_buffers++;
5661
5662 /* return zero length and not an EOS buffer */
5663 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5664 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5665 {
5666 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5667 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5668 OMX_COMPONENT_GENERATE_EBD);
5669 return OMX_ErrorNone;
5670 }
5671
5672
5673 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5674 mp4StreamType psBits;
5675 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5676 psBits.numBytes = buffer->nFilledLen;
5677 mp4_headerparser.parseHeader(&psBits);
5678 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5679 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5680 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005681 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005682 buffer->nFilledLen,frame_count);
5683 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5684 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5685 not_coded_vop = false;
5686 buffer->nFilledLen = 0;
5687 }
5688 }
5689 }
5690
5691 if(input_flush_progress == true
5692
5693 || not_coded_vop
5694
5695 )
5696 {
5697 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5698 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5699 OMX_COMPONENT_GENERATE_EBD);
5700 return OMX_ErrorNone;
5701 }
5702
5703 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5704
5705 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5706 {
5707 return OMX_ErrorBadParameter;
5708 }
5709
5710 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5711 /*for use buffer we need to memcpy the data*/
5712 temp_buffer->buffer_len = buffer->nFilledLen;
5713
5714 if (input_use_buffer)
5715 {
5716 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5717 {
5718 if(arbitrary_bytes)
5719 {
5720 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5721 }
5722 else
5723 {
5724 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5725 buffer->nFilledLen);
5726 }
5727 }
5728 else
5729 {
5730 return OMX_ErrorBadParameter;
5731 }
5732
5733 }
5734
5735 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5736 frameinfo.client_data = (void *) buffer;
5737 frameinfo.datalen = temp_buffer->buffer_len;
5738 frameinfo.flags = 0;
5739 frameinfo.offset = buffer->nOffset;
5740 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5741 frameinfo.pmem_offset = temp_buffer->offset;
5742 frameinfo.timestamp = buffer->nTimeStamp;
5743 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5744 {
5745 DEBUG_PRINT_LOW("ETB: dmx enabled");
5746 if (m_demux_entries == 0)
5747 {
5748 extract_demux_addr_offsets(buffer);
5749 }
5750
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005751 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005752 handle_demux_data(buffer);
5753 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5754 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5755 }
5756 else
5757 {
5758 frameinfo.desc_addr = NULL;
5759 frameinfo.desc_size = 0;
5760 }
5761 if(!arbitrary_bytes)
5762 {
5763 frameinfo.flags |= buffer->nFlags;
5764 }
5765
5766#ifdef _ANDROID_
5767 if (m_debug_timestamp)
5768 {
5769 if(arbitrary_bytes)
5770 {
5771 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5772 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5773 }
5774 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5775 {
5776 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5777 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5778 }
5779 }
5780#endif
5781
5782#ifdef INPUT_BUFFER_LOG
5783 if (inputBufferFile1)
5784 {
5785 fwrite((const char *)temp_buffer->bufferaddr,
5786 temp_buffer->buffer_len,1,inputBufferFile1);
5787 }
5788#endif
5789
5790 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5791 {
5792 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5793 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5794 }
5795
5796 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5797 {
5798 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5799 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5800 h264_scratch.nFilledLen = 0;
5801 nal_count = 0;
5802 look_ahead_nal = false;
5803 frame_count = 0;
5804 if (m_frame_parser.mutils)
5805 m_frame_parser.mutils->initialize_frame_checking_environment();
5806 m_frame_parser.flush();
5807 h264_last_au_ts = LLONG_MAX;
5808 h264_last_au_flags = 0;
5809 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5810 m_demux_entries = 0;
5811 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005812 struct v4l2_buffer buf;
5813 struct v4l2_plane plane;
5814 memset( (void *)&buf, 0, sizeof(buf));
5815 memset( (void *)&plane, 0, sizeof(plane));
5816 int rc;
5817 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5819 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005820 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821 }
5822 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5823 buf.index = nPortIndex;
5824 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5825 buf.memory = V4L2_MEMORY_USERPTR;
5826 plane.bytesused = temp_buffer->buffer_len;
5827 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005828 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5829 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005830 plane.reserved[0] = temp_buffer->pmem_fd;
5831 plane.reserved[1] = temp_buffer->offset;
5832 plane.data_offset = 0;
5833 buf.m.planes = &plane;
5834 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005835 if (frameinfo.timestamp >= LLONG_MAX) {
5836 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5837 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005838 //assumption is that timestamp is in milliseconds
5839 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5840 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005841 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5842
Shalaj Jain273b3e02012-06-22 19:08:03 -07005843 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005844 if(rc)
5845 {
5846 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5847 return OMX_ErrorHardware;
5848 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005849 if(!streaming[OUTPUT_PORT])
5850 {
5851 enum v4l2_buf_type buf_type;
5852 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005853
Shalaj Jain273b3e02012-06-22 19:08:03 -07005854 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5855 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5856 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5857 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005858 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005859 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005860 } else{
5861 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005862 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005863 }
5864}
5865 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5866 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5867 time_stamp_dts.insert_timestamp(buffer);
5868
5869 return ret;
5870}
5871
5872/* ======================================================================
5873FUNCTION
5874 omx_vdec::FillThisBuffer
5875
5876DESCRIPTION
5877 IL client uses this method to release the frame buffer
5878 after displaying them.
5879
5880PARAMETERS
5881 None.
5882
5883RETURN VALUE
5884 true/false
5885
5886========================================================================== */
5887OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5888 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5889{
5890
5891 if(m_state == OMX_StateInvalid)
5892 {
5893 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5894 return OMX_ErrorInvalidState;
5895 }
5896
5897 if (!m_out_bEnabled)
5898 {
5899 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5900 return OMX_ErrorIncorrectStateOperation;
5901 }
5902
Vinay Kaliada4f4422013-01-09 10:45:03 -08005903 if (buffer == NULL ||
5904 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905 {
5906 return OMX_ErrorBadParameter;
5907 }
5908
5909 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5910 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005911 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912 return OMX_ErrorBadPortIndex;
5913 }
5914
5915 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005916 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005917 return OMX_ErrorNone;
5918}
5919/* ======================================================================
5920FUNCTION
5921 omx_vdec::fill_this_buffer_proxy
5922
5923DESCRIPTION
5924 IL client uses this method to release the frame buffer
5925 after displaying them.
5926
5927PARAMETERS
5928 None.
5929
5930RETURN VALUE
5931 true/false
5932
5933========================================================================== */
5934OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5935 OMX_IN OMX_HANDLETYPE hComp,
5936 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5937{
5938 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005939 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5940 unsigned nPortIndex = 0;
5941 struct vdec_fillbuffer_cmd fillbuffer;
5942 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5943 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5944
Vinay Kaliada4f4422013-01-09 10:45:03 -08005945 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005946
Vinay Kaliada4f4422013-01-09 10:45:03 -08005947 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005948 return OMX_ErrorBadParameter;
5949
5950 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5951 bufferAdd, bufferAdd->pBuffer);
5952 /*Return back the output buffer to client*/
5953 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5954 {
5955 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5956 buffer->nFilledLen = 0;
5957 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5958 return OMX_ErrorNone;
5959 }
5960 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005961 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005962 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5963 if (ptr_respbuffer)
5964 {
5965 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5966 }
5967
5968 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5969 {
5970 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5971 buffer->nFilledLen = 0;
5972 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5973 pending_output_buffers--;
5974 return OMX_ErrorBadParameter;
5975 }
5976
Shalaj Jain286b0062013-02-21 20:35:48 -08005977 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005978 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08005979 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005980
5981#ifdef _ANDROID_ICS_
5982 if (m_enable_android_native_buffers)
5983 {
5984 // Acquire a write lock on this buffer.
5985 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5986 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5987 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5988 buffer->nFilledLen = 0;
5989 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5990 pending_output_buffers--;
5991 return OMX_ErrorInsufficientResources;
5992 } else {
5993 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5994 }
5995 }
5996#endif
5997 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08005998 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005999 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08006000 memset( (void *)&buf, 0, sizeof(buf));
6001 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006002 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006003
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006004 buf.index = nPortIndex;
6005 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6006 buf.memory = V4L2_MEMORY_USERPTR;
6007 plane[0].bytesused = buffer->nFilledLen;
6008 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08006009 plane[0].m.userptr =
6010 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6011 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006012 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6013 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6014 plane[0].data_offset = 0;
6015 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6016 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6017 plane[extra_idx].bytesused = 0;
6018 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6019 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
6020#ifdef USE_ION
6021 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
6022#endif
6023 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6024 plane[extra_idx].data_offset = 0;
6025 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6026 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6027 return OMX_ErrorBadParameter;
6028 }
6029 buf.m.planes = plane;
6030 buf.length = drv_ctx.num_planes;
6031 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6032 if (rc) {
6033 /*TODO: How to handle this case */
6034 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6035 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036//#ifdef _ANDROID_ICS_
6037 // if (m_enable_android_native_buffers)
6038 // {
6039 // Unlock the buffer
6040 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6041 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6042 // return OMX_ErrorInsufficientResources;
6043 /// } else {
6044 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6045 // }
6046 // }
6047//#endif
6048 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6049 // pending_output_buffers--;
6050 // return OMX_ErrorBadParameter;
6051 //}
6052 return OMX_ErrorNone;
6053}
6054
6055/* ======================================================================
6056FUNCTION
6057 omx_vdec::SetCallbacks
6058
6059DESCRIPTION
6060 Set the callbacks.
6061
6062PARAMETERS
6063 None.
6064
6065RETURN VALUE
6066 OMX Error None if everything successful.
6067
6068========================================================================== */
6069OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6070 OMX_IN OMX_CALLBACKTYPE* callbacks,
6071 OMX_IN OMX_PTR appData)
6072{
6073
6074 m_cb = *callbacks;
6075 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6076 m_cb.EventHandler,m_cb.FillBufferDone);
6077 m_app_data = appData;
6078 return OMX_ErrorNotImplemented;
6079}
6080
6081/* ======================================================================
6082FUNCTION
6083 omx_vdec::ComponentDeInit
6084
6085DESCRIPTION
6086 Destroys the component and release memory allocated to the heap.
6087
6088PARAMETERS
6089 <TBD>.
6090
6091RETURN VALUE
6092 OMX Error None if everything successful.
6093
6094========================================================================== */
6095OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6096{
6097#ifdef _ANDROID_
6098 if(iDivXDrmDecrypt)
6099 {
6100 delete iDivXDrmDecrypt;
6101 iDivXDrmDecrypt=NULL;
6102 }
6103#endif //_ANDROID_
6104
Shalaj Jain286b0062013-02-21 20:35:48 -08006105 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106 if (OMX_StateLoaded != m_state)
6107 {
6108 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6109 m_state);
6110 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6111 }
6112 else
6113 {
6114 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6115 }
6116
6117 /*Check if the output buffers have to be cleaned up*/
6118 if(m_out_mem_ptr)
6119 {
6120 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006121 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006122 {
6123 free_output_buffer (&m_out_mem_ptr[i]);
6124#ifdef _ANDROID_ICS_
6125 if (m_enable_android_native_buffers)
6126 {
6127 if (native_buffer[i].inuse)
6128 {
6129 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6130 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6131 }
6132 native_buffer[i].inuse = false;
6133 }
6134 }
6135#endif
6136 }
6137#ifdef _ANDROID_ICS_
6138 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6139#endif
6140 }
6141
6142 /*Check if the input buffers have to be cleaned up*/
6143 if(m_inp_mem_ptr || m_inp_heap_ptr)
6144 {
6145 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006146 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147 {
6148 if (m_inp_mem_ptr)
6149 free_input_buffer (i,&m_inp_mem_ptr[i]);
6150 else
6151 free_input_buffer (i,NULL);
6152 }
6153 }
6154 free_input_buffer_header();
6155 free_output_buffer_header();
6156 if(h264_scratch.pBuffer)
6157 {
6158 free(h264_scratch.pBuffer);
6159 h264_scratch.pBuffer = NULL;
6160 }
6161
6162 if (h264_parser)
6163 {
6164 delete h264_parser;
6165 h264_parser = NULL;
6166 }
6167
6168 if(m_platform_list)
6169 {
6170 free(m_platform_list);
6171 m_platform_list = NULL;
6172 }
6173 if(m_vendor_config.pData)
6174 {
6175 free(m_vendor_config.pData);
6176 m_vendor_config.pData = NULL;
6177 }
6178
6179 // Reset counters in mesg queues
6180 m_ftb_q.m_size=0;
6181 m_cmd_q.m_size=0;
6182 m_etb_q.m_size=0;
6183 m_ftb_q.m_read = m_ftb_q.m_write =0;
6184 m_cmd_q.m_read = m_cmd_q.m_write =0;
6185 m_etb_q.m_read = m_etb_q.m_write =0;
6186#ifdef _ANDROID_
6187 if (m_debug_timestamp)
6188 {
6189 m_timestamp_list.reset_ts_list();
6190 }
6191#endif
6192
6193 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6194 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6195 // NULL);
6196 DEBUG_PRINT_HIGH("\n Close the driver instance");
6197
6198#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006199 if (inputBufferFile1)
6200 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006201#endif
6202#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006203 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006204 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006205#endif
6206#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006207 if (outputExtradataFile)
6208 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006209#endif
6210 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6211 return OMX_ErrorNone;
6212}
6213
6214/* ======================================================================
6215FUNCTION
6216 omx_vdec::UseEGLImage
6217
6218DESCRIPTION
6219 OMX Use EGL Image method implementation <TBD>.
6220
6221PARAMETERS
6222 <TBD>.
6223
6224RETURN VALUE
6225 Not Implemented error.
6226
6227========================================================================== */
6228OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6229 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6230 OMX_IN OMX_U32 port,
6231 OMX_IN OMX_PTR appData,
6232 OMX_IN void* eglImage)
6233{
6234 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6235 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6236 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6237
6238#ifdef USE_EGL_IMAGE_GPU
6239 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6240 EGLint fd = -1, offset = 0,pmemPtr = 0;
6241#else
6242 int fd = -1, offset = 0;
6243#endif
6244 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6245 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6246 DEBUG_PRINT_ERROR("\n ");
6247 }
6248#ifdef USE_EGL_IMAGE_GPU
6249 if(m_display_id == NULL) {
6250 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6251 return OMX_ErrorInsufficientResources;
6252 }
6253 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6254 eglGetProcAddress("eglQueryImageKHR");
6255 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6256 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6257 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6258#else //with OMX test app
6259 struct temp_egl {
6260 int pmem_fd;
6261 int offset;
6262 };
6263 struct temp_egl *temp_egl_id = NULL;
6264 void * pmemPtr = (void *) eglImage;
6265 temp_egl_id = (struct temp_egl *)eglImage;
6266 if (temp_egl_id != NULL)
6267 {
6268 fd = temp_egl_id->pmem_fd;
6269 offset = temp_egl_id->offset;
6270 }
6271#endif
6272 if (fd < 0) {
6273 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6274 return OMX_ErrorInsufficientResources;
6275 }
6276 pmem_info.pmem_fd = (OMX_U32) fd;
6277 pmem_info.offset = (OMX_U32) offset;
6278 pmem_entry.entry = (void *) &pmem_info;
6279 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6280 pmem_list.entryList = &pmem_entry;
6281 pmem_list.nEntries = 1;
6282 ouput_egl_buffers = true;
6283 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6284 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6285 (OMX_U8 *)pmemPtr)) {
6286 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6287 return OMX_ErrorInsufficientResources;
6288 }
6289 return OMX_ErrorNone;
6290}
6291
6292/* ======================================================================
6293FUNCTION
6294 omx_vdec::ComponentRoleEnum
6295
6296DESCRIPTION
6297 OMX Component Role Enum method implementation.
6298
6299PARAMETERS
6300 <TBD>.
6301
6302RETURN VALUE
6303 OMX Error None if everything is successful.
6304========================================================================== */
6305OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6306 OMX_OUT OMX_U8* role,
6307 OMX_IN OMX_U32 index)
6308{
6309 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6310
6311 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6312 {
6313 if((0 == index) && role)
6314 {
6315 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6316 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6317 }
6318 else
6319 {
6320 eRet = OMX_ErrorNoMore;
6321 }
6322 }
6323 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6324 {
6325 if((0 == index) && role)
6326 {
6327 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6328 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6329 }
6330 else
6331 {
6332 eRet = OMX_ErrorNoMore;
6333 }
6334 }
6335 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6336 {
6337 if((0 == index) && role)
6338 {
6339 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6340 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6341 }
6342 else
6343 {
6344 DEBUG_PRINT_LOW("\n No more roles \n");
6345 eRet = OMX_ErrorNoMore;
6346 }
6347 }
6348
6349 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6350 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6351 )
6352
6353 {
6354 if((0 == index) && role)
6355 {
6356 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6357 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6358 }
6359 else
6360 {
6361 DEBUG_PRINT_LOW("\n No more roles \n");
6362 eRet = OMX_ErrorNoMore;
6363 }
6364 }
6365 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6366 {
6367 if((0 == index) && role)
6368 {
6369 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6370 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6371 }
6372 else
6373 {
6374 DEBUG_PRINT_LOW("\n No more roles \n");
6375 eRet = OMX_ErrorNoMore;
6376 }
6377 }
6378 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6379 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6380 )
6381 {
6382 if((0 == index) && role)
6383 {
6384 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6385 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6386 }
6387 else
6388 {
6389 DEBUG_PRINT_LOW("\n No more roles \n");
6390 eRet = OMX_ErrorNoMore;
6391 }
6392 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006393 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6394 {
6395 if((0 == index) && role)
6396 {
6397 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6398 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6399 }
6400 else
6401 {
6402 DEBUG_PRINT_LOW("\n No more roles \n");
6403 eRet = OMX_ErrorNoMore;
6404 }
6405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006406 else
6407 {
6408 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6409 eRet = OMX_ErrorInvalidComponentName;
6410 }
6411 return eRet;
6412}
6413
6414
6415
6416
6417/* ======================================================================
6418FUNCTION
6419 omx_vdec::AllocateDone
6420
6421DESCRIPTION
6422 Checks if entire buffer pool is allocated by IL Client or not.
6423 Need this to move to IDLE state.
6424
6425PARAMETERS
6426 None.
6427
6428RETURN VALUE
6429 true/false.
6430
6431========================================================================== */
6432bool omx_vdec::allocate_done(void)
6433{
6434 bool bRet = false;
6435 bool bRet_In = false;
6436 bool bRet_Out = false;
6437
6438 bRet_In = allocate_input_done();
6439 bRet_Out = allocate_output_done();
6440
6441 if(bRet_In && bRet_Out)
6442 {
6443 bRet = true;
6444 }
6445
6446 return bRet;
6447}
6448/* ======================================================================
6449FUNCTION
6450 omx_vdec::AllocateInputDone
6451
6452DESCRIPTION
6453 Checks if I/P buffer pool is allocated by IL Client or not.
6454
6455PARAMETERS
6456 None.
6457
6458RETURN VALUE
6459 true/false.
6460
6461========================================================================== */
6462bool omx_vdec::allocate_input_done(void)
6463{
6464 bool bRet = false;
6465 unsigned i=0;
6466
6467 if (m_inp_mem_ptr == NULL)
6468 {
6469 return bRet;
6470 }
6471 if(m_inp_mem_ptr )
6472 {
6473 for(;i<drv_ctx.ip_buf.actualcount;i++)
6474 {
6475 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6476 {
6477 break;
6478 }
6479 }
6480 }
6481 if(i == drv_ctx.ip_buf.actualcount)
6482 {
6483 bRet = true;
6484 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6485 }
6486 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6487 {
6488 m_inp_bPopulated = OMX_TRUE;
6489 }
6490 return bRet;
6491}
6492/* ======================================================================
6493FUNCTION
6494 omx_vdec::AllocateOutputDone
6495
6496DESCRIPTION
6497 Checks if entire O/P buffer pool is allocated by IL Client or not.
6498
6499PARAMETERS
6500 None.
6501
6502RETURN VALUE
6503 true/false.
6504
6505========================================================================== */
6506bool omx_vdec::allocate_output_done(void)
6507{
6508 bool bRet = false;
6509 unsigned j=0;
6510
6511 if (m_out_mem_ptr == NULL)
6512 {
6513 return bRet;
6514 }
6515
6516 if (m_out_mem_ptr)
6517 {
6518 for(;j < drv_ctx.op_buf.actualcount;j++)
6519 {
6520 if(BITMASK_ABSENT(&m_out_bm_count,j))
6521 {
6522 break;
6523 }
6524 }
6525 }
6526
6527 if(j == drv_ctx.op_buf.actualcount)
6528 {
6529 bRet = true;
6530 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6531 if(m_out_bEnabled)
6532 m_out_bPopulated = OMX_TRUE;
6533 }
6534
6535 return bRet;
6536}
6537
6538/* ======================================================================
6539FUNCTION
6540 omx_vdec::ReleaseDone
6541
6542DESCRIPTION
6543 Checks if IL client has released all the buffers.
6544
6545PARAMETERS
6546 None.
6547
6548RETURN VALUE
6549 true/false
6550
6551========================================================================== */
6552bool omx_vdec::release_done(void)
6553{
6554 bool bRet = false;
6555
6556 if(release_input_done())
6557 {
6558 if(release_output_done())
6559 {
6560 bRet = true;
6561 }
6562 }
6563 return bRet;
6564}
6565
6566
6567/* ======================================================================
6568FUNCTION
6569 omx_vdec::ReleaseOutputDone
6570
6571DESCRIPTION
6572 Checks if IL client has released all the buffers.
6573
6574PARAMETERS
6575 None.
6576
6577RETURN VALUE
6578 true/false
6579
6580========================================================================== */
6581bool omx_vdec::release_output_done(void)
6582{
6583 bool bRet = false;
6584 unsigned i=0,j=0;
6585
6586 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6587 if(m_out_mem_ptr)
6588 {
6589 for(;j < drv_ctx.op_buf.actualcount ; j++)
6590 {
6591 if(BITMASK_PRESENT(&m_out_bm_count,j))
6592 {
6593 break;
6594 }
6595 }
6596 if(j == drv_ctx.op_buf.actualcount)
6597 {
6598 m_out_bm_count = 0;
6599 bRet = true;
6600 }
6601 }
6602 else
6603 {
6604 m_out_bm_count = 0;
6605 bRet = true;
6606 }
6607 return bRet;
6608}
6609/* ======================================================================
6610FUNCTION
6611 omx_vdec::ReleaseInputDone
6612
6613DESCRIPTION
6614 Checks if IL client has released all the buffers.
6615
6616PARAMETERS
6617 None.
6618
6619RETURN VALUE
6620 true/false
6621
6622========================================================================== */
6623bool omx_vdec::release_input_done(void)
6624{
6625 bool bRet = false;
6626 unsigned i=0,j=0;
6627
6628 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6629 if(m_inp_mem_ptr)
6630 {
6631 for(;j<drv_ctx.ip_buf.actualcount;j++)
6632 {
6633 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6634 {
6635 break;
6636 }
6637 }
6638 if(j==drv_ctx.ip_buf.actualcount)
6639 {
6640 bRet = true;
6641 }
6642 }
6643 else
6644 {
6645 bRet = true;
6646 }
6647 return bRet;
6648}
6649
6650OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6651 OMX_BUFFERHEADERTYPE * buffer)
6652{
6653 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6654 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6655 {
6656 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6657 return OMX_ErrorBadParameter;
6658 }
6659 else if (output_flush_progress)
6660 {
6661 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6662 buffer->nFilledLen = 0;
6663 buffer->nTimeStamp = 0;
6664 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6665 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6666 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6667 }
6668
6669 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6670 buffer, buffer->pBuffer);
6671 pending_output_buffers --;
6672
6673 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6674 {
6675 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6676 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006677 post_event((unsigned)NULL, (unsigned)NULL,
6678 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006679
6680 if (psource_frame)
6681 {
6682 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6683 psource_frame = NULL;
6684 }
6685 if (pdest_frame)
6686 {
6687 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006688 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6689 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006690 pdest_frame = NULL;
6691 }
6692 }
6693
6694 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6695#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006696 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006697 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006698 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006699 int stride = drv_ctx.video_resolution.stride;
6700 int scanlines = drv_ctx.video_resolution.scan_lines;
6701 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006702 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006703 int bytes_written = 0;
6704 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6705 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6706 temp += stride;
6707 }
6708 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006709 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006710 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6711 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6712 temp += stride_c;
6713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006714 }
6715#endif
6716
6717 /* For use buffer we need to copy the data */
6718 if (!output_flush_progress)
6719 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006720 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006721 bool is_duplicate_ts_valid = true;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006722 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
6723
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006724 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6725 output_capability == V4L2_PIX_FMT_DIVX ||
6726 output_capability == V4L2_PIX_FMT_DIVX_311)
6727 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006728
6729 if (buffer->nFilledLen > 0) {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006730 time_stamp_dts.get_next_timestamp(buffer,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006731 is_interlaced && is_duplicate_ts_valid);
6732 } else {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006733 m_inp_err_count++;
6734 time_stamp_dts.remove_time_stamp(
6735 buffer->nTimeStamp,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006736 is_interlaced && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006737 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006738
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006739 if (m_debug_timestamp)
6740 {
6741 {
6742 OMX_TICKS expected_ts = 0;
6743 m_timestamp_list.pop_min_ts(expected_ts);
6744 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6745 buffer->nTimeStamp, expected_ts);
6746
6747 if (buffer->nTimeStamp != expected_ts)
6748 {
6749 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6750 }
6751 }
6752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006753 }
6754 if (m_cb.FillBufferDone)
6755 {
6756 if (buffer->nFilledLen > 0)
6757 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006758 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006760 set_frame_rate(buffer->nTimeStamp);
6761 else if (arbitrary_bytes)
6762 adjust_timestamp(buffer->nTimeStamp);
6763 if (perf_flag)
6764 {
6765 if (!proc_frms)
6766 {
6767 dec_time.stop();
6768 latency = dec_time.processing_time_us() - latency;
6769 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6770 dec_time.start();
6771 fps_metrics.start();
6772 }
6773 proc_frms++;
6774 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6775 {
6776 OMX_U64 proc_time = 0;
6777 fps_metrics.stop();
6778 proc_time = fps_metrics.processing_time_us();
6779 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6780 proc_frms, (float)proc_time / 1e6,
6781 (float)(1e6 * proc_frms) / proc_time);
6782 proc_frms = 0;
6783 }
6784 }
6785
6786#ifdef OUTPUT_EXTRADATA_LOG
6787 if (outputExtradataFile)
6788 {
6789
6790 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6791 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6792 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6793 buffer->nFilledLen + 3)&(~3));
6794 while(p_extra &&
6795 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6796 {
6797 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6798 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6799 if (p_extra->eType == OMX_ExtraDataNone)
6800 {
6801 break;
6802 }
6803 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6804 }
6805 }
6806#endif
6807 }
6808 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6809 prev_ts = LLONG_MAX;
6810 rst_prev_ts = true;
6811 }
6812
6813 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6814 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6815 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006816 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006817#ifdef _ANDROID_ICS_
6818 if (m_enable_android_native_buffers)
6819 {
6820 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6821 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6822 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6823 return OMX_ErrorInsufficientResources;
6824 }
6825 else {
6826 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6827 }
6828 }
6829 }
6830#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006831 OMX_BUFFERHEADERTYPE *il_buffer;
6832 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6833 if (il_buffer)
6834 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6835 else {
6836 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6837 return OMX_ErrorBadParameter;
6838 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006839 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006840 }
6841 else
6842 {
6843 return OMX_ErrorBadParameter;
6844 }
6845
6846 return OMX_ErrorNone;
6847}
6848
6849OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6850 OMX_BUFFERHEADERTYPE* buffer)
6851{
6852
6853 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6854 {
6855 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6856 return OMX_ErrorBadParameter;
6857 }
6858
6859 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6860 buffer, buffer->pBuffer);
6861 pending_input_buffers--;
6862
6863 if (arbitrary_bytes)
6864 {
6865 if (pdest_frame == NULL && input_flush_progress == false)
6866 {
6867 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6868 pdest_frame = buffer;
6869 buffer->nFilledLen = 0;
6870 buffer->nTimeStamp = LLONG_MAX;
6871 push_input_buffer (hComp);
6872 }
6873 else
6874 {
6875 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6876 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006877 if (!m_input_free_q.insert_entry((unsigned)buffer,
6878 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006879 {
6880 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6881 }
6882 }
6883 }
6884 else if(m_cb.EmptyBufferDone)
6885 {
6886 buffer->nFilledLen = 0;
6887 if (input_use_buffer == true){
6888 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6889 }
6890 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6891 }
6892 return OMX_ErrorNone;
6893}
6894
Shalaj Jain273b3e02012-06-22 19:08:03 -07006895int omx_vdec::async_message_process (void *context, void* message)
6896{
6897 omx_vdec* omx = NULL;
6898 struct vdec_msginfo *vdec_msg = NULL;
6899 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006900 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006901 struct vdec_output_frameinfo *output_respbuf = NULL;
6902 int rc=1;
6903 if (context == NULL || message == NULL)
6904 {
6905 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6906 return -1;
6907 }
6908 vdec_msg = (struct vdec_msginfo *)message;
6909
6910 omx = reinterpret_cast<omx_vdec*>(context);
6911
Shalaj Jain273b3e02012-06-22 19:08:03 -07006912 switch (vdec_msg->msgcode)
6913 {
6914
6915 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006916 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006917 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6918 break;
6919
6920 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006921 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006922 OMX_COMPONENT_GENERATE_START_DONE);
6923 break;
6924
6925 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006926 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006927 OMX_COMPONENT_GENERATE_STOP_DONE);
6928 break;
6929
6930 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006931 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006932 OMX_COMPONENT_GENERATE_RESUME_DONE);
6933 break;
6934
6935 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006936 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006937 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6938 break;
6939
6940 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006941 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006942 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6943 break;
6944 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006945 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006946 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6947 break;
6948 case VDEC_MSG_RESP_INPUT_FLUSHED:
6949 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6950
Shalaj Jain286b0062013-02-21 20:35:48 -08006951 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6952 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006953
6954 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6955 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6956 if (omxhdr == NULL ||
6957 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6958 {
6959 omxhdr = NULL;
6960 vdec_msg->status_code = VDEC_S_EFATAL;
6961 }
6962
6963 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6964 OMX_COMPONENT_GENERATE_EBD);
6965 break;
6966 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6967 int64_t *timestamp;
6968 timestamp = (int64_t *) malloc(sizeof(int64_t));
6969 if (timestamp) {
6970 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6971 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6972 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6973 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6974 vdec_msg->msgdata.output_frame.time_stamp);
6975 }
6976 break;
6977 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6978 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6979
6980 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6981 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6982 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6983 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6984 vdec_msg->msgdata.output_frame.pic_type);
6985
6986 if (omxhdr && omxhdr->pOutputPortPrivate &&
6987 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6988 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6989 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6990 {
6991 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6992 {
6993 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6994 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006995 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006996 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6997
6998 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6999 {
7000 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7001 //rc = -1;
7002 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08007003 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
7004 {
7005 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7006 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007007 vdec_msg->msgdata.output_frame.bufferaddr =
7008 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007009 int format_notably_changed = 0;
7010 if (omxhdr->nFilledLen &&
7011 (omxhdr->nFilledLen != omx->prev_n_filled_len))
7012 {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007013 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7014 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7015 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7016 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7017 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7018 format_notably_changed = 1;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007019 }
7020 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007021 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7022 vdec_msg->msgdata.output_frame.framesize.left)
7023 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08007024 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7025 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007026 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7027 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7028 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7029 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7030 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
7031 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
7032 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kaliafa7cc352013-04-03 17:02:37 -07007033 }
Vinay Kalia0321dc12013-04-08 20:45:54 -07007034 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
7035 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
7036 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007037 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7038 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7039 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7040 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007041 format_notably_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08007042 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007043 if (format_notably_changed) {
7044 if(omx->is_video_session_supported()) {
7045 omx->post_event (NULL, vdec_msg->status_code,
7046 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7047 } else {
7048 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7049 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7050 }
7051 }
7052 if (omxhdr->nFilledLen)
7053 omx->prev_n_filled_len = omxhdr->nFilledLen;
7054
Shalaj Jain273b3e02012-06-22 19:08:03 -07007055 output_respbuf = (struct vdec_output_frameinfo *)\
7056 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007057 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7058 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08007059 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7060 {
7061 output_respbuf->pic_type = PICTURE_TYPE_I;
7062 }
7063 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7064 {
7065 output_respbuf->pic_type = PICTURE_TYPE_P;
7066 }
7067 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7068 output_respbuf->pic_type = PICTURE_TYPE_B;
7069 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007070
7071 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007072 memcpy ( omxhdr->pBuffer, (void *)
7073 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7074 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7075 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007076 }
7077 else
7078 omxhdr->nFilledLen = 0;
7079 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7080 OMX_COMPONENT_GENERATE_FBD);
7081 }
7082 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007083 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007084 OMX_COMPONENT_GENERATE_EOS_DONE);
7085 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007086 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007087 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7088 break;
7089 case VDEC_MSG_EVT_CONFIG_CHANGED:
7090 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007091 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7092 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007093 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007094 default:
7095 break;
7096 }
7097 return rc;
7098}
7099
7100OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7101 OMX_HANDLETYPE hComp,
7102 OMX_BUFFERHEADERTYPE *buffer
7103 )
7104{
7105 unsigned address,p2,id;
7106 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7107
7108 if (buffer == NULL)
7109 {
7110 return OMX_ErrorBadParameter;
7111 }
7112 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007113 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7114 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007115
7116 /* return zero length and not an EOS buffer */
7117 /* return buffer if input flush in progress */
7118 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7119 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7120 {
7121 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7122 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7123 return OMX_ErrorNone;
7124 }
7125
7126 if (psource_frame == NULL)
7127 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007128 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007129 psource_frame = buffer;
7130 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7131 push_input_buffer (hComp);
7132 }
7133 else
7134 {
7135 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007136 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7137 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007138 {
7139 return OMX_ErrorBadParameter;
7140 }
7141 }
7142
7143
7144 return OMX_ErrorNone;
7145}
7146
7147OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7148{
7149 unsigned address,p2,id;
7150 OMX_ERRORTYPE ret = OMX_ErrorNone;
7151
7152 if (pdest_frame == NULL || psource_frame == NULL)
7153 {
7154 /*Check if we have a destination buffer*/
7155 if (pdest_frame == NULL)
7156 {
7157 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7158 if (m_input_free_q.m_size)
7159 {
7160 m_input_free_q.pop_entry(&address,&p2,&id);
7161 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7162 pdest_frame->nFilledLen = 0;
7163 pdest_frame->nTimeStamp = LLONG_MAX;
7164 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7165 }
7166 }
7167
7168 /*Check if we have a destination buffer*/
7169 if (psource_frame == NULL)
7170 {
7171 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7172 if (m_input_pending_q.m_size)
7173 {
7174 m_input_pending_q.pop_entry(&address,&p2,&id);
7175 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007176 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007177 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007178 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007179 psource_frame->nFlags,psource_frame->nFilledLen);
7180
7181 }
7182 }
7183
7184 }
7185
7186 while ((pdest_frame != NULL) && (psource_frame != NULL))
7187 {
7188 switch (codec_type_parse)
7189 {
7190 case CODEC_TYPE_MPEG4:
7191 case CODEC_TYPE_H263:
7192 case CODEC_TYPE_MPEG2:
7193 ret = push_input_sc_codec(hComp);
7194 break;
7195 case CODEC_TYPE_H264:
7196 ret = push_input_h264(hComp);
7197 break;
7198 case CODEC_TYPE_VC1:
7199 ret = push_input_vc1(hComp);
7200 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007201 default:
7202 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203 }
7204 if (ret != OMX_ErrorNone)
7205 {
7206 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7207 omx_report_error ();
7208 break;
7209 }
7210 }
7211
7212 return ret;
7213}
7214
7215OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7216{
7217 OMX_U32 partial_frame = 1;
7218 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007219 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007220
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007221 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007222 psource_frame,psource_frame->nTimeStamp);
7223 if (m_frame_parser.parse_sc_frame(psource_frame,
7224 pdest_frame,&partial_frame) == -1)
7225 {
7226 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7227 return OMX_ErrorBadParameter;
7228 }
7229
7230 if (partial_frame == 0)
7231 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007232 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007233 pdest_frame->nFilledLen,psource_frame,frame_count);
7234
7235
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007236 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007237 /*First Parsed buffer will have only header Hence skip*/
7238 if (frame_count == 0)
7239 {
7240 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7241
7242 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7243 codec_type_parse == CODEC_TYPE_DIVX) {
7244 mp4StreamType psBits;
7245 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7246 psBits.numBytes = pdest_frame->nFilledLen;
7247 mp4_headerparser.parseHeader(&psBits);
7248 }
7249
7250 frame_count++;
7251 }
7252 else
7253 {
7254 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7255 if(pdest_frame->nFilledLen)
7256 {
7257 /*Push the frame to the Decoder*/
7258 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7259 {
7260 return OMX_ErrorBadParameter;
7261 }
7262 frame_count++;
7263 pdest_frame = NULL;
7264
7265 if (m_input_free_q.m_size)
7266 {
7267 m_input_free_q.pop_entry(&address,&p2,&id);
7268 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7269 pdest_frame->nFilledLen = 0;
7270 }
7271 }
7272 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7273 {
7274 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007275 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7276 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007277 pdest_frame = NULL;
7278 }
7279 }
7280 }
7281 else
7282 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007283 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007284 /*Check if Destination Buffer is full*/
7285 if (pdest_frame->nAllocLen ==
7286 pdest_frame->nFilledLen + pdest_frame->nOffset)
7287 {
7288 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7289 return OMX_ErrorStreamCorrupt;
7290 }
7291 }
7292
7293 if (psource_frame->nFilledLen == 0)
7294 {
7295 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7296 {
7297 if (pdest_frame)
7298 {
7299 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007300 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007301 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007302 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007303 pdest_frame->nFilledLen,frame_count++);
7304 /*Push the frame to the Decoder*/
7305 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7306 {
7307 return OMX_ErrorBadParameter;
7308 }
7309 frame_count++;
7310 pdest_frame = NULL;
7311 }
7312 else
7313 {
7314 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7315 generate_ebd = OMX_FALSE;
7316 }
7317 }
7318 if(generate_ebd)
7319 {
7320 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7321 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7322 psource_frame = NULL;
7323
7324 if (m_input_pending_q.m_size)
7325 {
7326 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7327 m_input_pending_q.pop_entry(&address,&p2,&id);
7328 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007329 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007330 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007331 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007332 psource_frame->nFlags,psource_frame->nFilledLen);
7333 }
7334 }
7335 }
7336 return OMX_ErrorNone;
7337}
7338
7339OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7340{
7341 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007342 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007343 OMX_BOOL isNewFrame = OMX_FALSE;
7344 OMX_BOOL generate_ebd = OMX_TRUE;
7345
7346 if (h264_scratch.pBuffer == NULL)
7347 {
7348 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7349 return OMX_ErrorBadParameter;
7350 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007351 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007352 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007353 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007354 if (h264_scratch.nFilledLen && look_ahead_nal)
7355 {
7356 look_ahead_nal = false;
7357 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7358 h264_scratch.nFilledLen)
7359 {
7360 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7361 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7362 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7363 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7364 h264_scratch.nFilledLen = 0;
7365 }
7366 else
7367 {
7368 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7369 return OMX_ErrorBadParameter;
7370 }
7371 }
7372 if (nal_length == 0)
7373 {
7374 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7375 if (m_frame_parser.parse_sc_frame(psource_frame,
7376 &h264_scratch,&partial_frame) == -1)
7377 {
7378 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7379 return OMX_ErrorBadParameter;
7380 }
7381 }
7382 else
7383 {
7384 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7385 if (m_frame_parser.parse_h264_nallength(psource_frame,
7386 &h264_scratch,&partial_frame) == -1)
7387 {
7388 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7389 return OMX_ErrorBadParameter;
7390 }
7391 }
7392
7393 if (partial_frame == 0)
7394 {
7395 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7396 {
7397 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7398 nal_count++;
7399 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7400 h264_scratch.nFlags = psource_frame->nFlags;
7401 }
7402 else
7403 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007404 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007405 if(h264_scratch.nFilledLen)
7406 {
7407 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7408 NALU_TYPE_SPS);
7409#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7410 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7411 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7412 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7413 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7414 // If timeinfo is present frame info from SEI is already processed
7415 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7416 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7417#endif
7418 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7419 nal_count++;
7420 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7421 pdest_frame->nTimeStamp = h264_last_au_ts;
7422 pdest_frame->nFlags = h264_last_au_flags;
7423#ifdef PANSCAN_HDLR
7424 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7425 h264_parser->update_panscan_data(h264_last_au_ts);
7426#endif
7427 }
7428 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7429 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7430 h264_last_au_ts = h264_scratch.nTimeStamp;
7431 h264_last_au_flags = h264_scratch.nFlags;
7432#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7433 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7434 {
7435 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7436 if (!VALID_TS(h264_last_au_ts))
7437 h264_last_au_ts = ts_in_sei;
7438 }
7439#endif
7440 } else
7441 h264_last_au_ts = LLONG_MAX;
7442 }
7443
7444 if (!isNewFrame)
7445 {
7446 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7447 h264_scratch.nFilledLen)
7448 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007449 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450 h264_scratch.nFilledLen);
7451 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7452 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7453 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7454 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7455 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7456 h264_scratch.nFilledLen = 0;
7457 }
7458 else
7459 {
7460 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7461 return OMX_ErrorBadParameter;
7462 }
7463 }
7464 else
7465 {
7466 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007467 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007468 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007469 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007470 pdest_frame->nFilledLen,frame_count++);
7471
7472 if (pdest_frame->nFilledLen == 0)
7473 {
7474 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7475 look_ahead_nal = false;
7476 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7477 h264_scratch.nFilledLen)
7478 {
7479 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7480 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7481 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7482 h264_scratch.nFilledLen = 0;
7483 }
7484 else
7485 {
7486 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7487 return OMX_ErrorBadParameter;
7488 }
7489 }
7490 else
7491 {
7492 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7493 {
7494 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7495 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7496 }
7497 /*Push the frame to the Decoder*/
7498 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7499 {
7500 return OMX_ErrorBadParameter;
7501 }
7502 //frame_count++;
7503 pdest_frame = NULL;
7504 if (m_input_free_q.m_size)
7505 {
7506 m_input_free_q.pop_entry(&address,&p2,&id);
7507 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7508 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7509 pdest_frame->nFilledLen = 0;
7510 pdest_frame->nFlags = 0;
7511 pdest_frame->nTimeStamp = LLONG_MAX;
7512 }
7513 }
7514 }
7515 }
7516 }
7517 else
7518 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007519 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007520 /*Check if Destination Buffer is full*/
7521 if (h264_scratch.nAllocLen ==
7522 h264_scratch.nFilledLen + h264_scratch.nOffset)
7523 {
7524 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7525 return OMX_ErrorStreamCorrupt;
7526 }
7527 }
7528
7529 if (!psource_frame->nFilledLen)
7530 {
7531 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7532
7533 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7534 {
7535 if (pdest_frame)
7536 {
7537 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7538 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7539 h264_scratch.nFilledLen)
7540 {
7541 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7542 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7543 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7544 h264_scratch.nFilledLen = 0;
7545 }
7546 else
7547 {
7548 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7549 return OMX_ErrorBadParameter;
7550 }
7551 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7552 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7553
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007554 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007555 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7556 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7557#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7558 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7559 {
7560 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7561 if (!VALID_TS(pdest_frame->nTimeStamp))
7562 pdest_frame->nTimeStamp = ts_in_sei;
7563 }
7564#endif
7565 /*Push the frame to the Decoder*/
7566 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7567 {
7568 return OMX_ErrorBadParameter;
7569 }
7570 frame_count++;
7571 pdest_frame = NULL;
7572 }
7573 else
7574 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007575 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007576 pdest_frame,h264_scratch.nFilledLen);
7577 generate_ebd = OMX_FALSE;
7578 }
7579 }
7580 }
7581 if(generate_ebd && !psource_frame->nFilledLen)
7582 {
7583 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7584 psource_frame = NULL;
7585 if (m_input_pending_q.m_size)
7586 {
7587 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7588 m_input_pending_q.pop_entry(&address,&p2,&id);
7589 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007590 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007591 psource_frame->nFlags,psource_frame->nFilledLen);
7592 }
7593 }
7594 return OMX_ErrorNone;
7595}
7596
7597OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7598{
7599 OMX_U8 *buf, *pdest;
7600 OMX_U32 partial_frame = 1;
7601 OMX_U32 buf_len, dest_len;
7602
7603 if(first_frame == 0)
7604 {
7605 first_frame = 1;
7606 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7607 if(!m_vendor_config.pData)
7608 {
7609 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7610 buf = psource_frame->pBuffer;
7611 buf_len = psource_frame->nFilledLen;
7612
7613 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7614 VC1_SP_MP_START_CODE)
7615 {
7616 m_vc1_profile = VC1_SP_MP_RCV;
7617 }
7618 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7619 {
7620 m_vc1_profile = VC1_AP;
7621 }
7622 else
7623 {
7624 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7625 return OMX_ErrorStreamCorrupt;
7626 }
7627 }
7628 else
7629 {
7630 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7631 pdest_frame->nOffset;
7632 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7633 pdest_frame->nOffset);
7634
7635 if(dest_len < m_vendor_config.nDataSize)
7636 {
7637 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7638 return OMX_ErrorBadParameter;
7639 }
7640 else
7641 {
7642 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7643 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7644 }
7645 }
7646 }
7647
7648 switch(m_vc1_profile)
7649 {
7650 case VC1_AP:
7651 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7652 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7653 {
7654 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7655 return OMX_ErrorBadParameter;
7656 }
7657 break;
7658
7659 case VC1_SP_MP_RCV:
7660 default:
7661 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7662 return OMX_ErrorBadParameter;
7663 }
7664 return OMX_ErrorNone;
7665}
7666
David Ng38e2d232013-03-15 20:05:58 -07007667#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007668bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7669 OMX_U32 alignment)
7670{
7671 struct pmem_allocation allocation;
7672 allocation.size = buffer_size;
7673 allocation.align = clip2(alignment);
7674 if (allocation.align < 4096)
7675 {
7676 allocation.align = 4096;
7677 }
7678 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7679 {
7680 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7681 allocation.align, allocation.size);
7682 return false;
7683 }
7684 return true;
7685}
David Ng38e2d232013-03-15 20:05:58 -07007686#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007687#ifdef USE_ION
7688int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7689 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7690 struct ion_fd_data *fd_data, int flag)
7691{
7692 int fd = -EINVAL;
7693 int rc = -EINVAL;
7694 int ion_dev_flag;
7695 struct vdec_ion ion_buf_info;
7696 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7697 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7698 return -EINVAL;
7699 }
Arun Menon737de532012-09-14 14:48:18 -07007700 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007701 fd = open (MEM_DEVICE, ion_dev_flag);
7702 if (fd < 0) {
7703 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7704 return fd;
7705 }
Arun Menon737de532012-09-14 14:48:18 -07007706 alloc_data->flags = 0;
7707 if(!secure_mode && (flag & ION_FLAG_CACHED))
7708 {
7709 alloc_data->flags |= ION_FLAG_CACHED;
7710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007711 alloc_data->len = buffer_size;
7712 alloc_data->align = clip2(alignment);
7713 if (alloc_data->align < 4096)
7714 {
7715 alloc_data->align = 4096;
7716 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007717 if ((secure_mode) && (flag & ION_SECURE))
7718 alloc_data->flags |= ION_SECURE;
7719
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007720 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7721 if (secure_mode)
7722 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007723 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7724 if (rc || !alloc_data->handle) {
7725 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7726 alloc_data->handle = NULL;
7727 close(fd);
7728 fd = -ENOMEM;
7729 return fd;
7730 }
7731 fd_data->handle = alloc_data->handle;
7732 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7733 if (rc) {
7734 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7735 ion_buf_info.ion_alloc_data = *alloc_data;
7736 ion_buf_info.ion_device_fd = fd;
7737 ion_buf_info.fd_ion_data = *fd_data;
7738 free_ion_memory(&ion_buf_info);
7739 fd_data->fd =-1;
7740 close(fd);
7741 fd = -ENOMEM;
7742 }
7743
7744 return fd;
7745}
7746
7747void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7748
7749 if(!buf_ion_info) {
7750 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7751 return;
7752 }
7753 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7754 &buf_ion_info->ion_alloc_data.handle)) {
7755 DEBUG_PRINT_ERROR("\n ION: free failed" );
7756 }
7757 close(buf_ion_info->ion_device_fd);
7758 buf_ion_info->ion_device_fd = -1;
7759 buf_ion_info->ion_alloc_data.handle = NULL;
7760 buf_ion_info->fd_ion_data.fd = -1;
7761}
7762#endif
7763void omx_vdec::free_output_buffer_header()
7764{
7765 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7766 output_use_buffer = false;
7767 ouput_egl_buffers = false;
7768
7769 if (m_out_mem_ptr)
7770 {
7771 free (m_out_mem_ptr);
7772 m_out_mem_ptr = NULL;
7773 }
7774
7775 if(m_platform_list)
7776 {
7777 free(m_platform_list);
7778 m_platform_list = NULL;
7779 }
7780
7781 if (drv_ctx.ptr_respbuffer)
7782 {
7783 free (drv_ctx.ptr_respbuffer);
7784 drv_ctx.ptr_respbuffer = NULL;
7785 }
7786 if (drv_ctx.ptr_outputbuffer)
7787 {
7788 free (drv_ctx.ptr_outputbuffer);
7789 drv_ctx.ptr_outputbuffer = NULL;
7790 }
7791#ifdef USE_ION
7792 if (drv_ctx.op_buf_ion_info) {
7793 DEBUG_PRINT_LOW("\n Free o/p ion context");
7794 free(drv_ctx.op_buf_ion_info);
7795 drv_ctx.op_buf_ion_info = NULL;
7796 }
7797#endif
7798}
7799
7800void omx_vdec::free_input_buffer_header()
7801{
7802 input_use_buffer = false;
7803 if (arbitrary_bytes)
7804 {
7805 if (m_frame_parser.mutils)
7806 {
7807 DEBUG_PRINT_LOW("\n Free utils parser");
7808 delete (m_frame_parser.mutils);
7809 m_frame_parser.mutils = NULL;
7810 }
7811
7812 if (m_inp_heap_ptr)
7813 {
7814 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7815 free (m_inp_heap_ptr);
7816 m_inp_heap_ptr = NULL;
7817 }
7818
7819 if (m_phdr_pmem_ptr)
7820 {
7821 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7822 free (m_phdr_pmem_ptr);
7823 m_phdr_pmem_ptr = NULL;
7824 }
7825 }
7826 if (m_inp_mem_ptr)
7827 {
7828 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7829 free (m_inp_mem_ptr);
7830 m_inp_mem_ptr = NULL;
7831 }
7832 if (drv_ctx.ptr_inputbuffer)
7833 {
7834 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7835 free (drv_ctx.ptr_inputbuffer);
7836 drv_ctx.ptr_inputbuffer = NULL;
7837 }
7838#ifdef USE_ION
7839 if (drv_ctx.ip_buf_ion_info) {
7840 DEBUG_PRINT_LOW("\n Free ion context");
7841 free(drv_ctx.ip_buf_ion_info);
7842 drv_ctx.ip_buf_ion_info = NULL;
7843 }
7844#endif
7845}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007846
7847int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007848{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007849 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007850 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007851 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007852
7853 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7854 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7855 v4l2_port = OUTPUT_PORT;
7856 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7857 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7858 v4l2_port = CAPTURE_PORT;
7859 } else if (port == OMX_ALL) {
7860 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7861 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7862
7863 if (!rc_input)
7864 return rc_input;
7865 else
7866 return rc_output;
7867 }
7868
7869 if (!streaming[v4l2_port]) {
7870 // already streamed off, warn and move on
7871 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7872 " which is already streamed off", v4l2_port);
7873 return 0;
7874 }
7875
7876 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7877
Shalaj Jain273b3e02012-06-22 19:08:03 -07007878 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7879 if (rc) {
7880 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007881 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007882 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007883 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007884 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007885
7886 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007887}
7888
7889OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7890{
7891 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7892 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007893 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007894 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007895 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7897 buffer_prop->actualcount, buffer_prop->buffer_size);
7898 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007899 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7901 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7902 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7903 fmt.fmt.pix_mp.pixelformat = output_capability;
7904 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7905 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7906 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7907 fmt.fmt.pix_mp.pixelformat = capture_capability;
7908 }else {eRet = OMX_ErrorBadParameter;}
7909 if(eRet==OMX_ErrorNone){
7910 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7911 }
7912 if(ret)
7913 {
7914 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7915 /*TODO: How to handle this case */
7916 eRet = OMX_ErrorInsufficientResources;
7917 return eRet;
7918 }
7919 else
7920 {
7921 buffer_prop->actualcount = bufreq.count;
7922 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007923 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007924 }
7925 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7926 buffer_prop->actualcount, buffer_prop->buffer_size);
7927
7928 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7929 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7930
7931 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7932
Vinay Kalia21649b32013-03-18 17:28:07 -07007933 update_resolution(fmt.fmt.pix_mp.width,
7934 fmt.fmt.pix_mp.height,
7935 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7936 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007937 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7938 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007939 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940
7941 if(ret)
7942 {
7943 /*TODO: How to handle this case */
7944 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7945 eRet = OMX_ErrorInsufficientResources;
7946 }
7947 else
7948 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007949 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08007950
7951 eRet = is_video_session_supported();
7952 if (eRet)
7953 return eRet;
7954
Shalaj Jain273b3e02012-06-22 19:08:03 -07007955 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7956 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007957 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7958 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7959 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7960 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7961 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7962 return OMX_ErrorBadParameter;
7963 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007964 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7965 {
7966 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007967 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007968 }
7969 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7970 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007971 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007972 }
7973 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7974 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007975 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7976 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7977 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007978 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007979 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007980 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007981 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007982 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7983 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007984 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7985 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7986 drv_ctx.extradata_info.buffer_size = extra_data_size;
7987 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007988 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7989 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007990 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007991 if (in_reconfig) // BufReq will be set to driver when port is disabled
7992 buffer_prop->buffer_size = buf_size;
7993 else if (buf_size != buffer_prop->buffer_size)
7994 {
7995 buffer_prop->buffer_size = buf_size;
7996 eRet = set_buffer_req(buffer_prop);
7997 }
7998 }
7999 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8000 buffer_prop->actualcount, buffer_prop->buffer_size);
8001 return eRet;
8002}
8003
8004OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8005{
8006 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8007 unsigned buf_size = 0;
8008 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008009 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008010 int ret;
8011 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8012 buffer_prop->actualcount, buffer_prop->buffer_size);
8013 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8014 if (buf_size != buffer_prop->buffer_size)
8015 {
8016 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8017 buffer_prop->buffer_size, buf_size);
8018 eRet = OMX_ErrorBadParameter;
8019 }
8020 else
8021 {
8022 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8023 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008024
8025 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8026 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8027 fmt.fmt.pix_mp.pixelformat = output_capability;
8028 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8029 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8030 fmt.fmt.pix_mp.pixelformat = capture_capability;
8031 } else {eRet = OMX_ErrorBadParameter;}
8032
8033 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8034 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008035 {
8036 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008037 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008038 eRet = OMX_ErrorInsufficientResources;
8039 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008040
8041 bufreq.memory = V4L2_MEMORY_USERPTR;
8042 bufreq.count = buffer_prop->actualcount;
8043 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8044 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8045 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8046 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8047 } else {eRet = OMX_ErrorBadParameter;}
8048
8049 if (eRet==OMX_ErrorNone) {
8050 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8051 }
8052
8053 if (ret)
8054 {
8055 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8056 /*TODO: How to handle this case */
8057 eRet = OMX_ErrorInsufficientResources;
8058 } else if (bufreq.count < buffer_prop->actualcount) {
8059 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8060 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8061 buffer_prop->actualcount, bufreq.count);
8062 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008063 } else {
8064 if (!client_buffers.update_buffer_req()) {
8065 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8066 eRet = OMX_ErrorInsufficientResources;
8067 }
8068 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008069 }
8070 return eRet;
8071}
8072
Shalaj Jain273b3e02012-06-22 19:08:03 -07008073OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8074{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008075 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008076 return eRet;
8077}
8078
8079OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8080{
8081 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8082 if (!portDefn)
8083 {
8084 return OMX_ErrorBadParameter;
8085 }
8086 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8087 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8088 portDefn->nSize = sizeof(portDefn);
8089 portDefn->eDomain = OMX_PortDomainVideo;
8090 if (drv_ctx.frame_rate.fps_denominator > 0)
8091 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8092 drv_ctx.frame_rate.fps_denominator;
8093 else {
8094 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8095 return OMX_ErrorBadParameter;
8096 }
8097 if (0 == portDefn->nPortIndex)
8098 {
8099 portDefn->eDir = OMX_DirInput;
8100 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8101 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8102 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8103 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8104 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8105 portDefn->bEnabled = m_inp_bEnabled;
8106 portDefn->bPopulated = m_inp_bPopulated;
8107 }
8108 else if (1 == portDefn->nPortIndex)
8109 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008110 unsigned int buf_size = 0;
8111 if (!client_buffers.update_buffer_req()) {
8112 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8113 return OMX_ErrorHardware;
8114 }
8115 if (!client_buffers.get_buffer_req(buf_size)) {
8116 DEBUG_PRINT_ERROR("\n update buffer requirements");
8117 return OMX_ErrorHardware;
8118 }
8119 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008120 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008121 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8122 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008123 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8124 portDefn->bEnabled = m_out_bEnabled;
8125 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008126 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8127 DEBUG_PRINT_ERROR("\n Error in getting color format");
8128 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008129 }
8130 }
8131 else
8132 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008133 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008134 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8135 (int)portDefn->nPortIndex);
8136 eRet = OMX_ErrorBadPortIndex;
8137 }
8138 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8139 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8140 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8141 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008142 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8143 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008144 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008145 portDefn->format.video.nStride,
8146 portDefn->format.video.nSliceHeight);
8147 return eRet;
8148
8149}
8150
8151OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8152{
8153 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8154 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8155 unsigned i= 0;
8156
8157 if(!m_out_mem_ptr) {
8158 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8159 int nBufHdrSize = 0;
8160 int nPlatformEntrySize = 0;
8161 int nPlatformListSize = 0;
8162 int nPMEMInfoSize = 0;
8163 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8164 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8165 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8166
8167 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8168 drv_ctx.op_buf.actualcount);
8169 nBufHdrSize = drv_ctx.op_buf.actualcount *
8170 sizeof(OMX_BUFFERHEADERTYPE);
8171
8172 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8173 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8174 nPlatformListSize = drv_ctx.op_buf.actualcount *
8175 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8176 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8177 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8178
8179 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8180 sizeof(OMX_BUFFERHEADERTYPE),
8181 nPMEMInfoSize,
8182 nPlatformListSize);
8183 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8184 m_out_bm_count);
8185 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8186 // Alloc mem for platform specific info
8187 char *pPtr=NULL;
8188 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8189 nPMEMInfoSize,1);
8190 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8191 calloc (sizeof(struct vdec_bufferpayload),
8192 drv_ctx.op_buf.actualcount);
8193 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8194 calloc (sizeof (struct vdec_output_frameinfo),
8195 drv_ctx.op_buf.actualcount);
8196#ifdef USE_ION
8197 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8198 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8199#endif
8200
8201 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8202 && drv_ctx.ptr_respbuffer)
8203 {
8204 bufHdr = m_out_mem_ptr;
8205 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8206 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8207 (((char *) m_platform_list) + nPlatformListSize);
8208 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8209 (((char *) m_platform_entry) + nPlatformEntrySize);
8210 pPlatformList = m_platform_list;
8211 pPlatformEntry = m_platform_entry;
8212 pPMEMInfo = m_pmem_info;
8213
8214 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8215
8216 // Settting the entire storage nicely
8217 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8218 m_out_mem_ptr,pPlatformEntry);
8219 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8220 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8221 {
8222 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8223 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8224 // Set the values when we determine the right HxW param
8225 bufHdr->nAllocLen = 0;
8226 bufHdr->nFilledLen = 0;
8227 bufHdr->pAppPrivate = NULL;
8228 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8229 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8230 pPlatformEntry->entry = pPMEMInfo;
8231 // Initialize the Platform List
8232 pPlatformList->nEntries = 1;
8233 pPlatformList->entryList = pPlatformEntry;
8234 // Keep pBuffer NULL till vdec is opened
8235 bufHdr->pBuffer = NULL;
8236 pPMEMInfo->offset = 0;
8237 pPMEMInfo->pmem_fd = 0;
8238 bufHdr->pPlatformPrivate = pPlatformList;
8239 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8240#ifdef USE_ION
8241 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8242#endif
8243 /*Create a mapping between buffers*/
8244 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8245 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8246 &drv_ctx.ptr_outputbuffer[i];
8247 // Move the buffer and buffer header pointers
8248 bufHdr++;
8249 pPMEMInfo++;
8250 pPlatformEntry++;
8251 pPlatformList++;
8252 }
8253 }
8254 else
8255 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008256 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008257 m_out_mem_ptr, pPtr);
8258 if(m_out_mem_ptr)
8259 {
8260 free(m_out_mem_ptr);
8261 m_out_mem_ptr = NULL;
8262 }
8263 if(pPtr)
8264 {
8265 free(pPtr);
8266 pPtr = NULL;
8267 }
8268 if(drv_ctx.ptr_outputbuffer)
8269 {
8270 free(drv_ctx.ptr_outputbuffer);
8271 drv_ctx.ptr_outputbuffer = NULL;
8272 }
8273 if(drv_ctx.ptr_respbuffer)
8274 {
8275 free(drv_ctx.ptr_respbuffer);
8276 drv_ctx.ptr_respbuffer = NULL;
8277 }
8278#ifdef USE_ION
8279 if (drv_ctx.op_buf_ion_info) {
8280 DEBUG_PRINT_LOW("\n Free o/p ion context");
8281 free(drv_ctx.op_buf_ion_info);
8282 drv_ctx.op_buf_ion_info = NULL;
8283 }
8284#endif
8285 eRet = OMX_ErrorInsufficientResources;
8286 }
8287 } else {
8288 eRet = OMX_ErrorInsufficientResources;
8289 }
8290 return eRet;
8291}
8292
8293void omx_vdec::complete_pending_buffer_done_cbs()
8294{
8295 unsigned p1;
8296 unsigned p2;
8297 unsigned ident;
8298 omx_cmd_queue tmp_q, pending_bd_q;
8299 pthread_mutex_lock(&m_lock);
8300 // pop all pending GENERATE FDB from ftb queue
8301 while (m_ftb_q.m_size)
8302 {
8303 m_ftb_q.pop_entry(&p1,&p2,&ident);
8304 if(ident == OMX_COMPONENT_GENERATE_FBD)
8305 {
8306 pending_bd_q.insert_entry(p1,p2,ident);
8307 }
8308 else
8309 {
8310 tmp_q.insert_entry(p1,p2,ident);
8311 }
8312 }
8313 //return all non GENERATE FDB to ftb queue
8314 while(tmp_q.m_size)
8315 {
8316 tmp_q.pop_entry(&p1,&p2,&ident);
8317 m_ftb_q.insert_entry(p1,p2,ident);
8318 }
8319 // pop all pending GENERATE EDB from etb queue
8320 while (m_etb_q.m_size)
8321 {
8322 m_etb_q.pop_entry(&p1,&p2,&ident);
8323 if(ident == OMX_COMPONENT_GENERATE_EBD)
8324 {
8325 pending_bd_q.insert_entry(p1,p2,ident);
8326 }
8327 else
8328 {
8329 tmp_q.insert_entry(p1,p2,ident);
8330 }
8331 }
8332 //return all non GENERATE FDB to etb queue
8333 while(tmp_q.m_size)
8334 {
8335 tmp_q.pop_entry(&p1,&p2,&ident);
8336 m_etb_q.insert_entry(p1,p2,ident);
8337 }
8338 pthread_mutex_unlock(&m_lock);
8339 // process all pending buffer dones
8340 while(pending_bd_q.m_size)
8341 {
8342 pending_bd_q.pop_entry(&p1,&p2,&ident);
8343 switch(ident)
8344 {
8345 case OMX_COMPONENT_GENERATE_EBD:
8346 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8347 {
8348 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8349 omx_report_error ();
8350 }
8351 break;
8352
8353 case OMX_COMPONENT_GENERATE_FBD:
8354 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8355 {
8356 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8357 omx_report_error ();
8358 }
8359 break;
8360 }
8361 }
8362}
8363
8364void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8365{
8366 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008367 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8368 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8369 {
8370 new_frame_interval = (act_timestamp > prev_ts)?
8371 act_timestamp - prev_ts :
8372 prev_ts - act_timestamp;
8373 if (new_frame_interval < frm_int || frm_int == 0)
8374 {
8375 frm_int = new_frame_interval;
8376 if(frm_int)
8377 {
8378 drv_ctx.frame_rate.fps_numerator = 1e6;
8379 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008380 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008381 frm_int, drv_ctx.frame_rate.fps_numerator /
8382 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008383
Praneeth Paladugu53478562013-03-12 14:49:46 -07008384 enableAdditionalCores(frm_int);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008385 /* We need to report the difference between this FBD and the previous FBD
8386 * back to the driver for clock scaling purposes. */
8387 struct v4l2_outputparm oparm;
8388 /*XXX: we're providing timing info as seconds per frame rather than frames
8389 * per second.*/
8390 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8391 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
8392
8393 struct v4l2_streamparm sparm;
8394 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8395 sparm.parm.output = oparm;
8396 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm))
8397 {
8398 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8399 performance might be affected");
8400 }
8401
Shalaj Jain273b3e02012-06-22 19:08:03 -07008402 }
8403 }
8404 }
8405 prev_ts = act_timestamp;
8406}
8407
8408void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8409{
8410 if (rst_prev_ts && VALID_TS(act_timestamp))
8411 {
8412 prev_ts = act_timestamp;
8413 rst_prev_ts = false;
8414 }
8415 else if (VALID_TS(prev_ts))
8416 {
8417 bool codec_cond = (drv_ctx.timestamp_adjust)?
8418 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8419 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8420 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8421 if(frm_int > 0 && codec_cond)
8422 {
8423 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8424 act_timestamp = prev_ts + frm_int;
8425 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8426 prev_ts = act_timestamp;
8427 }
8428 else
8429 set_frame_rate(act_timestamp);
8430 }
8431 else if (frm_int > 0) // In this case the frame rate was set along
8432 { // with the port definition, start ts with 0
8433 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8434 rst_prev_ts = true;
8435 }
8436}
8437
8438void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8439{
8440 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8441 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008442 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008443 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008444 OMX_U32 num_MB_in_frame;
8445 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008446 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008447 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008448 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8449 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008450 if (!drv_ctx.extradata_info.uaddr) {
8451 return;
8452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008453 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008454 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8455 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8456 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008457 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008458 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008459 if (data) {
8460 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008461 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008462 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008463 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008464 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008465 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008466 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008467 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008468 struct msm_vidc_interlace_payload *payload;
8469 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008470 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8471 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008472 OMX_U32 mbaff = 0;
8473 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8474 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8475 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8476 else
8477 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8478 if(m_enable_android_native_buffers)
8479 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008480 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008481 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008482 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8483 append_interlace_extradata(p_extra, payload->format);
8484 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8485 }
8486 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008487 case EXTRADATA_FRAME_RATE:
8488 struct msm_vidc_framerate_payload *frame_rate_payload;
8489 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8490 frame_rate = frame_rate_payload->frame_rate;
8491 break;
8492 case EXTRADATA_TIMESTAMP:
8493 struct msm_vidc_ts_payload *time_stamp_payload;
8494 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008495 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008496 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008497 break;
8498 case EXTRADATA_NUM_CONCEALED_MB:
8499 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8500 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8501 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8502 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8503 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8504 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008505 case EXTRADATA_ASPECT_RATIO:
8506 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8507 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8508 ((struct vdec_output_frameinfo *)
8509 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8510 ((struct vdec_output_frameinfo *)
8511 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8512 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008513 case EXTRADATA_RECOVERY_POINT_SEI:
8514 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8515 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8516 recovery_sei_flags = recovery_sei_payload->flags;
8517 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8518 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008519 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008520 }
8521 break;
8522 case EXTRADATA_PANSCAN_WINDOW:
8523 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8524 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008525 default:
8526 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008527 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008528 consumed_len += data->nSize;
8529 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008530 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008531 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008532 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008533 append_frame_info_extradata(p_extra,
8534 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008535 panscan_payload,&((struct vdec_output_frameinfo *)
8536 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008537 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008538unrecognized_extradata:
8539 if(!secure_mode && client_extradata)
8540 append_terminator_extradata(p_extra);
8541 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008542}
8543
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008544OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8545 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008546{
8547 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008548 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008549 if(m_state != OMX_StateLoaded)
8550 {
8551 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8552 return OMX_ErrorIncorrectStateOperation;
8553 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008554 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008555 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008556
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008557 if (!is_internal) {
8558 if (enable)
8559 client_extradata |= requested_extradata;
8560 else
8561 client_extradata = client_extradata & ~requested_extradata;
8562 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008563
8564 if (enable) {
8565 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8566 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8567 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8568 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8569 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8570 " Quality of interlaced clips might be impacted.\n");
8571 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008572 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8573 {
8574 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8575 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8576 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8577 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8578 }
8579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8580 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8581 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8582 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8583 }
8584 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8585 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8586 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8587 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8588 }
8589 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8590 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8591 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8592 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8593 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008594 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8595 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8596 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8597 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8598 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008599 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8600 {
8601 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8602 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8603 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8604 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8605 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008606 }
8607 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008608 return ret;
8609}
8610
8611OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8612{
8613 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8614 OMX_U8 *data_ptr = extra->data, data = 0;
8615 while (byte_count < extra->nDataSize)
8616 {
8617 data = *data_ptr;
8618 while (data)
8619 {
8620 num_MB += (data&0x01);
8621 data >>= 1;
8622 }
8623 data_ptr++;
8624 byte_count++;
8625 }
8626 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8627 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8628 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8629}
8630
8631void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8632{
8633 if (!m_debug_extradata)
8634 return;
8635
8636 DEBUG_PRINT_HIGH(
8637 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008638 " Size: %lu \n"
8639 " Version: %lu \n"
8640 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008641 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008642 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008643 extra->nSize, extra->nVersion.nVersion,
8644 extra->nPortIndex, extra->eType, extra->nDataSize);
8645
Shalaj Jain286b0062013-02-21 20:35:48 -08008646 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008647 {
8648 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8649 DEBUG_PRINT_HIGH(
8650 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008651 " Size: %lu \n"
8652 " Version: %lu \n"
8653 " PortIndex: %lu \n"
8654 " Is Interlace Format: %d \n"
8655 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008656 "=========== End of Interlace ===========\n",
8657 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8658 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8659 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008660 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008661 {
8662 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8663
8664 DEBUG_PRINT_HIGH(
8665 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008666 " Picture Type: %d \n"
8667 " Interlace Type: %d \n"
8668 " Pan Scan Total Frame Num: %lu \n"
8669 " Concealed Macro Blocks: %lu \n"
8670 " frame rate: %lu \n"
8671 " Aspect Ratio X: %lu \n"
8672 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008673 fminfo->ePicType,
8674 fminfo->interlaceType,
8675 fminfo->panScan.numWindows,
8676 fminfo->nConcealedMacroblocks,
8677 fminfo->nFrameRate,
8678 fminfo->aspectRatio.aspectRatioX,
8679 fminfo->aspectRatio.aspectRatioY);
8680
Praneeth Paladugu32284302013-02-14 22:53:06 -08008681 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008682 {
8683 DEBUG_PRINT_HIGH(
8684 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008685 " Pan Scan Frame Num: %lu \n"
8686 " Rectangle x: %ld \n"
8687 " Rectangle y: %ld \n"
8688 " Rectangle dx: %ld \n"
8689 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008690 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8691 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8692 }
8693
8694 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8695 }
8696 else if (extra->eType == OMX_ExtraDataNone)
8697 {
8698 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8699 }
8700 else
8701 {
8702 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8703 }
8704}
8705
8706void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8707 OMX_U32 interlaced_format_type)
8708{
8709 OMX_STREAMINTERLACEFORMAT *interlace_format;
8710 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008711 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8712 return;
8713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008714 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8715 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8716 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8717 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8718 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8719 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8720 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8721 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8722 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8723 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008724 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008725 {
8726 interlace_format->bInterlaceFormat = OMX_FALSE;
8727 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8728 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8729 }
8730 else
8731 {
8732 interlace_format->bInterlaceFormat = OMX_TRUE;
8733 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8734 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8735 }
8736 print_debug_extradata(extra);
8737}
8738
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008739void omx_vdec::fill_aspect_ratio_info(
8740 struct vdec_aspectratioinfo *aspect_ratio_info,
8741 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8742{
8743 m_extradata = frame_info;
8744 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8745 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008746 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008747 m_extradata->aspectRatio.aspectRatioY);
8748}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008749
8750void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008751 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008752 struct msm_vidc_panscan_window_payload *panscan_payload,
8753 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008754{
8755 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008756 struct msm_vidc_panscan_window *panscan_window;
8757 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8758 return;
8759 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008760 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8761 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8762 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8763 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8764 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8765 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8766 switch (picture_type)
8767 {
8768 case PICTURE_TYPE_I:
8769 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8770 break;
8771 case PICTURE_TYPE_P:
8772 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8773 break;
8774 case PICTURE_TYPE_B:
8775 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8776 break;
8777 default:
8778 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8779 }
8780 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8781 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8782 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8783 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8784 else
8785 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008786 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008787 frame_info->nConcealedMacroblocks = num_conceal_mb;
8788 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008789 frame_info->panScan.numWindows = 0;
8790 if(panscan_payload) {
8791 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8792 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008793 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008794 {
8795 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8796 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8797 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8798 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8799 panscan_window++;
8800 }
8801 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008802 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008803 print_debug_extradata(extra);
8804}
8805
8806void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8807{
8808 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8809 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8810 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8811 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8812 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8813 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8814 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8815 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008816 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8817 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008818 portDefn->format.video.nFrameWidth,
8819 portDefn->format.video.nStride,
8820 portDefn->format.video.nSliceHeight);
8821}
8822
8823void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8824{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008825 if (!client_extradata) {
8826 return;
8827 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008828 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8829 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8830 extra->eType = OMX_ExtraDataNone;
8831 extra->nDataSize = 0;
8832 extra->data[0] = 0;
8833
8834 print_debug_extradata(extra);
8835}
8836
8837OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8838{
8839 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8840 if (index >= drv_ctx.ip_buf.actualcount)
8841 {
8842 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8843 return OMX_ErrorInsufficientResources;
8844 }
8845 if (m_desc_buffer_ptr == NULL)
8846 {
8847 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8848 calloc( (sizeof(desc_buffer_hdr)),
8849 drv_ctx.ip_buf.actualcount);
8850 if (m_desc_buffer_ptr == NULL)
8851 {
8852 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8853 return OMX_ErrorInsufficientResources;
8854 }
8855 }
8856
8857 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8858 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8859 {
8860 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8861 return OMX_ErrorInsufficientResources;
8862 }
8863
8864 return eRet;
8865}
8866
8867void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8868{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008869 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008870 if (m_demux_entries < 8192)
8871 {
8872 m_demux_offsets[m_demux_entries++] = address_offset;
8873 }
8874 return;
8875}
8876
8877void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8878{
8879 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8880 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8881 OMX_U32 index = 0;
8882
8883 m_demux_entries = 0;
8884
8885 while (index < bytes_to_parse)
8886 {
8887 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8888 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8889 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8890 (buf[index+2] == 0x01)) )
8891 {
8892 //Found start code, insert address offset
8893 insert_demux_addr_offset(index);
8894 if (buf[index+2] == 0x01) // 3 byte start code
8895 index += 3;
8896 else //4 byte start code
8897 index += 4;
8898 }
8899 else
8900 index++;
8901 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008902 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008903 return;
8904}
8905
8906OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8907{
8908 //fix this, handle 3 byte start code, vc1 terminator entry
8909 OMX_U8 *p_demux_data = NULL;
8910 OMX_U32 desc_data = 0;
8911 OMX_U32 start_addr = 0;
8912 OMX_U32 nal_size = 0;
8913 OMX_U32 suffix_byte = 0;
8914 OMX_U32 demux_index = 0;
8915 OMX_U32 buffer_index = 0;
8916
8917 if (m_desc_buffer_ptr == NULL)
8918 {
8919 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8920 return OMX_ErrorBadParameter;
8921 }
8922
8923 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8924 if (buffer_index > drv_ctx.ip_buf.actualcount)
8925 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008926 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008927 return OMX_ErrorBadParameter;
8928 }
8929
8930 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8931
8932 if ( ((OMX_U8*)p_demux_data == NULL) ||
8933 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8934 {
8935 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8936 return OMX_ErrorBadParameter;
8937 }
8938 else
8939 {
8940 for (; demux_index < m_demux_entries; demux_index++)
8941 {
8942 desc_data = 0;
8943 start_addr = m_demux_offsets[demux_index];
8944 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8945 {
8946 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8947 }
8948 else
8949 {
8950 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8951 }
8952 if (demux_index < (m_demux_entries - 1))
8953 {
8954 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8955 }
8956 else
8957 {
8958 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8959 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008960 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8961 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008962 suffix_byte,
8963 nal_size,
8964 demux_index);
8965 desc_data = (start_addr >> 3) << 1;
8966 desc_data |= (start_addr & 7) << 21;
8967 desc_data |= suffix_byte << 24;
8968
8969 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8970 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8971 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8972 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8973
8974 p_demux_data += 16;
8975 }
8976 if (codec_type_parse == CODEC_TYPE_VC1)
8977 {
8978 DEBUG_PRINT_LOW("VC1 terminator entry");
8979 desc_data = 0;
8980 desc_data = 0x82 << 24;
8981 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8982 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8983 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8984 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8985 p_demux_data += 16;
8986 m_demux_entries++;
8987 }
8988 //Add zero word to indicate end of descriptors
8989 memset(p_demux_data, 0, sizeof(OMX_U32));
8990
8991 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008992 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008993 }
8994 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8995 m_demux_entries = 0;
8996 DEBUG_PRINT_LOW("Demux table complete!");
8997 return OMX_ErrorNone;
8998}
8999
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009000OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009001{
9002 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009003 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07009004 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07009005 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9006 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009007 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009008 delete iDivXDrmDecrypt;
9009 iDivXDrmDecrypt = NULL;
9010 }
9011 }
9012 else {
9013 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009014 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009015 }
9016 return err;
9017}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009018
Vinay Kaliada4f4422013-01-09 10:45:03 -08009019omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9020{
9021 enabled = false;
9022 omx = NULL;
9023 init_members();
9024 ColorFormat = OMX_COLOR_FormatMax;
9025}
9026
9027void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9028{
9029 omx = reinterpret_cast<omx_vdec*>(client);
9030}
9031
9032void omx_vdec::allocate_color_convert_buf::init_members() {
9033 allocated_count = 0;
9034 buffer_size_req = 0;
9035 buffer_alignment_req = 0;
9036 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9037 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9038 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9039 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9040#ifdef USE_ION
9041 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9042#endif
9043 for (int i = 0; i < MAX_COUNT;i++)
9044 pmem_fd[i] = -1;
9045}
9046
9047omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
9048 c2d.destroy();
9049}
9050
9051bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9052{
9053 bool status = true;
9054 unsigned int src_size = 0, destination_size = 0;
9055 OMX_COLOR_FORMATTYPE drv_color_format;
9056 if (!omx){
9057 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9058 return false;
9059 }
9060 if (!enabled){
9061 DEBUG_PRINT_ERROR("\n No color conversion required");
9062 return status;
9063 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009064 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009065 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9066 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9067 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009068 status = false;
9069 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009070 }
9071 c2d.close();
9072 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9073 omx->drv_ctx.video_resolution.frame_width,
9074 NV12_128m,YCbCr420P);
9075 if (status) {
9076 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9077 if (status)
9078 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9079 }
9080 if (status) {
9081 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9082 !destination_size) {
9083 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9084 "driver size %d destination size %d",
9085 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9086 status = false;
9087 c2d.close();
9088 buffer_size_req = 0;
9089 } else {
9090 buffer_size_req = destination_size;
9091 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9092 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9093 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9094 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9095 }
9096 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009097fail_update_buf_req:
9098 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009099 return status;
9100}
9101
9102bool omx_vdec::allocate_color_convert_buf::set_color_format(
9103 OMX_COLOR_FORMATTYPE dest_color_format)
9104{
9105 bool status = true;
9106 OMX_COLOR_FORMATTYPE drv_color_format;
9107 if (!omx){
9108 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9109 return false;
9110 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009111 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009112 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9113 drv_color_format = (OMX_COLOR_FORMATTYPE)
9114 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9115 else {
9116 DEBUG_PRINT_ERROR("\n Incorrect color format");
9117 status = false;
9118 }
9119 if (status && (drv_color_format != dest_color_format)) {
9120 DEBUG_PRINT_LOW("Enabling C2D\n");
9121 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9122 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9123 status = false;
9124 } else {
9125 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9126 if (enabled)
9127 c2d.destroy();
9128 enabled = false;
9129 if (!c2d.init()) {
9130 DEBUG_PRINT_ERROR("\n open failed for c2d");
9131 status = false;
9132 } else
9133 enabled = true;
9134 }
9135 } else {
9136 if (enabled)
9137 c2d.destroy();
9138 enabled = false;
9139 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009140 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009141 return status;
9142}
9143
9144OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9145{
9146 if (!omx){
9147 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9148 return NULL;
9149 }
9150 if (!enabled)
9151 return omx->m_out_mem_ptr;
9152 return m_out_mem_ptr_client;
9153}
9154
9155OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9156 (OMX_BUFFERHEADERTYPE *bufadd)
9157{
9158 if (!omx){
9159 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9160 return NULL;
9161 }
9162 if (!enabled)
9163 return bufadd;
9164
9165 unsigned index = 0;
9166 index = bufadd - omx->m_out_mem_ptr;
9167 if (index < omx->drv_ctx.op_buf.actualcount) {
9168 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9169 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9170 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009171 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009172 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009173 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9174 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009175 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009176 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9177 if (!status){
9178 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009179 m_out_mem_ptr_client[index].nFilledLen = 0;
9180 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009181 }
9182 } else
9183 m_out_mem_ptr_client[index].nFilledLen = 0;
9184 return &m_out_mem_ptr_client[index];
9185 }
9186 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9187 return NULL;
9188}
9189
9190OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9191 (OMX_BUFFERHEADERTYPE *bufadd)
9192{
9193 if (!omx){
9194 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9195 return NULL;
9196 }
9197 if (!enabled)
9198 return bufadd;
9199 unsigned index = 0;
9200 index = bufadd - m_out_mem_ptr_client;
9201 if (index < omx->drv_ctx.op_buf.actualcount) {
9202 return &omx->m_out_mem_ptr[index];
9203 }
9204 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9205 return NULL;
9206}
9207bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9208 (unsigned int &buffer_size)
9209{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009210 bool status = true;
9211 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009212 if (!enabled)
9213 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009214 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009215 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9216 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009217 status = false;
9218 goto fail_get_buffer_size;
9219 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009220 }
9221 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9222 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9223 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9224 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009225fail_get_buffer_size:
9226 pthread_mutex_unlock(&omx->c_lock);
9227 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009228}
9229OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9230 OMX_BUFFERHEADERTYPE *bufhdr) {
9231 unsigned int index = 0;
9232
9233 if (!enabled)
9234 return omx->free_output_buffer(bufhdr);
9235 if (enabled && omx->is_component_secure())
9236 return OMX_ErrorNone;
9237 if (!allocated_count || !bufhdr) {
9238 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9239 return OMX_ErrorBadParameter;
9240 }
9241 index = bufhdr - m_out_mem_ptr_client;
9242 if (index >= omx->drv_ctx.op_buf.actualcount){
9243 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9244 return OMX_ErrorBadParameter;
9245 }
9246 if (pmem_fd[index] > 0) {
9247 munmap(pmem_baseaddress[index], buffer_size_req);
9248 close(pmem_fd[index]);
9249 }
9250 pmem_fd[index] = -1;
9251#ifdef USE_ION
9252 omx->free_ion_memory(&op_buf_ion_info[index]);
9253#endif
9254 m_heap_ptr[index].video_heap_ptr = NULL;
9255 if (allocated_count > 0)
9256 allocated_count--;
9257 else
9258 allocated_count = 0;
9259 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009260 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009261 c2d.close();
9262 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009263 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009264 }
9265 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9266}
9267
9268OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9269 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9270{
9271 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9272 if (!enabled){
9273 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9274 return eRet;
9275 }
9276 if (enabled && omx->is_component_secure()) {
9277 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9278 omx->is_component_secure());
9279 return OMX_ErrorUnsupportedSetting;
9280 }
9281 if (!bufferHdr || bytes > buffer_size_req) {
9282 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009283 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009284 buffer_size_req,bytes);
9285 return OMX_ErrorBadParameter;
9286 }
9287 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9288 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9289 return OMX_ErrorInsufficientResources;
9290 }
9291 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9292 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9293 port,appData,omx->drv_ctx.op_buf.buffer_size);
9294 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9295 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9296 return eRet;
9297 }
9298 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9299 omx->drv_ctx.op_buf.actualcount) {
9300 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9301 (temp_bufferHdr - omx->m_out_mem_ptr));
9302 return OMX_ErrorUndefined;
9303 }
9304 unsigned int i = allocated_count;
9305#ifdef USE_ION
9306 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9307 buffer_size_req,buffer_alignment_req,
9308 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009309 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009310 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9311 if (op_buf_ion_info[i].ion_device_fd < 0) {
9312 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9313 return OMX_ErrorInsufficientResources;
9314 }
9315 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9316 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9317
9318 if (pmem_baseaddress[i] == MAP_FAILED) {
9319 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9320 close(pmem_fd[i]);
9321 omx->free_ion_memory(&op_buf_ion_info[i]);
9322 return OMX_ErrorInsufficientResources;
9323 }
9324 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9325 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9326 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9327#endif
9328 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9329 m_pmem_info_client[i].offset = 0;
9330 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9331 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9332 m_platform_list_client[i].nEntries = 1;
9333 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9334 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9335 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9336 m_out_mem_ptr_client[i].nFilledLen = 0;
9337 m_out_mem_ptr_client[i].nFlags = 0;
9338 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9339 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9340 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9341 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9342 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9343 m_out_mem_ptr_client[i].pAppPrivate = appData;
9344 *bufferHdr = &m_out_mem_ptr_client[i];
9345 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9346 allocated_count++;
9347 return eRet;
9348}
9349
9350bool omx_vdec::is_component_secure()
9351{
9352 return secure_mode;
9353}
9354
9355bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9356{
9357 bool status = true;
9358 if (!enabled) {
9359 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9360 dest_color_format = (OMX_COLOR_FORMATTYPE)
9361 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9362 else
9363 status = false;
9364 } else {
9365 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9366 status = false;
9367 } else
9368 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9369 }
9370 return status;
9371}
Praneeth Paladugu53478562013-03-12 14:49:46 -07009372
9373void omx_vdec::enableAdditionalCores(int frame_interval)
9374{
9375 DEBUG_PRINT_LOW("Setting frame rate to 1/(%dusec)", frame_interval);
9376 if (frame_interval < 33000)
9377 {
9378 DEBUG_PRINT_HIGH("Turning on additional CPU cores");
9379 if (NULL == opt_handle) {
9380 char opt_lib_path[PATH_MAX] = {0};
9381
9382 if (property_get("ro.vendor.extension_library", opt_lib_path, NULL) != 0) {
9383 if ((opt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
9384 DEBUG_PRINT_ERROR("Unable to open %s: %s\n", opt_lib_path, dlerror());
9385 } else {
9386 perf_lock_acq = (int(*)(int, int, int*,int))dlsym(opt_handle, "perf_lock_acq");
9387 if (perf_lock_acq == NULL) {
9388 DEBUG_PRINT_ERROR("failed to get lock_acq sym");
9389 }
9390
9391 perf_lock_rel = (int(*)(int))dlsym(opt_handle, "perf_lock_rel");
9392 if (perf_lock_rel == NULL) {
9393 DEBUG_PRINT_ERROR("failed to get lock_rel sym");
9394 }
9395 }
9396 } else {
9397 DEBUG_PRINT_ERROR("Property ro.vendor.extension_library does not exist.");
9398 }
9399 }
9400
9401 int decode_opts[1] = {0x704}; //value of last nibble == # of cores
9402 if (perf_lock_acq && perf_lock_handle < 0) {
9403 DEBUG_PRINT_LOW("Lock acquired");
9404 perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, decode_opts, 1);
9405 }
9406 }
9407}