blob: c79ea758be15d2dc2af87927ff1f853b54e68471 [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;
Vinay Kaliadae8ad62013-04-26 20:42:10 -0700709 if (drv_ctx.video_driver_fd >=0 ) {
710 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
711 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700712 }
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 Kaliadae8ad62013-04-26 20:42:10 -07001428 ret = subscribe_to_events(drv_ctx.video_driver_fd);
1429 if (!ret)
1430 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1431 if(ret) {
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001432 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1433 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001435
1436#ifdef INPUT_BUFFER_LOG
1437 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1438#endif
1439#ifdef OUTPUT_BUFFER_LOG
1440 outputBufferFile1 = fopen (outputfilename, "ab");
1441#endif
1442#ifdef OUTPUT_EXTRADATA_LOG
1443 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1444#endif
1445
1446 // Copy the role information which provides the decoder kind
1447 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001448
Shalaj Jain273b3e02012-06-22 19:08:03 -07001449 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1450 OMX_MAX_STRINGNAME_SIZE))
1451 {
1452 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1453 OMX_MAX_STRINGNAME_SIZE);
1454 drv_ctx.timestamp_adjust = true;
1455 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1456 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001457 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001458 /*Initialize Start Code for MPEG4*/
1459 codec_type_parse = CODEC_TYPE_MPEG4;
1460 m_frame_parser.init_start_codes (codec_type_parse);
1461#ifdef INPUT_BUFFER_LOG
1462 strcat(inputfilename, "m4v");
1463#endif
1464 }
1465 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1466 OMX_MAX_STRINGNAME_SIZE))
1467 {
1468 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1469 OMX_MAX_STRINGNAME_SIZE);
1470 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001471 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001472 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1473 /*Initialize Start Code for MPEG2*/
1474 codec_type_parse = CODEC_TYPE_MPEG2;
1475 m_frame_parser.init_start_codes (codec_type_parse);
1476#ifdef INPUT_BUFFER_LOG
1477 strcat(inputfilename, "mpg");
1478#endif
1479 }
1480 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1481 OMX_MAX_STRINGNAME_SIZE))
1482 {
1483 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1484 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1485 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1486 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001487 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001488 codec_type_parse = CODEC_TYPE_H263;
1489 m_frame_parser.init_start_codes (codec_type_parse);
1490#ifdef INPUT_BUFFER_LOG
1491 strcat(inputfilename, "263");
1492#endif
1493 }
1494 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1495 OMX_MAX_STRINGNAME_SIZE))
1496 {
1497 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1498 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1499 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1500 output_capability = V4L2_PIX_FMT_DIVX_311;
1501 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1502 codec_type_parse = CODEC_TYPE_DIVX;
1503 m_frame_parser.init_start_codes (codec_type_parse);
1504
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001505 eRet = createDivxDrmContext();
1506 if (eRet != OMX_ErrorNone) {
1507 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1508 return eRet;
1509 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001510 }
1511 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1512 OMX_MAX_STRINGNAME_SIZE))
1513 {
1514 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1515 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1516 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1517 output_capability = V4L2_PIX_FMT_DIVX;
1518 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1519 codec_type_parse = CODEC_TYPE_DIVX;
1520 codec_ambiguous = true;
1521 m_frame_parser.init_start_codes (codec_type_parse);
1522
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001523 eRet = createDivxDrmContext();
1524 if (eRet != OMX_ErrorNone) {
1525 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1526 return eRet;
1527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001528 }
1529 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1530 OMX_MAX_STRINGNAME_SIZE))
1531 {
1532 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1533 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1534 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1535 output_capability = V4L2_PIX_FMT_DIVX;
1536 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1537 codec_type_parse = CODEC_TYPE_DIVX;
1538 codec_ambiguous = true;
1539 m_frame_parser.init_start_codes (codec_type_parse);
1540
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001541 eRet = createDivxDrmContext();
1542 if (eRet != OMX_ErrorNone) {
1543 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1544 return eRet;
1545 }
1546
Shalaj Jain273b3e02012-06-22 19:08:03 -07001547 }
1548 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1549 OMX_MAX_STRINGNAME_SIZE))
1550 {
1551 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1552 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1553 output_capability=V4L2_PIX_FMT_H264;
1554 eCompressionFormat = OMX_VIDEO_CodingAVC;
1555 codec_type_parse = CODEC_TYPE_H264;
1556 m_frame_parser.init_start_codes (codec_type_parse);
1557 m_frame_parser.init_nal_length(nal_length);
1558#ifdef INPUT_BUFFER_LOG
1559 strcat(inputfilename, "264");
1560#endif
1561 }
1562 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1563 OMX_MAX_STRINGNAME_SIZE))
1564 {
1565 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1566 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1567 eCompressionFormat = OMX_VIDEO_CodingWMV;
1568 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001569 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001570 m_frame_parser.init_start_codes (codec_type_parse);
1571#ifdef INPUT_BUFFER_LOG
1572 strcat(inputfilename, "vc1");
1573#endif
1574 }
1575 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1576 OMX_MAX_STRINGNAME_SIZE))
1577 {
1578 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1579 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1580 eCompressionFormat = OMX_VIDEO_CodingWMV;
1581 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001582 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001583 m_frame_parser.init_start_codes (codec_type_parse);
1584#ifdef INPUT_BUFFER_LOG
1585 strcat(inputfilename, "vc1");
1586#endif
1587 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001588 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1589 OMX_MAX_STRINGNAME_SIZE))
1590 {
1591 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1592 output_capability=V4L2_PIX_FMT_VP8;
1593 eCompressionFormat = OMX_VIDEO_CodingVPX;
1594 codec_type_parse = CODEC_TYPE_VP8;
1595 arbitrary_bytes = false;
1596 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001597 else
1598 {
1599 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1600 eRet = OMX_ErrorInvalidComponentName;
1601 }
1602#ifdef INPUT_BUFFER_LOG
1603 inputBufferFile1 = fopen (inputfilename, "ab");
1604#endif
1605 if (eRet == OMX_ErrorNone)
1606 {
1607
Vinay Kaliada4f4422013-01-09 10:45:03 -08001608 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1609 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1610 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1611 if (!client_buffers.set_color_format(dest_color_format)) {
1612 DEBUG_PRINT_ERROR("\n Setting color format failed");
1613 eRet = OMX_ErrorInsufficientResources;
1614 }
1615
Shalaj Jain273b3e02012-06-22 19:08:03 -07001616 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001617
1618 struct v4l2_capability cap;
1619 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1620 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001621 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001622 /*TODO: How to handle this case */
1623 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001624 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001625 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1626 cap.bus_info, cap.version, cap.capabilities);
1627 }
1628 ret=0;
1629 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1630 fdesc.index=0;
1631 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001632 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001633 fdesc.pixelformat, fdesc.flags);
1634 fdesc.index++;
1635 }
1636 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1637 fdesc.index=0;
1638 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1639
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001640 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001641 fdesc.pixelformat, fdesc.flags);
1642 fdesc.index++;
1643 }
Vinay Kalia21649b32013-03-18 17:28:07 -07001644 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1646 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1647 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1648 fmt.fmt.pix_mp.pixelformat = output_capability;
1649 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1650 if (ret) {
1651 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001652 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001653 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001654 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001655 if (codec_ambiguous) {
1656 if (output_capability == V4L2_PIX_FMT_DIVX) {
1657 struct v4l2_control divx_ctrl;
1658
1659 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001660 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001661 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001662 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001663 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001664 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665 }
1666
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001667 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001668 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001669 if (ret) {
1670 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1671 }
1672 } else {
1673 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1674 }
1675 }
1676
Arun Menon6836ba02013-02-19 20:37:40 -08001677 //Get the hardware capabilities
1678 memset((void *)&frmsize,0,sizeof(frmsize));
1679 frmsize.index = 0;
1680 frmsize.pixel_format = output_capability;
1681 ret = ioctl(drv_ctx.video_driver_fd,
1682 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1683 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1684 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1685 return OMX_ErrorHardware;
1686 }
1687
1688 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1689 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1690 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1691 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1692 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1693 }
1694
Shalaj Jain273b3e02012-06-22 19:08:03 -07001695 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1696 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1697 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001698 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001699 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1700 if (ret) {
1701 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001702 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001703 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001704 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001705 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001706 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1707 control.value = 1;
1708 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1709 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1710 if (ret) {
1711 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001712 return OMX_ErrorInsufficientResources;
1713 }
1714 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001715
1716 /*Get the Buffer requirements for input and output ports*/
1717 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1718 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001719 if (secure_mode) {
1720 drv_ctx.op_buf.alignment=SZ_1M;
1721 drv_ctx.ip_buf.alignment=SZ_1M;
1722 } else {
1723 drv_ctx.op_buf.alignment=SZ_4K;
1724 drv_ctx.ip_buf.alignment=SZ_4K;
1725 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001726 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1727 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001728 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1729 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1730 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1731 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732 drv_ctx.idr_only_decoding = 0;
1733
Vinay Kalia5713bb32013-01-16 18:39:59 -08001734 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001735#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001736 if (eRet == OMX_ErrorNone && !secure_mode)
1737 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001738#endif
Praneeth Paladugu1d654b02013-04-02 10:28:29 -07001739 if (output_capability != V4L2_PIX_FMT_VC1_ANNEX_L &&
1740 output_capability != V4L2_PIX_FMT_VC1_ANNEX_G ) {
1741 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
1742 control.value = 1;
1743 DEBUG_PRINT_HIGH("Enabling smooth streaming!\n");
1744 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
1745 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming");
1746 }
1747 }
Vinay Kalia5713bb32013-01-16 18:39:59 -08001748 eRet=get_buffer_req(&drv_ctx.ip_buf);
1749 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1750 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001751 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1752 {
1753 if (m_frame_parser.mutils == NULL)
1754 {
1755 m_frame_parser.mutils = new H264_Utils();
1756
1757 if (m_frame_parser.mutils == NULL)
1758 {
1759 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1760 eRet = OMX_ErrorInsufficientResources;
1761 }
1762 else
1763 {
1764 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1765 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1766 h264_scratch.nFilledLen = 0;
1767 h264_scratch.nOffset = 0;
1768
1769 if (h264_scratch.pBuffer == NULL)
1770 {
1771 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1772 return OMX_ErrorInsufficientResources;
1773 }
1774 m_frame_parser.mutils->initialize_frame_checking_environment();
1775 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1776 }
1777 }
1778
1779 h264_parser = new h264_stream_parser();
1780 if (!h264_parser)
1781 {
1782 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1783 eRet = OMX_ErrorInsufficientResources;
1784 }
1785 }
1786
1787 if(pipe(fds))
1788 {
1789 DEBUG_PRINT_ERROR("pipe creation failed\n");
1790 eRet = OMX_ErrorInsufficientResources;
1791 }
1792 else
1793 {
1794 int temp1[2];
1795 if(fds[0] == 0 || fds[1] == 0)
1796 {
1797 if (pipe (temp1))
1798 {
1799 DEBUG_PRINT_ERROR("pipe creation failed\n");
1800 return OMX_ErrorInsufficientResources;
1801 }
1802 //close (fds[0]);
1803 //close (fds[1]);
1804 fds[0] = temp1 [0];
1805 fds[1] = temp1 [1];
1806 }
1807 m_pipe_in = fds[0];
1808 m_pipe_out = fds[1];
1809 r = pthread_create(&msg_thread_id,0,message_thread,this);
1810
1811 if(r < 0)
1812 {
1813 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1814 eRet = OMX_ErrorInsufficientResources;
1815 }
1816 }
1817 }
1818
1819 if (eRet != OMX_ErrorNone)
1820 {
1821 DEBUG_PRINT_ERROR("\n Component Init Failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001822 }
1823 else
1824 {
1825 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1826 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001827 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1828 return eRet;
1829}
1830
1831/* ======================================================================
1832FUNCTION
1833 omx_vdec::GetComponentVersion
1834
1835DESCRIPTION
1836 Returns the component version.
1837
1838PARAMETERS
1839 TBD.
1840
1841RETURN VALUE
1842 OMX_ErrorNone.
1843
1844========================================================================== */
1845OMX_ERRORTYPE omx_vdec::get_component_version
1846 (
1847 OMX_IN OMX_HANDLETYPE hComp,
1848 OMX_OUT OMX_STRING componentName,
1849 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1850 OMX_OUT OMX_VERSIONTYPE* specVersion,
1851 OMX_OUT OMX_UUIDTYPE* componentUUID
1852 )
1853{
1854 if(m_state == OMX_StateInvalid)
1855 {
1856 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1857 return OMX_ErrorInvalidState;
1858 }
1859 /* TBD -- Return the proper version */
1860 if (specVersion)
1861 {
1862 specVersion->nVersion = OMX_SPEC_VERSION;
1863 }
1864 return OMX_ErrorNone;
1865}
1866/* ======================================================================
1867FUNCTION
1868 omx_vdec::SendCommand
1869
1870DESCRIPTION
1871 Returns zero if all the buffers released..
1872
1873PARAMETERS
1874 None.
1875
1876RETURN VALUE
1877 true/false
1878
1879========================================================================== */
1880OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1881 OMX_IN OMX_COMMANDTYPE cmd,
1882 OMX_IN OMX_U32 param1,
1883 OMX_IN OMX_PTR cmdData
1884 )
1885{
1886 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1887 if(m_state == OMX_StateInvalid)
1888 {
1889 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1890 return OMX_ErrorInvalidState;
1891 }
1892 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1893 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1894 {
1895 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001896 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001897 return OMX_ErrorBadPortIndex;
1898 }
1899 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1900 sem_wait(&m_cmd_lock);
1901 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1902 return OMX_ErrorNone;
1903}
1904
1905/* ======================================================================
1906FUNCTION
1907 omx_vdec::SendCommand
1908
1909DESCRIPTION
1910 Returns zero if all the buffers released..
1911
1912PARAMETERS
1913 None.
1914
1915RETURN VALUE
1916 true/false
1917
1918========================================================================== */
1919OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1920 OMX_IN OMX_COMMANDTYPE cmd,
1921 OMX_IN OMX_U32 param1,
1922 OMX_IN OMX_PTR cmdData
1923 )
1924{
1925 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1926 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1927 int bFlag = 1,sem_posted = 0,ret=0;
1928
1929 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1930 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1931 m_state, eState);
1932
1933 if(cmd == OMX_CommandStateSet)
1934 {
1935 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1936 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1937 /***************************/
1938 /* Current State is Loaded */
1939 /***************************/
1940 if(m_state == OMX_StateLoaded)
1941 {
1942 if(eState == OMX_StateIdle)
1943 {
1944 //if all buffers are allocated or all ports disabled
1945 if(allocate_done() ||
1946 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1947 {
1948 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1949 }
1950 else
1951 {
1952 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1953 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1954 // Skip the event notification
1955 bFlag = 0;
1956 }
1957 }
1958 /* Requesting transition from Loaded to Loaded */
1959 else if(eState == OMX_StateLoaded)
1960 {
1961 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1962 post_event(OMX_EventError,OMX_ErrorSameState,\
1963 OMX_COMPONENT_GENERATE_EVENT);
1964 eRet = OMX_ErrorSameState;
1965 }
1966 /* Requesting transition from Loaded to WaitForResources */
1967 else if(eState == OMX_StateWaitForResources)
1968 {
1969 /* Since error is None , we will post an event
1970 at the end of this function definition */
1971 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1972 }
1973 /* Requesting transition from Loaded to Executing */
1974 else if(eState == OMX_StateExecuting)
1975 {
1976 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1977 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1978 OMX_COMPONENT_GENERATE_EVENT);
1979 eRet = OMX_ErrorIncorrectStateTransition;
1980 }
1981 /* Requesting transition from Loaded to Pause */
1982 else if(eState == OMX_StatePause)
1983 {
1984 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1985 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1986 OMX_COMPONENT_GENERATE_EVENT);
1987 eRet = OMX_ErrorIncorrectStateTransition;
1988 }
1989 /* Requesting transition from Loaded to Invalid */
1990 else if(eState == OMX_StateInvalid)
1991 {
1992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1993 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1994 eRet = OMX_ErrorInvalidState;
1995 }
1996 else
1997 {
1998 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1999 eState);
2000 eRet = OMX_ErrorBadParameter;
2001 }
2002 }
2003
2004 /***************************/
2005 /* Current State is IDLE */
2006 /***************************/
2007 else if(m_state == OMX_StateIdle)
2008 {
2009 if(eState == OMX_StateLoaded)
2010 {
2011 if(release_done())
2012 {
2013 /*
2014 Since error is None , we will post an event at the end
2015 of this function definition
2016 */
2017 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2018 }
2019 else
2020 {
2021 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2022 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2023 // Skip the event notification
2024 bFlag = 0;
2025 }
2026 }
2027 /* Requesting transition from Idle to Executing */
2028 else if(eState == OMX_StateExecuting)
2029 {
2030 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2031 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2032 bFlag = 1;
2033 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2034 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002035 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002036 }
2037 /* Requesting transition from Idle to Idle */
2038 else if(eState == OMX_StateIdle)
2039 {
2040 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2041 post_event(OMX_EventError,OMX_ErrorSameState,\
2042 OMX_COMPONENT_GENERATE_EVENT);
2043 eRet = OMX_ErrorSameState;
2044 }
2045 /* Requesting transition from Idle to WaitForResources */
2046 else if(eState == OMX_StateWaitForResources)
2047 {
2048 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2049 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2050 OMX_COMPONENT_GENERATE_EVENT);
2051 eRet = OMX_ErrorIncorrectStateTransition;
2052 }
2053 /* Requesting transition from Idle to Pause */
2054 else if(eState == OMX_StatePause)
2055 {
2056 /*To pause the Video core we need to start the driver*/
2057 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2058 NULL) < */0)
2059 {
2060 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2061 omx_report_error ();
2062 eRet = OMX_ErrorHardware;
2063 }
2064 else
2065 {
2066 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2067 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2068 bFlag = 0;
2069 }
2070 }
2071 /* Requesting transition from Idle to Invalid */
2072 else if(eState == OMX_StateInvalid)
2073 {
2074 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2075 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2076 eRet = OMX_ErrorInvalidState;
2077 }
2078 else
2079 {
2080 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2081 eRet = OMX_ErrorBadParameter;
2082 }
2083 }
2084
2085 /******************************/
2086 /* Current State is Executing */
2087 /******************************/
2088 else if(m_state == OMX_StateExecuting)
2089 {
2090 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2091 /* Requesting transition from Executing to Idle */
2092 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002093 {
2094 /* Since error is None , we will post an event
2095 at the end of this function definition
2096 */
2097 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002098 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002099 if(!sem_posted)
2100 {
2101 sem_posted = 1;
2102 sem_post (&m_cmd_lock);
2103 execute_omx_flush(OMX_ALL);
2104 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002105 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002106 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002107 /* Requesting transition from Executing to Paused */
2108 else if(eState == OMX_StatePause)
2109 {
2110 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002111 m_state = OMX_StatePause;
2112 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002113 }
2114 /* Requesting transition from Executing to Loaded */
2115 else if(eState == OMX_StateLoaded)
2116 {
2117 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2118 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2119 OMX_COMPONENT_GENERATE_EVENT);
2120 eRet = OMX_ErrorIncorrectStateTransition;
2121 }
2122 /* Requesting transition from Executing to WaitForResources */
2123 else if(eState == OMX_StateWaitForResources)
2124 {
2125 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2126 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2127 OMX_COMPONENT_GENERATE_EVENT);
2128 eRet = OMX_ErrorIncorrectStateTransition;
2129 }
2130 /* Requesting transition from Executing to Executing */
2131 else if(eState == OMX_StateExecuting)
2132 {
2133 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2134 post_event(OMX_EventError,OMX_ErrorSameState,\
2135 OMX_COMPONENT_GENERATE_EVENT);
2136 eRet = OMX_ErrorSameState;
2137 }
2138 /* Requesting transition from Executing to Invalid */
2139 else if(eState == OMX_StateInvalid)
2140 {
2141 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2142 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2143 eRet = OMX_ErrorInvalidState;
2144 }
2145 else
2146 {
2147 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2148 eRet = OMX_ErrorBadParameter;
2149 }
2150 }
2151 /***************************/
2152 /* Current State is Pause */
2153 /***************************/
2154 else if(m_state == OMX_StatePause)
2155 {
2156 /* Requesting transition from Pause to Executing */
2157 if(eState == OMX_StateExecuting)
2158 {
2159 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002160 m_state = OMX_StateExecuting;
2161 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002162 }
2163 /* Requesting transition from Pause to Idle */
2164 else if(eState == OMX_StateIdle)
2165 {
2166 /* Since error is None , we will post an event
2167 at the end of this function definition */
2168 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2169 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2170 if(!sem_posted)
2171 {
2172 sem_posted = 1;
2173 sem_post (&m_cmd_lock);
2174 execute_omx_flush(OMX_ALL);
2175 }
2176 bFlag = 0;
2177 }
2178 /* Requesting transition from Pause to loaded */
2179 else if(eState == OMX_StateLoaded)
2180 {
2181 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2182 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2183 OMX_COMPONENT_GENERATE_EVENT);
2184 eRet = OMX_ErrorIncorrectStateTransition;
2185 }
2186 /* Requesting transition from Pause to WaitForResources */
2187 else if(eState == OMX_StateWaitForResources)
2188 {
2189 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2190 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2191 OMX_COMPONENT_GENERATE_EVENT);
2192 eRet = OMX_ErrorIncorrectStateTransition;
2193 }
2194 /* Requesting transition from Pause to Pause */
2195 else if(eState == OMX_StatePause)
2196 {
2197 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2198 post_event(OMX_EventError,OMX_ErrorSameState,\
2199 OMX_COMPONENT_GENERATE_EVENT);
2200 eRet = OMX_ErrorSameState;
2201 }
2202 /* Requesting transition from Pause to Invalid */
2203 else if(eState == OMX_StateInvalid)
2204 {
2205 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2206 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2207 eRet = OMX_ErrorInvalidState;
2208 }
2209 else
2210 {
2211 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2212 eRet = OMX_ErrorBadParameter;
2213 }
2214 }
2215 /***************************/
2216 /* Current State is WaitForResources */
2217 /***************************/
2218 else if(m_state == OMX_StateWaitForResources)
2219 {
2220 /* Requesting transition from WaitForResources to Loaded */
2221 if(eState == OMX_StateLoaded)
2222 {
2223 /* Since error is None , we will post an event
2224 at the end of this function definition */
2225 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2226 }
2227 /* Requesting transition from WaitForResources to WaitForResources */
2228 else if (eState == OMX_StateWaitForResources)
2229 {
2230 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2231 post_event(OMX_EventError,OMX_ErrorSameState,
2232 OMX_COMPONENT_GENERATE_EVENT);
2233 eRet = OMX_ErrorSameState;
2234 }
2235 /* Requesting transition from WaitForResources to Executing */
2236 else if(eState == OMX_StateExecuting)
2237 {
2238 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2239 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2240 OMX_COMPONENT_GENERATE_EVENT);
2241 eRet = OMX_ErrorIncorrectStateTransition;
2242 }
2243 /* Requesting transition from WaitForResources to Pause */
2244 else if(eState == OMX_StatePause)
2245 {
2246 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2247 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2248 OMX_COMPONENT_GENERATE_EVENT);
2249 eRet = OMX_ErrorIncorrectStateTransition;
2250 }
2251 /* Requesting transition from WaitForResources to Invalid */
2252 else if(eState == OMX_StateInvalid)
2253 {
2254 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2255 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2256 eRet = OMX_ErrorInvalidState;
2257 }
2258 /* Requesting transition from WaitForResources to Loaded -
2259 is NOT tested by Khronos TS */
2260
2261 }
2262 else
2263 {
2264 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2265 eRet = OMX_ErrorBadParameter;
2266 }
2267 }
2268 /********************************/
2269 /* Current State is Invalid */
2270 /*******************************/
2271 else if(m_state == OMX_StateInvalid)
2272 {
2273 /* State Transition from Inavlid to any state */
2274 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2275 || OMX_StateIdle || OMX_StateExecuting
2276 || OMX_StatePause || OMX_StateInvalid))
2277 {
2278 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2279 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2280 OMX_COMPONENT_GENERATE_EVENT);
2281 eRet = OMX_ErrorInvalidState;
2282 }
2283 }
2284 else if (cmd == OMX_CommandFlush)
2285 {
2286 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002287 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002288 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2289 {
2290 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2291 }
2292 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2293 {
2294 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2295 }
2296 if (!sem_posted){
2297 sem_posted = 1;
2298 DEBUG_PRINT_LOW("\n Set the Semaphore");
2299 sem_post (&m_cmd_lock);
2300 execute_omx_flush(param1);
2301 }
2302 bFlag = 0;
2303 }
2304 else if ( cmd == OMX_CommandPortEnable)
2305 {
2306 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002307 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002308 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2309 {
2310 m_inp_bEnabled = OMX_TRUE;
2311
2312 if( (m_state == OMX_StateLoaded &&
2313 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2314 || allocate_input_done())
2315 {
2316 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2317 OMX_COMPONENT_GENERATE_EVENT);
2318 }
2319 else
2320 {
2321 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2322 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2323 // Skip the event notification
2324 bFlag = 0;
2325 }
2326 }
2327 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2328 {
2329 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2330 m_out_bEnabled = OMX_TRUE;
2331
2332 if( (m_state == OMX_StateLoaded &&
2333 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2334 || (allocate_output_done()))
2335 {
2336 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2337 OMX_COMPONENT_GENERATE_EVENT);
2338
2339 }
2340 else
2341 {
2342 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2343 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2344 // Skip the event notification
2345 bFlag = 0;
2346 }
2347 }
2348 }
2349 else if (cmd == OMX_CommandPortDisable)
2350 {
2351 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002352 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002353 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2354 {
2355 m_inp_bEnabled = OMX_FALSE;
2356 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2357 && release_input_done())
2358 {
2359 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2360 OMX_COMPONENT_GENERATE_EVENT);
2361 }
2362 else
2363 {
2364 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2365 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2366 {
2367 if(!sem_posted)
2368 {
2369 sem_posted = 1;
2370 sem_post (&m_cmd_lock);
2371 }
2372 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2373 }
2374
2375 // Skip the event notification
2376 bFlag = 0;
2377 }
2378 }
2379 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2380 {
2381 m_out_bEnabled = OMX_FALSE;
2382 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2383 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2384 && release_output_done())
2385 {
2386 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2387 OMX_COMPONENT_GENERATE_EVENT);
2388 }
2389 else
2390 {
2391 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2392 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2393 {
2394 if (!sem_posted)
2395 {
2396 sem_posted = 1;
2397 sem_post (&m_cmd_lock);
2398 }
2399 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2400 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2401 }
2402 // Skip the event notification
2403 bFlag = 0;
2404
2405 }
2406 }
2407 }
2408 else
2409 {
2410 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2411 eRet = OMX_ErrorNotImplemented;
2412 }
2413 if(eRet == OMX_ErrorNone && bFlag)
2414 {
2415 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2416 }
2417 if(!sem_posted)
2418 {
2419 sem_post(&m_cmd_lock);
2420 }
2421
2422 return eRet;
2423}
2424
2425/* ======================================================================
2426FUNCTION
2427 omx_vdec::ExecuteOmxFlush
2428
2429DESCRIPTION
2430 Executes the OMX flush.
2431
2432PARAMETERS
2433 flushtype - input flush(1)/output flush(0)/ both.
2434
2435RETURN VALUE
2436 true/false
2437
2438========================================================================== */
2439bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2440{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002441 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002442 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002443 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002444 struct v4l2_decoder_cmd dec;
2445 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002446 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002447 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002448 switch (flushType)
2449 {
2450 case OMX_CORE_INPUT_PORT_INDEX:
2451 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002452 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002453 break;
2454 case OMX_CORE_OUTPUT_PORT_INDEX:
2455 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002456 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002457 break;
2458 default:
2459 input_flush_progress = true;
2460 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002461 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2462 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002463 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002464
2465 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002466 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002467 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002468 bRet = false;
2469 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002470
Shalaj Jain273b3e02012-06-22 19:08:03 -07002471 return bRet;
2472}
2473/*=========================================================================
2474FUNCTION : execute_output_flush
2475
2476DESCRIPTION
2477 Executes the OMX flush at OUTPUT PORT.
2478
2479PARAMETERS
2480 None.
2481
2482RETURN VALUE
2483 true/false
2484==========================================================================*/
2485bool omx_vdec::execute_output_flush()
2486{
2487 unsigned p1 = 0; // Parameter - 1
2488 unsigned p2 = 0; // Parameter - 2
2489 unsigned ident = 0;
2490 bool bRet = true;
2491
2492 /*Generate FBD for all Buffers in the FTBq*/
2493 pthread_mutex_lock(&m_lock);
2494 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2495 while (m_ftb_q.m_size)
2496 {
2497 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2498 m_ftb_q.m_size,pending_output_buffers);
2499 m_ftb_q.pop_entry(&p1,&p2,&ident);
2500 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002501 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002502 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002503 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504 }
2505 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2506 {
2507 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2508 }
2509 }
2510 pthread_mutex_unlock(&m_lock);
2511 output_flush_progress = false;
2512
2513 if (arbitrary_bytes)
2514 {
2515 prev_ts = LLONG_MAX;
2516 rst_prev_ts = true;
2517 }
2518 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2519 return bRet;
2520}
2521/*=========================================================================
2522FUNCTION : execute_input_flush
2523
2524DESCRIPTION
2525 Executes the OMX flush at INPUT PORT.
2526
2527PARAMETERS
2528 None.
2529
2530RETURN VALUE
2531 true/false
2532==========================================================================*/
2533bool omx_vdec::execute_input_flush()
2534{
2535 unsigned i =0;
2536 unsigned p1 = 0; // Parameter - 1
2537 unsigned p2 = 0; // Parameter - 2
2538 unsigned ident = 0;
2539 bool bRet = true;
2540
2541 /*Generate EBD for all Buffers in the ETBq*/
2542 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2543
2544 pthread_mutex_lock(&m_lock);
2545 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2546 while (m_etb_q.m_size)
2547 {
2548 m_etb_q.pop_entry(&p1,&p2,&ident);
2549
2550 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2551 {
2552 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2553 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2554 }
2555 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2556 {
2557 pending_input_buffers++;
2558 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2559 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2560 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2561 }
2562 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2563 {
2564 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2565 (OMX_BUFFERHEADERTYPE *)p1);
2566 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2567 }
2568 }
2569 time_stamp_dts.flush_timestamp();
2570 /*Check if Heap Buffers are to be flushed*/
2571 if (arbitrary_bytes)
2572 {
2573 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2574 h264_scratch.nFilledLen = 0;
2575 nal_count = 0;
2576 look_ahead_nal = false;
2577 frame_count = 0;
2578 h264_last_au_ts = LLONG_MAX;
2579 h264_last_au_flags = 0;
2580 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2581 m_demux_entries = 0;
2582 DEBUG_PRINT_LOW("\n Initialize parser");
2583 if (m_frame_parser.mutils)
2584 {
2585 m_frame_parser.mutils->initialize_frame_checking_environment();
2586 }
2587
2588 while (m_input_pending_q.m_size)
2589 {
2590 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2591 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2592 }
2593
2594 if (psource_frame)
2595 {
2596 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2597 psource_frame = NULL;
2598 }
2599
2600 if (pdest_frame)
2601 {
2602 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002603 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2604 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002605 pdest_frame = NULL;
2606 }
2607 m_frame_parser.flush();
2608 }
2609 pthread_mutex_unlock(&m_lock);
2610 input_flush_progress = false;
2611 if (!arbitrary_bytes)
2612 {
2613 prev_ts = LLONG_MAX;
2614 rst_prev_ts = true;
2615 }
2616#ifdef _ANDROID_
2617 if (m_debug_timestamp)
2618 {
2619 m_timestamp_list.reset_ts_list();
2620 }
2621#endif
2622 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2623 return bRet;
2624}
2625
2626
2627/* ======================================================================
2628FUNCTION
2629 omx_vdec::SendCommandEvent
2630
2631DESCRIPTION
2632 Send the event to decoder pipe. This is needed to generate the callbacks
2633 in decoder thread context.
2634
2635PARAMETERS
2636 None.
2637
2638RETURN VALUE
2639 true/false
2640
2641========================================================================== */
2642bool omx_vdec::post_event(unsigned int p1,
2643 unsigned int p2,
2644 unsigned int id)
2645{
2646 bool bRet = false;
2647
2648
2649 pthread_mutex_lock(&m_lock);
2650
Vinay Kaliada4f4422013-01-09 10:45:03 -08002651 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002652 id == OMX_COMPONENT_GENERATE_FBD)
2653 {
2654 m_ftb_q.insert_entry(p1,p2,id);
2655 }
2656 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2657 id == OMX_COMPONENT_GENERATE_EBD ||
2658 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2659 {
2660 m_etb_q.insert_entry(p1,p2,id);
2661 }
2662 else
2663 {
2664 m_cmd_q.insert_entry(p1,p2,id);
2665 }
2666
2667 bRet = true;
2668 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2669 post_message(this, id);
2670
2671 pthread_mutex_unlock(&m_lock);
2672
2673 return bRet;
2674}
2675
2676OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2677{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002678 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002679 if(!profileLevelType)
2680 return OMX_ErrorBadParameter;
2681
2682 if(profileLevelType->nPortIndex == 0) {
2683 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2684 {
2685 if (profileLevelType->nProfileIndex == 0)
2686 {
2687 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2688 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2689
2690 }
2691 else if (profileLevelType->nProfileIndex == 1)
2692 {
2693 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2694 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2695 }
2696 else if(profileLevelType->nProfileIndex == 2)
2697 {
2698 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2699 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2700 }
2701 else
2702 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002703 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002704 profileLevelType->nProfileIndex);
2705 eRet = OMX_ErrorNoMore;
2706 }
2707 }
2708 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2709 {
2710 if (profileLevelType->nProfileIndex == 0)
2711 {
2712 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2713 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2714 }
2715 else
2716 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002717 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002718 eRet = OMX_ErrorNoMore;
2719 }
2720 }
2721 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2722 {
2723 if (profileLevelType->nProfileIndex == 0)
2724 {
2725 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2726 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2727 }
2728 else if(profileLevelType->nProfileIndex == 1)
2729 {
2730 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2731 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2732 }
2733 else
2734 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002735 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002736 eRet = OMX_ErrorNoMore;
2737 }
2738 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002739 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2740 {
2741 eRet = OMX_ErrorNoMore;
2742 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002743 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2744 {
2745 if (profileLevelType->nProfileIndex == 0)
2746 {
2747 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2748 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2749 }
2750 else if(profileLevelType->nProfileIndex == 1)
2751 {
2752 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2753 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2754 }
2755 else
2756 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002757 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002758 eRet = OMX_ErrorNoMore;
2759 }
2760 }
2761 }
2762 else
2763 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002764 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 -07002765 eRet = OMX_ErrorBadPortIndex;
2766 }
2767 return eRet;
2768}
2769
2770/* ======================================================================
2771FUNCTION
2772 omx_vdec::GetParameter
2773
2774DESCRIPTION
2775 OMX Get Parameter method implementation
2776
2777PARAMETERS
2778 <TBD>.
2779
2780RETURN VALUE
2781 Error None if successful.
2782
2783========================================================================== */
2784OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2785 OMX_IN OMX_INDEXTYPE paramIndex,
2786 OMX_INOUT OMX_PTR paramData)
2787{
2788 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2789
2790 DEBUG_PRINT_LOW("get_parameter: \n");
2791 if(m_state == OMX_StateInvalid)
2792 {
2793 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2794 return OMX_ErrorInvalidState;
2795 }
2796 if(paramData == NULL)
2797 {
2798 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2799 return OMX_ErrorBadParameter;
2800 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002801 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002802 {
2803 case OMX_IndexParamPortDefinition:
2804 {
2805 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2806 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2807 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2808 eRet = update_portdef(portDefn);
2809 if (eRet == OMX_ErrorNone)
2810 m_port_def = *portDefn;
2811 break;
2812 }
2813 case OMX_IndexParamVideoInit:
2814 {
2815 OMX_PORT_PARAM_TYPE *portParamType =
2816 (OMX_PORT_PARAM_TYPE *) paramData;
2817 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2818
2819 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2820 portParamType->nSize = sizeof(portParamType);
2821 portParamType->nPorts = 2;
2822 portParamType->nStartPortNumber = 0;
2823 break;
2824 }
2825 case OMX_IndexParamVideoPortFormat:
2826 {
2827 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2828 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2829 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2830
2831 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2832 portFmt->nSize = sizeof(portFmt);
2833
2834 if (0 == portFmt->nPortIndex)
2835 {
2836 if (0 == portFmt->nIndex)
2837 {
2838 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2839 portFmt->eCompressionFormat = eCompressionFormat;
2840 }
2841 else
2842 {
2843 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2844 " NoMore compression formats\n");
2845 eRet = OMX_ErrorNoMore;
2846 }
2847 }
2848 else if (1 == portFmt->nPortIndex)
2849 {
2850 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2851
2852 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002853 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2854 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2855 else if (1 == portFmt->nIndex)
2856 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002857 else
2858 {
2859 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2860 " NoMore Color formats\n");
2861 eRet = OMX_ErrorNoMore;
2862 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002863 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002864 }
2865 else
2866 {
2867 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2868 (int)portFmt->nPortIndex);
2869 eRet = OMX_ErrorBadPortIndex;
2870 }
2871 break;
2872 }
2873 /*Component should support this port definition*/
2874 case OMX_IndexParamAudioInit:
2875 {
2876 OMX_PORT_PARAM_TYPE *audioPortParamType =
2877 (OMX_PORT_PARAM_TYPE *) paramData;
2878 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2879 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2880 audioPortParamType->nSize = sizeof(audioPortParamType);
2881 audioPortParamType->nPorts = 0;
2882 audioPortParamType->nStartPortNumber = 0;
2883 break;
2884 }
2885 /*Component should support this port definition*/
2886 case OMX_IndexParamImageInit:
2887 {
2888 OMX_PORT_PARAM_TYPE *imagePortParamType =
2889 (OMX_PORT_PARAM_TYPE *) paramData;
2890 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2891 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2892 imagePortParamType->nSize = sizeof(imagePortParamType);
2893 imagePortParamType->nPorts = 0;
2894 imagePortParamType->nStartPortNumber = 0;
2895 break;
2896
2897 }
2898 /*Component should support this port definition*/
2899 case OMX_IndexParamOtherInit:
2900 {
2901 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2902 paramIndex);
2903 eRet =OMX_ErrorUnsupportedIndex;
2904 break;
2905 }
2906 case OMX_IndexParamStandardComponentRole:
2907 {
2908 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2909 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2910 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2911 comp_role->nSize = sizeof(*comp_role);
2912
2913 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2914 paramIndex);
2915 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2916 OMX_MAX_STRINGNAME_SIZE);
2917 break;
2918 }
2919 /* Added for parameter test */
2920 case OMX_IndexParamPriorityMgmt:
2921 {
2922
2923 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2924 (OMX_PRIORITYMGMTTYPE *) paramData;
2925 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2926 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2927 priorityMgmType->nSize = sizeof(priorityMgmType);
2928
2929 break;
2930 }
2931 /* Added for parameter test */
2932 case OMX_IndexParamCompBufferSupplier:
2933 {
2934 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2935 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2936 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2937
2938 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2939 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2940 if(0 == bufferSupplierType->nPortIndex)
2941 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2942 else if (1 == bufferSupplierType->nPortIndex)
2943 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2944 else
2945 eRet = OMX_ErrorBadPortIndex;
2946
2947
2948 break;
2949 }
2950 case OMX_IndexParamVideoAvc:
2951 {
2952 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2953 paramIndex);
2954 break;
2955 }
2956 case OMX_IndexParamVideoH263:
2957 {
2958 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2959 paramIndex);
2960 break;
2961 }
2962 case OMX_IndexParamVideoMpeg4:
2963 {
2964 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2965 paramIndex);
2966 break;
2967 }
2968 case OMX_IndexParamVideoMpeg2:
2969 {
2970 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2971 paramIndex);
2972 break;
2973 }
2974 case OMX_IndexParamVideoProfileLevelQuerySupported:
2975 {
2976 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2977 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2978 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2979 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2980 break;
2981 }
2982#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2983 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2984 {
2985 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2986 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2987 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2988
2989 if(secure_mode) {
2990 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302991 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002992 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08002993 nativeBuffersUsage->nUsage =
2994 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2995 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002996 }
2997 } else {
2998 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2999 eRet = OMX_ErrorBadParameter;
3000 }
3001 }
3002 break;
3003#endif
3004
3005 default:
3006 {
3007 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
3008 eRet =OMX_ErrorUnsupportedIndex;
3009 }
3010
3011 }
3012
3013 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3014 drv_ctx.video_resolution.frame_width,
3015 drv_ctx.video_resolution.frame_height,
3016 drv_ctx.video_resolution.stride,
3017 drv_ctx.video_resolution.scan_lines);
3018
3019 return eRet;
3020}
3021
3022#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3023OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3024{
3025 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3026 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3027 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3028
3029 if((params == NULL) ||
3030 (params->nativeBuffer == NULL) ||
3031 (params->nativeBuffer->handle == NULL) ||
3032 !m_enable_android_native_buffers)
3033 return OMX_ErrorBadParameter;
3034 m_use_android_native_buffers = OMX_TRUE;
3035 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3036 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3037 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3038 OMX_U8 *buffer = NULL;
3039 if(!secure_mode) {
3040 buffer = (OMX_U8*)mmap(0, handle->size,
3041 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3042 if(buffer == MAP_FAILED) {
3043 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3044 return OMX_ErrorInsufficientResources;
3045 }
3046 }
3047 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3048 } else {
3049 eRet = OMX_ErrorBadParameter;
3050 }
3051 return eRet;
3052}
3053#endif
3054/* ======================================================================
3055FUNCTION
3056 omx_vdec::Setparameter
3057
3058DESCRIPTION
3059 OMX Set Parameter method implementation.
3060
3061PARAMETERS
3062 <TBD>.
3063
3064RETURN VALUE
3065 OMX Error None if successful.
3066
3067========================================================================== */
3068OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3069 OMX_IN OMX_INDEXTYPE paramIndex,
3070 OMX_IN OMX_PTR paramData)
3071{
3072 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003073 int ret=0;
3074 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003075 if(m_state == OMX_StateInvalid)
3076 {
3077 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3078 return OMX_ErrorInvalidState;
3079 }
3080 if(paramData == NULL)
3081 {
3082 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3083 return OMX_ErrorBadParameter;
3084 }
3085 if((m_state != OMX_StateLoaded) &&
3086 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3087 (m_out_bEnabled == OMX_TRUE) &&
3088 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3089 (m_inp_bEnabled == OMX_TRUE)) {
3090 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3091 return OMX_ErrorIncorrectStateOperation;
3092 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003093 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003094 {
3095 case OMX_IndexParamPortDefinition:
3096 {
3097 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3098 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3099 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3100 //been called.
3101 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3102 (int)portDefn->format.video.nFrameHeight,
3103 (int)portDefn->format.video.nFrameWidth);
3104 if(OMX_DirOutput == portDefn->eDir)
3105 {
3106 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3107 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003108 unsigned int buffer_size;
3109 if (!client_buffers.get_buffer_req(buffer_size)) {
3110 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003111 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003112 } else {
3113 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3114 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3115 {
3116 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3117 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3118 eRet = set_buffer_req(&drv_ctx.op_buf);
3119 if (eRet == OMX_ErrorNone)
3120 m_port_def = *portDefn;
3121 }
3122 else
3123 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003124 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003125 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3126 portDefn->nBufferCountActual, portDefn->nBufferSize);
3127 eRet = OMX_ErrorBadParameter;
3128 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003129 }
3130 }
3131 else if(OMX_DirInput == portDefn->eDir)
3132 {
3133 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3134 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3135 {
3136 // Frame rate only should be set if this is a "known value" or to
3137 // activate ts prediction logic (arbitrary mode only) sending input
3138 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003139 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003140 portDefn->format.video.xFramerate >> 16);
3141 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3142 drv_ctx.frame_rate.fps_denominator);
3143 if(!drv_ctx.frame_rate.fps_numerator)
3144 {
3145 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3146 drv_ctx.frame_rate.fps_numerator = 30;
3147 }
3148 if(drv_ctx.frame_rate.fps_denominator)
3149 drv_ctx.frame_rate.fps_numerator = (int)
3150 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3151 drv_ctx.frame_rate.fps_denominator = 1;
3152 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3153 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003154 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003155 frm_int, drv_ctx.frame_rate.fps_numerator /
3156 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07003157 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003158 }
3159 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3160 if(drv_ctx.video_resolution.frame_height !=
3161 portDefn->format.video.nFrameHeight ||
3162 drv_ctx.video_resolution.frame_width !=
3163 portDefn->format.video.nFrameWidth)
3164 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003165 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003166 portDefn->format.video.nFrameWidth,
3167 portDefn->format.video.nFrameHeight);
3168 if (portDefn->format.video.nFrameHeight != 0x0 &&
3169 portDefn->format.video.nFrameWidth != 0x0)
3170 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003171 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003172 portDefn->format.video.nFrameHeight,
3173 portDefn->format.video.nFrameWidth,
3174 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003175 eRet = is_video_session_supported();
3176 if (eRet)
3177 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003178 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3179 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3180 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3181 fmt.fmt.pix_mp.pixelformat = output_capability;
3182 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);
3183 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003184 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003185 {
3186 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3187 eRet = OMX_ErrorUnsupportedSetting;
3188 }
3189 else
3190 eRet = get_buffer_req(&drv_ctx.op_buf);
3191 }
3192 }
3193 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003194 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003195 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003196 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003197 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003198 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3199 (~(buffer_prop->alignment - 1));
3200 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003201 }
3202 else
3203 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003204 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003205 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3206 portDefn->nBufferCountActual, portDefn->nBufferSize);
3207 eRet = OMX_ErrorBadParameter;
3208 }
3209 }
3210 else if (portDefn->eDir == OMX_DirMax)
3211 {
3212 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3213 (int)portDefn->nPortIndex);
3214 eRet = OMX_ErrorBadPortIndex;
3215 }
3216 }
3217 break;
3218 case OMX_IndexParamVideoPortFormat:
3219 {
3220 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3221 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3222 int ret=0;
3223 struct v4l2_format fmt;
3224 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3225 portFmt->eColorFormat);
3226
3227 if(1 == portFmt->nPortIndex)
3228 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003229 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3230 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3231 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3232 fmt.fmt.pix_mp.pixelformat = capture_capability;
3233 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003234 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3235 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003236 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003237 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003238 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003239 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003240 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3241 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3242 else
3243 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003244
Vinay Kaliada4f4422013-01-09 10:45:03 -08003245 if(eRet == OMX_ErrorNone)
3246 {
3247 drv_ctx.output_format = op_format;
3248 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3249 if(ret)
3250 {
3251 DEBUG_PRINT_ERROR("\n Set output format failed");
3252 eRet = OMX_ErrorUnsupportedSetting;
3253 /*TODO: How to handle this case */
3254 }
3255 else
3256 {
3257 eRet = get_buffer_req(&drv_ctx.op_buf);
3258 }
3259 }
3260 if (eRet == OMX_ErrorNone){
3261 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3262 DEBUG_PRINT_ERROR("\n Set color format failed");
3263 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003264 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003265 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003266 }
3267 }
3268 break;
3269
3270 case OMX_QcomIndexPortDefn:
3271 {
3272 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3273 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003274 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003275 portFmt->nFramePackingFormat);
3276
3277 /* Input port */
3278 if (portFmt->nPortIndex == 0)
3279 {
3280 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3281 {
3282 if(secure_mode) {
3283 arbitrary_bytes = false;
3284 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3285 eRet = OMX_ErrorUnsupportedSetting;
3286 } else {
3287 arbitrary_bytes = true;
3288 }
3289 }
3290 else if (portFmt->nFramePackingFormat ==
3291 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3292 {
3293 arbitrary_bytes = false;
3294 }
3295 else
3296 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003297 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003298 portFmt->nFramePackingFormat);
3299 eRet = OMX_ErrorUnsupportedSetting;
3300 }
3301 }
3302 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3303 {
3304 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3305 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3306 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3307 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3308 {
3309 m_out_mem_region_smi = OMX_TRUE;
3310 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3311 {
3312 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3313 m_use_output_pmem = OMX_TRUE;
3314 }
3315 }
3316 }
3317 }
3318 break;
3319
3320 case OMX_IndexParamStandardComponentRole:
3321 {
3322 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3323 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3324 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3325 comp_role->cRole);
3326
3327 if((m_state == OMX_StateLoaded)&&
3328 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3329 {
3330 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3331 }
3332 else
3333 {
3334 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3335 return OMX_ErrorIncorrectStateOperation;
3336 }
3337
3338 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3339 {
3340 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3341 {
3342 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3343 }
3344 else
3345 {
3346 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3347 eRet =OMX_ErrorUnsupportedSetting;
3348 }
3349 }
3350 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3351 {
3352 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3353 {
3354 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3355 }
3356 else
3357 {
3358 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3359 eRet = OMX_ErrorUnsupportedSetting;
3360 }
3361 }
3362 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3363 {
3364 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3365 {
3366 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3367 }
3368 else
3369 {
3370 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3371 eRet =OMX_ErrorUnsupportedSetting;
3372 }
3373 }
3374 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3375 {
3376 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3377 {
3378 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3379 }
3380 else
3381 {
3382 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3383 eRet = OMX_ErrorUnsupportedSetting;
3384 }
3385 }
3386 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3387 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3388 )
3389 {
3390 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3391 {
3392 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3393 }
3394 else
3395 {
3396 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3397 eRet =OMX_ErrorUnsupportedSetting;
3398 }
3399 }
3400 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3401 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3402 )
3403 {
3404 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3405 {
3406 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3407 }
3408 else
3409 {
3410 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3411 eRet =OMX_ErrorUnsupportedSetting;
3412 }
3413 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003414 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3415 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003416 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3417 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003418 {
3419 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3420 }
3421 else
3422 {
3423 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3424 eRet = OMX_ErrorUnsupportedSetting;
3425 }
3426 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003427 else
3428 {
3429 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3430 eRet = OMX_ErrorInvalidComponentName;
3431 }
3432 break;
3433 }
3434
3435 case OMX_IndexParamPriorityMgmt:
3436 {
3437 if(m_state != OMX_StateLoaded)
3438 {
3439 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3440 return OMX_ErrorIncorrectStateOperation;
3441 }
3442 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003443 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003444 priorityMgmtype->nGroupID);
3445
Shalaj Jainaf08f302013-03-18 13:15:35 -07003446 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003447 priorityMgmtype->nGroupPriority);
3448
3449 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3450 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3451
3452 break;
3453 }
3454
3455 case OMX_IndexParamCompBufferSupplier:
3456 {
3457 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3458 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3459 bufferSupplierType->eBufferSupplier);
3460 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3461 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3462
3463 else
3464
3465 eRet = OMX_ErrorBadPortIndex;
3466
3467 break;
3468
3469 }
3470 case OMX_IndexParamVideoAvc:
3471 {
3472 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3473 paramIndex);
3474 break;
3475 }
3476 case OMX_IndexParamVideoH263:
3477 {
3478 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3479 paramIndex);
3480 break;
3481 }
3482 case OMX_IndexParamVideoMpeg4:
3483 {
3484 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3485 paramIndex);
3486 break;
3487 }
3488 case OMX_IndexParamVideoMpeg2:
3489 {
3490 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3491 paramIndex);
3492 break;
3493 }
3494 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3495 {
3496 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3497 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003498 struct v4l2_control control;
3499 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003500 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3501 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003502 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3503 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3504 }
3505 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3506 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003507 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003508 }
3509 else
3510 eRet = OMX_ErrorBadParameter;
3511 if (eRet == OMX_ErrorNone)
3512 {
3513 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3514 control.value = pic_order;
3515 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3516 if(rc)
3517 {
3518 DEBUG_PRINT_ERROR("\n Set picture order failed");
3519 eRet = OMX_ErrorUnsupportedSetting;
3520 }
3521 }
3522 break;
3523 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003524 case OMX_QcomIndexParamConcealMBMapExtraData:
3525 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003526 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003527 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3528 else {
3529 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3530 eRet = OMX_ErrorUnsupportedSetting;
3531 }
3532 break;
3533 case OMX_QcomIndexParamFrameInfoExtraData:
3534 {
3535 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003536 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003537 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3538 else {
3539 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3540 eRet = OMX_ErrorUnsupportedSetting;
3541 }
3542 break;
3543 }
3544 case OMX_QcomIndexParamInterlaceExtraData:
3545 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003546 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003547 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3548 else {
3549 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3550 eRet = OMX_ErrorUnsupportedSetting;
3551 }
3552 break;
3553 case OMX_QcomIndexParamH264TimeInfo:
3554 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003555 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003556 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3557 else {
3558 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3559 eRet = OMX_ErrorUnsupportedSetting;
3560 }
3561 break;
3562 case OMX_QcomIndexParamVideoDivx:
3563 {
3564 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003565 }
3566 break;
3567 case OMX_QcomIndexPlatformPvt:
3568 {
3569 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3570 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3571 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3572 {
3573 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3574 eRet = OMX_ErrorUnsupportedSetting;
3575 }
3576 else
3577 {
3578 m_out_pvt_entry_pmem = OMX_TRUE;
3579 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3580 {
3581 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3582 m_use_output_pmem = OMX_TRUE;
3583 }
3584 }
3585
3586 }
3587 break;
3588 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3589 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003590 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3591 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3592 struct v4l2_control control;
3593 int rc;
3594 drv_ctx.idr_only_decoding = 1;
3595 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3596 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3597 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3598 if(rc)
3599 {
3600 DEBUG_PRINT_ERROR("\n Set picture order failed");
3601 eRet = OMX_ErrorUnsupportedSetting;
3602 } else {
3603 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3604 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3605 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3606 if(rc)
3607 {
3608 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3609 eRet = OMX_ErrorUnsupportedSetting;
3610 }
3611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003612 }
3613 break;
3614
3615 case OMX_QcomIndexParamIndexExtraDataType:
3616 {
3617 if(!secure_mode) {
3618 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3619 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3620 (extradataIndexType->bEnabled == OMX_TRUE) &&
3621 (extradataIndexType->nPortIndex == 1))
3622 {
3623 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003624 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003625
Shalaj Jain273b3e02012-06-22 19:08:03 -07003626 }
3627 }
3628 }
3629 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003630 case OMX_QcomIndexParamEnableSmoothStreaming:
3631 {
3632 struct v4l2_control control;
3633 struct v4l2_format fmt;
3634 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3635 control.value = 1;
3636 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3637 if(rc < 0) {
3638 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3639 eRet = OMX_ErrorHardware;
3640 }
3641 }
3642 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003643#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3644 /* Need to allow following two set_parameters even in Idle
3645 * state. This is ANDROID architecture which is not in sync
3646 * with openmax standard. */
3647 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3648 {
3649 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3650 if(enableNativeBuffers) {
3651 m_enable_android_native_buffers = enableNativeBuffers->enable;
3652 }
3653 }
3654 break;
3655 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3656 {
3657 eRet = use_android_native_buffer(hComp, paramData);
3658 }
3659 break;
3660#endif
3661 case OMX_QcomIndexParamEnableTimeStampReorder:
3662 {
3663 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003664 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003665 if (reorder->bEnable == OMX_TRUE) {
3666 frm_int =0;
3667 time_stamp_dts.set_timestamp_reorder_mode(true);
3668 }
3669 else
3670 time_stamp_dts.set_timestamp_reorder_mode(false);
3671 } else {
3672 time_stamp_dts.set_timestamp_reorder_mode(false);
3673 if (reorder->bEnable == OMX_TRUE)
3674 {
3675 eRet = OMX_ErrorUnsupportedSetting;
3676 }
3677 }
3678 }
3679 break;
3680 default:
3681 {
3682 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3683 eRet = OMX_ErrorUnsupportedIndex;
3684 }
3685 }
3686 return eRet;
3687}
3688
3689/* ======================================================================
3690FUNCTION
3691 omx_vdec::GetConfig
3692
3693DESCRIPTION
3694 OMX Get Config Method implementation.
3695
3696PARAMETERS
3697 <TBD>.
3698
3699RETURN VALUE
3700 OMX Error None if successful.
3701
3702========================================================================== */
3703OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3704 OMX_IN OMX_INDEXTYPE configIndex,
3705 OMX_INOUT OMX_PTR configData)
3706{
3707 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3708
3709 if (m_state == OMX_StateInvalid)
3710 {
3711 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3712 return OMX_ErrorInvalidState;
3713 }
3714
Shalaj Jain286b0062013-02-21 20:35:48 -08003715 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003716 {
3717 case OMX_QcomIndexConfigInterlaced:
3718 {
3719 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3720 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3721 if (configFmt->nPortIndex == 1)
3722 {
3723 if (configFmt->nIndex == 0)
3724 {
3725 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3726 }
3727 else if (configFmt->nIndex == 1)
3728 {
3729 configFmt->eInterlaceType =
3730 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3731 }
3732 else if (configFmt->nIndex == 2)
3733 {
3734 configFmt->eInterlaceType =
3735 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3736 }
3737 else
3738 {
3739 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3740 " NoMore Interlaced formats\n");
3741 eRet = OMX_ErrorNoMore;
3742 }
3743
3744 }
3745 else
3746 {
3747 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3748 (int)configFmt->nPortIndex);
3749 eRet = OMX_ErrorBadPortIndex;
3750 }
3751 break;
3752 }
3753 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3754 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003755 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3756 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003757 decoderinstances->nNumOfInstances = 16;
3758 /*TODO: How to handle this case */
3759 break;
3760 }
3761 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3762 {
3763 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3764 {
3765 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3766 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3767 h264_parser->get_frame_pack_data(configFmt);
3768 }
3769 else
3770 {
3771 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3772 }
3773 break;
3774 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003775 case OMX_IndexConfigCommonOutputCrop:
3776 {
3777 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3778 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3779 break;
3780 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003781 default:
3782 {
3783 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3784 eRet = OMX_ErrorBadParameter;
3785 }
3786
3787 }
3788
3789 return eRet;
3790}
3791
3792/* ======================================================================
3793FUNCTION
3794 omx_vdec::SetConfig
3795
3796DESCRIPTION
3797 OMX Set Config method implementation
3798
3799PARAMETERS
3800 <TBD>.
3801
3802RETURN VALUE
3803 OMX Error None if successful.
3804========================================================================== */
3805OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3806 OMX_IN OMX_INDEXTYPE configIndex,
3807 OMX_IN OMX_PTR configData)
3808{
3809 if(m_state == OMX_StateInvalid)
3810 {
3811 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3812 return OMX_ErrorInvalidState;
3813 }
3814
3815 OMX_ERRORTYPE ret = OMX_ErrorNone;
3816 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3817
3818 DEBUG_PRINT_LOW("\n Set Config Called");
3819
3820 if (m_state == OMX_StateExecuting)
3821 {
3822 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3823 return ret;
3824 }
3825
Shalaj Jain286b0062013-02-21 20:35:48 -08003826 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003827 {
3828 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3829 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3830 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3831 {
3832 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3833 OMX_U32 extra_size;
3834 // Parsing done here for the AVC atom is definitely not generic
3835 // Currently this piece of code is working, but certainly
3836 // not tested with all .mp4 files.
3837 // Incase of failure, we might need to revisit this
3838 // for a generic piece of code.
3839
3840 // Retrieve size of NAL length field
3841 // byte #4 contains the size of NAL lenght field
3842 nal_length = (config->pData[4] & 0x03) + 1;
3843
3844 extra_size = 0;
3845 if (nal_length > 2)
3846 {
3847 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3848 extra_size = (nal_length - 2) * 2;
3849 }
3850
3851 // SPS starts from byte #6
3852 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3853 OMX_U8 *pDestBuf;
3854 m_vendor_config.nPortIndex = config->nPortIndex;
3855
3856 // minus 6 --> SPS starts from byte #6
3857 // minus 1 --> picture param set byte to be ignored from avcatom
3858 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3859 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3860 OMX_U32 len;
3861 OMX_U8 index = 0;
3862 // case where SPS+PPS is sent as part of set_config
3863 pDestBuf = m_vendor_config.pData;
3864
Shalaj Jainaf08f302013-03-18 13:15:35 -07003865 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003866 m_vendor_config.nPortIndex,
3867 m_vendor_config.nDataSize,
3868 m_vendor_config.pData);
3869 while (index < 2)
3870 {
3871 uint8 *psize;
3872 len = *pSrcBuf;
3873 len = len << 8;
3874 len |= *(pSrcBuf + 1);
3875 psize = (uint8 *) & len;
3876 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003877 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003878 {
3879 pDestBuf[i] = psize[nal_length - 1 - i];
3880 }
3881 //memcpy(pDestBuf,pSrcBuf,(len+2));
3882 pDestBuf += len + nal_length;
3883 pSrcBuf += len + 2;
3884 index++;
3885 pSrcBuf++; // skip picture param set
3886 len = 0;
3887 }
3888 }
3889 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3890 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3891 {
3892 m_vendor_config.nPortIndex = config->nPortIndex;
3893 m_vendor_config.nDataSize = config->nDataSize;
3894 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3895 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3896 }
3897 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3898 {
3899 if(m_vendor_config.pData)
3900 {
3901 free(m_vendor_config.pData);
3902 m_vendor_config.pData = NULL;
3903 m_vendor_config.nDataSize = 0;
3904 }
3905
3906 if (((*((OMX_U32 *) config->pData)) &
3907 VC1_SP_MP_START_CODE_MASK) ==
3908 VC1_SP_MP_START_CODE)
3909 {
3910 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3911 m_vendor_config.nPortIndex = config->nPortIndex;
3912 m_vendor_config.nDataSize = config->nDataSize;
3913 m_vendor_config.pData =
3914 (OMX_U8 *) malloc(config->nDataSize);
3915 memcpy(m_vendor_config.pData, config->pData,
3916 config->nDataSize);
3917 m_vc1_profile = VC1_SP_MP_RCV;
3918 }
3919 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3920 {
3921 DEBUG_PRINT_LOW("set_config - VC1 Advance 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_AP;
3929 }
3930 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3931 {
3932 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3933 m_vendor_config.nPortIndex = config->nPortIndex;
3934 m_vendor_config.nDataSize = config->nDataSize;
3935 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3936 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3937 m_vc1_profile = VC1_SP_MP_RCV;
3938 }
3939 else
3940 {
3941 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3942 }
3943 }
3944 return ret;
3945 }
3946 else if (configIndex == OMX_IndexConfigVideoNalSize)
3947 {
3948
3949 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3950 nal_length = pNal->nNaluBytes;
3951 m_frame_parser.init_nal_length(nal_length);
3952 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3953 return ret;
3954 }
3955
3956 return OMX_ErrorNotImplemented;
3957}
3958
3959/* ======================================================================
3960FUNCTION
3961 omx_vdec::GetExtensionIndex
3962
3963DESCRIPTION
3964 OMX GetExtensionIndex method implementaion. <TBD>
3965
3966PARAMETERS
3967 <TBD>.
3968
3969RETURN VALUE
3970 OMX Error None if everything successful.
3971
3972========================================================================== */
3973OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3974 OMX_IN OMX_STRING paramName,
3975 OMX_OUT OMX_INDEXTYPE* indexType)
3976{
3977 if(m_state == OMX_StateInvalid)
3978 {
3979 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3980 return OMX_ErrorInvalidState;
3981 }
3982 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3983 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3984 }
3985 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3986 {
3987 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3988 }
3989#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3990 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3991 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3992 }
3993 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3994 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3995 }
3996 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3997 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3998 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3999 }
4000 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
4001 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4002 }
4003#endif
4004 else {
4005 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
4006 return OMX_ErrorNotImplemented;
4007 }
4008 return OMX_ErrorNone;
4009}
4010
4011/* ======================================================================
4012FUNCTION
4013 omx_vdec::GetState
4014
4015DESCRIPTION
4016 Returns the state information back to the caller.<TBD>
4017
4018PARAMETERS
4019 <TBD>.
4020
4021RETURN VALUE
4022 Error None if everything is successful.
4023========================================================================== */
4024OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4025 OMX_OUT OMX_STATETYPE* state)
4026{
4027 *state = m_state;
4028 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4029 return OMX_ErrorNone;
4030}
4031
4032/* ======================================================================
4033FUNCTION
4034 omx_vdec::ComponentTunnelRequest
4035
4036DESCRIPTION
4037 OMX Component Tunnel Request method implementation. <TBD>
4038
4039PARAMETERS
4040 None.
4041
4042RETURN VALUE
4043 OMX Error None if everything successful.
4044
4045========================================================================== */
4046OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4047 OMX_IN OMX_U32 port,
4048 OMX_IN OMX_HANDLETYPE peerComponent,
4049 OMX_IN OMX_U32 peerPort,
4050 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4051{
4052 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4053 return OMX_ErrorNotImplemented;
4054}
4055
4056/* ======================================================================
4057FUNCTION
4058 omx_vdec::UseOutputBuffer
4059
4060DESCRIPTION
4061 Helper function for Use buffer in the input pin
4062
4063PARAMETERS
4064 None.
4065
4066RETURN VALUE
4067 true/false
4068
4069========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004070OMX_ERRORTYPE omx_vdec::allocate_extradata()
4071{
4072#ifdef USE_ION
4073 if (drv_ctx.extradata_info.buffer_size) {
4074 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4075 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4076 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4077 free_ion_memory(&drv_ctx.extradata_info.ion);
4078 }
4079 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4080 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4081 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4082 &drv_ctx.extradata_info.ion.ion_alloc_data,
4083 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4084 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4085 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4086 return OMX_ErrorInsufficientResources;
4087 }
4088 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4089 drv_ctx.extradata_info.size,
4090 PROT_READ|PROT_WRITE, MAP_SHARED,
4091 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4092 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4093 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4094 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4095 free_ion_memory(&drv_ctx.extradata_info.ion);
4096 return OMX_ErrorInsufficientResources;
4097 }
4098 }
4099#endif
4100 return OMX_ErrorNone;
4101}
4102
4103void omx_vdec::free_extradata() {
4104#ifdef USE_ION
4105 if (drv_ctx.extradata_info.uaddr) {
4106 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4107 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4108 free_ion_memory(&drv_ctx.extradata_info.ion);
4109 }
4110 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4111#endif
4112}
4113
Shalaj Jain273b3e02012-06-22 19:08:03 -07004114OMX_ERRORTYPE omx_vdec::use_output_buffer(
4115 OMX_IN OMX_HANDLETYPE hComp,
4116 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4117 OMX_IN OMX_U32 port,
4118 OMX_IN OMX_PTR appData,
4119 OMX_IN OMX_U32 bytes,
4120 OMX_IN OMX_U8* buffer)
4121{
4122 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4123 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4124 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004125 struct vdec_setbuffer_cmd setbuffers;
4126 OMX_PTR privateAppData = NULL;
4127 private_handle_t *handle = NULL;
4128 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004129 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004130 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4131 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004132
Shalaj Jain273b3e02012-06-22 19:08:03 -07004133 if (!m_out_mem_ptr) {
4134 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4135 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004136 if (eRet == OMX_ErrorNone)
4137 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004138 }
4139
4140 if (eRet == OMX_ErrorNone) {
4141 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4142 if(BITMASK_ABSENT(&m_out_bm_count,i))
4143 {
4144 break;
4145 }
4146 }
4147 }
4148
4149 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004150 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004151 eRet = OMX_ErrorInsufficientResources;
4152 }
4153
4154 if (eRet == OMX_ErrorNone) {
4155#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4156 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004157 if (m_use_android_native_buffers) {
4158 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4159 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4160 handle = (private_handle_t *)nBuf->handle;
4161 privateAppData = params->pAppPrivate;
4162 } else {
4163 handle = (private_handle_t *)buff;
4164 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004165 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004166
4167 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4168 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4169 " expected %u, got %lu",
4170 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4171 return OMX_ErrorBadParameter;
4172 }
4173
4174 if (!m_use_android_native_buffers) {
4175 if (!secure_mode) {
4176 buff = (OMX_U8*)mmap(0, handle->size,
4177 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4178 if (buff == MAP_FAILED) {
4179 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4180 return OMX_ErrorInsufficientResources;
4181 }
4182 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004183 }
4184#if defined(_ANDROID_ICS_)
4185 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004186 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004187#endif
4188 if(!handle) {
4189 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4190 return OMX_ErrorBadParameter;
4191 }
4192 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4193 drv_ctx.ptr_outputbuffer[i].offset = 0;
4194 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4195 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4196 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4197 } else
4198#endif
4199
4200 if (!ouput_egl_buffers && !m_use_output_pmem) {
4201#ifdef USE_ION
4202 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4203 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4204 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004205 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004206 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004207 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 -07004208 return OMX_ErrorInsufficientResources;
4209 }
4210 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4211 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4212#else
4213 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4214 open (MEM_DEVICE,O_RDWR);
4215
4216 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004217 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 -07004218 return OMX_ErrorInsufficientResources;
4219 }
4220
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004221 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004222 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4223 {
4224 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4225 open (MEM_DEVICE,O_RDWR);
4226 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004227 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 -07004228 return OMX_ErrorInsufficientResources;
4229 }
4230 }
4231
4232 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4233 drv_ctx.op_buf.buffer_size,
4234 drv_ctx.op_buf.alignment))
4235 {
4236 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4237 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4238 return OMX_ErrorInsufficientResources;
4239 }
4240#endif
4241 if(!secure_mode) {
4242 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4243 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4244 PROT_READ|PROT_WRITE, MAP_SHARED,
4245 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4246 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4247 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4248#ifdef USE_ION
4249 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4250#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004251 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004252 return OMX_ErrorInsufficientResources;
4253 }
4254 }
4255 drv_ctx.ptr_outputbuffer[i].offset = 0;
4256 privateAppData = appData;
4257 }
4258 else {
4259
4260 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4261 if (!appData || !bytes ) {
4262 if(!secure_mode && !buffer) {
4263 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4264 return OMX_ErrorBadParameter;
4265 }
4266 }
4267
4268 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4269 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4270 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4271 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4272 !pmem_list->nEntries ||
4273 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4274 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4275 return OMX_ErrorBadParameter;
4276 }
4277 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4278 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004279 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004280 pmem_info->pmem_fd);
4281 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4282 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4283 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4284 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4285 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4286 privateAppData = appData;
4287 }
4288 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4289 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4290
4291 *bufferHdr = (m_out_mem_ptr + i );
4292 if(secure_mode)
4293 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4294 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4295 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4296 sizeof (vdec_bufferpayload));
4297
Shalaj Jain286b0062013-02-21 20:35:48 -08004298 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4299 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4300 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004301
4302 buf.index = i;
4303 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4304 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004305 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004306 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4307 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004308 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4309 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4310 plane[0].data_offset = 0;
4311 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4312 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4313 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4314 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4315#ifdef USE_ION
4316 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4317#endif
4318 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4319 plane[extra_idx].data_offset = 0;
4320 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4321 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4322 return OMX_ErrorBadParameter;
4323 }
4324 buf.m.planes = plane;
4325 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004326
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004327 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4328 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4329 /*TODO: How to handle this case */
4330 return OMX_ErrorInsufficientResources;
4331 }
4332
4333 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4334 enum v4l2_buf_type buf_type;
4335 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4336 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4337 return OMX_ErrorInsufficientResources;
4338 } else {
4339 streaming[CAPTURE_PORT] = true;
4340 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4341 }
4342 }
4343
Shalaj Jain273b3e02012-06-22 19:08:03 -07004344 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004345 if (m_enable_android_native_buffers) {
4346 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4347 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4348 } else {
4349 (*bufferHdr)->pBuffer = buff;
4350 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004351 (*bufferHdr)->pAppPrivate = privateAppData;
4352 BITMASK_SET(&m_out_bm_count,i);
4353 }
4354 return eRet;
4355}
4356
4357/* ======================================================================
4358FUNCTION
4359 omx_vdec::use_input_heap_buffers
4360
4361DESCRIPTION
4362 OMX Use Buffer Heap allocation method implementation.
4363
4364PARAMETERS
4365 <TBD>.
4366
4367RETURN VALUE
4368 OMX Error None , if everything successful.
4369
4370========================================================================== */
4371OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4372 OMX_IN OMX_HANDLETYPE hComp,
4373 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4374 OMX_IN OMX_U32 port,
4375 OMX_IN OMX_PTR appData,
4376 OMX_IN OMX_U32 bytes,
4377 OMX_IN OMX_U8* buffer)
4378{
4379 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4380 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4381 if(!m_inp_heap_ptr)
4382 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4383 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4384 drv_ctx.ip_buf.actualcount);
4385 if(!m_phdr_pmem_ptr)
4386 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4387 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4388 drv_ctx.ip_buf.actualcount);
4389 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4390 {
4391 DEBUG_PRINT_ERROR("Insufficent memory");
4392 eRet = OMX_ErrorInsufficientResources;
4393 }
4394 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4395 {
4396 input_use_buffer = true;
4397 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4398 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4399 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4400 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4401 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4402 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4403 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4404 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4405 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 -08004406 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4407 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408 {
4409 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4410 return OMX_ErrorInsufficientResources;
4411 }
4412 m_in_alloc_cnt++;
4413 }
4414 else
4415 {
4416 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4417 eRet = OMX_ErrorInsufficientResources;
4418 }
4419 return eRet;
4420}
4421
4422/* ======================================================================
4423FUNCTION
4424 omx_vdec::UseBuffer
4425
4426DESCRIPTION
4427 OMX Use Buffer method implementation.
4428
4429PARAMETERS
4430 <TBD>.
4431
4432RETURN VALUE
4433 OMX Error None , if everything successful.
4434
4435========================================================================== */
4436OMX_ERRORTYPE omx_vdec::use_buffer(
4437 OMX_IN OMX_HANDLETYPE hComp,
4438 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4439 OMX_IN OMX_U32 port,
4440 OMX_IN OMX_PTR appData,
4441 OMX_IN OMX_U32 bytes,
4442 OMX_IN OMX_U8* buffer)
4443{
4444 OMX_ERRORTYPE error = OMX_ErrorNone;
4445 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004446
4447 if (bufferHdr == NULL || bytes == 0)
4448 {
4449 if(!secure_mode && buffer == NULL) {
4450 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4451 return OMX_ErrorBadParameter;
4452 }
4453 }
4454 if(m_state == OMX_StateInvalid)
4455 {
4456 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4457 return OMX_ErrorInvalidState;
4458 }
4459 if(port == OMX_CORE_INPUT_PORT_INDEX)
4460 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4461 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4462 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4463 else
4464 {
4465 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4466 error = OMX_ErrorBadPortIndex;
4467 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004468 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004469 if(error == OMX_ErrorNone)
4470 {
4471 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4472 {
4473 // Send the callback now
4474 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4475 post_event(OMX_CommandStateSet,OMX_StateIdle,
4476 OMX_COMPONENT_GENERATE_EVENT);
4477 }
4478 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4479 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4480 {
4481 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4482 post_event(OMX_CommandPortEnable,
4483 OMX_CORE_INPUT_PORT_INDEX,
4484 OMX_COMPONENT_GENERATE_EVENT);
4485 }
4486 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4487 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4488 {
4489 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4490 post_event(OMX_CommandPortEnable,
4491 OMX_CORE_OUTPUT_PORT_INDEX,
4492 OMX_COMPONENT_GENERATE_EVENT);
4493 }
4494 }
4495 return error;
4496}
4497
4498OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4499 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4500{
4501 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4502 {
4503 if(m_inp_heap_ptr[bufferindex].pBuffer)
4504 free(m_inp_heap_ptr[bufferindex].pBuffer);
4505 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4506 }
4507 if (pmem_bufferHdr)
4508 free_input_buffer(pmem_bufferHdr);
4509 return OMX_ErrorNone;
4510}
4511
4512OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4513{
4514 unsigned int index = 0;
4515 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4516 {
4517 return OMX_ErrorBadParameter;
4518 }
4519
4520 index = bufferHdr - m_inp_mem_ptr;
4521 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4522
4523 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4524 {
4525 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4526 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4527 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004528 struct vdec_setbuffer_cmd setbuffers;
4529 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4530 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4531 sizeof (vdec_bufferpayload));
Praveen Chavan212671f2013-04-05 20:00:42 -07004532 if(!secure_mode) {
4533 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4534 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4535 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4536 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4537 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4538 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4539 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4540 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4542 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4543 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4544 {
4545 free(m_desc_buffer_ptr[index].buf_addr);
4546 m_desc_buffer_ptr[index].buf_addr = NULL;
4547 m_desc_buffer_ptr[index].desc_data_size = 0;
4548 }
4549#ifdef USE_ION
4550 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4551#endif
4552 }
4553 }
4554
4555 return OMX_ErrorNone;
4556}
4557
4558OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4559{
4560 unsigned int index = 0;
4561
4562 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4563 {
4564 return OMX_ErrorBadParameter;
4565 }
4566
4567 index = bufferHdr - m_out_mem_ptr;
4568 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4569
4570 if (index < drv_ctx.op_buf.actualcount
4571 && drv_ctx.ptr_outputbuffer)
4572 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004573 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004574 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4575
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576 struct vdec_setbuffer_cmd setbuffers;
4577 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4578 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4579 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580#ifdef _ANDROID_
4581 if(m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004582 if (!secure_mode) {
4583 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4584 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4585 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4586 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587 }
4588 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4589 } else {
4590#endif
4591 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4592 {
Praveen Chavan212671f2013-04-05 20:00:42 -07004593 if (!secure_mode) {
4594 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4595 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4596 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4597 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4598 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4599 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4600 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4601 }
4602 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4603 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604#ifdef USE_ION
Praveen Chavan212671f2013-04-05 20:00:42 -07004605 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004606#endif
4607 }
4608#ifdef _ANDROID_
4609 }
4610#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004611 if (release_output_done()) {
4612 free_extradata();
4613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004614 }
4615
4616 return OMX_ErrorNone;
4617
4618}
4619
4620OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4621 OMX_BUFFERHEADERTYPE **bufferHdr,
4622 OMX_U32 port,
4623 OMX_PTR appData,
4624 OMX_U32 bytes)
4625{
4626 OMX_BUFFERHEADERTYPE *input = NULL;
4627 unsigned char *buf_addr = NULL;
4628 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4629 unsigned i = 0;
4630
4631 /* Sanity Check*/
4632 if (bufferHdr == NULL)
4633 {
4634 return OMX_ErrorBadParameter;
4635 }
4636
4637 if (m_inp_heap_ptr == NULL)
4638 {
4639 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4640 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4641 drv_ctx.ip_buf.actualcount);
4642 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4643 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4644 drv_ctx.ip_buf.actualcount);
4645
4646 if (m_inp_heap_ptr == NULL)
4647 {
4648 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4649 return OMX_ErrorInsufficientResources;
4650 }
4651 }
4652
4653 /*Find a Free index*/
4654 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4655 {
4656 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4657 {
4658 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4659 break;
4660 }
4661 }
4662
4663 if (i < drv_ctx.ip_buf.actualcount)
4664 {
4665 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4666
4667 if (buf_addr == NULL)
4668 {
4669 return OMX_ErrorInsufficientResources;
4670 }
4671
4672 *bufferHdr = (m_inp_heap_ptr + i);
4673 input = *bufferHdr;
4674 BITMASK_SET(&m_heap_inp_bm_count,i);
4675
4676 input->pBuffer = (OMX_U8 *)buf_addr;
4677 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4678 input->nVersion.nVersion = OMX_SPEC_VERSION;
4679 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4680 input->pAppPrivate = appData;
4681 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4682 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4683 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004684 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004685 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004686 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4687 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688 {
4689 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4690 return OMX_ErrorInsufficientResources;
4691 }
4692 }
4693 else
4694 {
4695 return OMX_ErrorBadParameter;
4696 }
4697
4698 return eRet;
4699
4700}
4701
4702
4703/* ======================================================================
4704FUNCTION
4705 omx_vdec::AllocateInputBuffer
4706
4707DESCRIPTION
4708 Helper function for allocate buffer in the input pin
4709
4710PARAMETERS
4711 None.
4712
4713RETURN VALUE
4714 true/false
4715
4716========================================================================== */
4717OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4718 OMX_IN OMX_HANDLETYPE hComp,
4719 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4720 OMX_IN OMX_U32 port,
4721 OMX_IN OMX_PTR appData,
4722 OMX_IN OMX_U32 bytes)
4723{
4724
4725 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4726 struct vdec_setbuffer_cmd setbuffers;
4727 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004728 unsigned i = 0;
4729 unsigned char *buf_addr = NULL;
4730 int pmem_fd = -1;
4731
4732 if(bytes != drv_ctx.ip_buf.buffer_size)
4733 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004734 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004735 bytes, drv_ctx.ip_buf.buffer_size);
4736 return OMX_ErrorBadParameter;
4737 }
4738
4739 if(!m_inp_mem_ptr)
4740 {
4741 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4742 drv_ctx.ip_buf.actualcount,
4743 drv_ctx.ip_buf.buffer_size);
4744
4745 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4746 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4747
4748 if (m_inp_mem_ptr == NULL)
4749 {
4750 return OMX_ErrorInsufficientResources;
4751 }
4752
4753 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4754 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4755
4756 if (drv_ctx.ptr_inputbuffer == NULL)
4757 {
4758 return OMX_ErrorInsufficientResources;
4759 }
4760#ifdef USE_ION
4761 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4762 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4763
4764 if (drv_ctx.ip_buf_ion_info == NULL)
4765 {
4766 return OMX_ErrorInsufficientResources;
4767 }
4768#endif
4769
4770 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4771 {
4772 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4773#ifdef USE_ION
4774 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4775#endif
4776 }
4777 }
4778
4779 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4780 {
4781 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4782 {
4783 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4784 break;
4785 }
4786 }
4787
4788 if(i < drv_ctx.ip_buf.actualcount)
4789 {
4790 struct v4l2_buffer buf;
4791 struct v4l2_plane plane;
4792 int rc;
4793 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4794#ifdef USE_ION
4795 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4796 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4797 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004798 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004799 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4800 return OMX_ErrorInsufficientResources;
4801 }
4802 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4803#else
4804 pmem_fd = open (MEM_DEVICE,O_RDWR);
4805
4806 if (pmem_fd < 0)
4807 {
4808 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4809 return OMX_ErrorInsufficientResources;
4810 }
4811
4812 if (pmem_fd == 0)
4813 {
4814 pmem_fd = open (MEM_DEVICE,O_RDWR);
4815
4816 if (pmem_fd < 0)
4817 {
4818 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4819 return OMX_ErrorInsufficientResources;
4820 }
4821 }
4822
4823 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4824 drv_ctx.ip_buf.alignment))
4825 {
4826 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4827 close(pmem_fd);
4828 return OMX_ErrorInsufficientResources;
4829 }
4830#endif
4831 if (!secure_mode) {
4832 buf_addr = (unsigned char *)mmap(NULL,
4833 drv_ctx.ip_buf.buffer_size,
4834 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4835
4836 if (buf_addr == MAP_FAILED)
4837 {
4838 close(pmem_fd);
4839#ifdef USE_ION
4840 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4841#endif
4842 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4843 return OMX_ErrorInsufficientResources;
4844 }
4845 }
4846 *bufferHdr = (m_inp_mem_ptr + i);
4847 if (secure_mode)
4848 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4849 else
4850 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4851 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4852 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4853 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4854 drv_ctx.ptr_inputbuffer [i].offset = 0;
4855
4856
4857 buf.index = i;
4858 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4859 buf.memory = V4L2_MEMORY_USERPTR;
4860 plane.bytesused = 0;
4861 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4862 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4863 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4864 plane.reserved[1] = 0;
4865 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4866 buf.m.planes = &plane;
4867 buf.length = 1;
4868
Shalaj Jainaf08f302013-03-18 13:15:35 -07004869 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4870 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871
4872 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4873
4874 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004875 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004876 /*TODO: How to handle this case */
4877 return OMX_ErrorInsufficientResources;
4878 }
4879
4880 input = *bufferHdr;
4881 BITMASK_SET(&m_inp_bm_count,i);
4882 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4883 if (secure_mode)
4884 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4885 else
4886 input->pBuffer = (OMX_U8 *)buf_addr;
4887 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4888 input->nVersion.nVersion = OMX_SPEC_VERSION;
4889 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4890 input->pAppPrivate = appData;
4891 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4892 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4893
4894 if (drv_ctx.disable_dmx)
4895 {
4896 eRet = allocate_desc_buffer(i);
4897 }
4898 }
4899 else
4900 {
4901 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4902 eRet = OMX_ErrorInsufficientResources;
4903 }
4904 return eRet;
4905}
4906
4907
4908/* ======================================================================
4909FUNCTION
4910 omx_vdec::AllocateOutputBuffer
4911
4912DESCRIPTION
4913 Helper fn for AllocateBuffer in the output pin
4914
4915PARAMETERS
4916 <TBD>.
4917
4918RETURN VALUE
4919 OMX Error None if everything went well.
4920
4921========================================================================== */
4922OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4923 OMX_IN OMX_HANDLETYPE hComp,
4924 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4925 OMX_IN OMX_U32 port,
4926 OMX_IN OMX_PTR appData,
4927 OMX_IN OMX_U32 bytes)
4928{
4929 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4930 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4931 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004932 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004933 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004934#ifdef USE_ION
4935 int ion_device_fd =-1;
4936 struct ion_allocation_data ion_alloc_data;
4937 struct ion_fd_data fd_ion_data;
4938#endif
4939 if(!m_out_mem_ptr)
4940 {
4941 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4942 drv_ctx.op_buf.actualcount,
4943 drv_ctx.op_buf.buffer_size);
4944 int nBufHdrSize = 0;
4945 int nPlatformEntrySize = 0;
4946 int nPlatformListSize = 0;
4947 int nPMEMInfoSize = 0;
4948 int pmem_fd = -1;
4949 unsigned char *pmem_baseaddress = NULL;
4950
4951 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4952 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4953 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4954
4955 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4956 drv_ctx.op_buf.actualcount);
4957 nBufHdrSize = drv_ctx.op_buf.actualcount *
4958 sizeof(OMX_BUFFERHEADERTYPE);
4959
4960 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4961 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4962 nPlatformListSize = drv_ctx.op_buf.actualcount *
4963 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4964 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4965 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4966
4967 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4968 sizeof(OMX_BUFFERHEADERTYPE),
4969 nPMEMInfoSize,
4970 nPlatformListSize);
4971 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4972 drv_ctx.op_buf.actualcount);
4973#ifdef USE_ION
4974 ion_device_fd = alloc_map_ion_memory(
4975 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4976 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004977 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004978 if (ion_device_fd < 0) {
4979 return OMX_ErrorInsufficientResources;
4980 }
4981 pmem_fd = fd_ion_data.fd;
4982#else
4983 pmem_fd = open (MEM_DEVICE,O_RDWR);
4984
4985 if (pmem_fd < 0)
4986 {
4987 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4988 drv_ctx.op_buf.buffer_size);
4989 return OMX_ErrorInsufficientResources;
4990 }
4991
4992 if(pmem_fd == 0)
4993 {
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
5004 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5005 drv_ctx.op_buf.actualcount,
5006 drv_ctx.op_buf.alignment))
5007 {
5008 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5009 close(pmem_fd);
5010 return OMX_ErrorInsufficientResources;
5011 }
5012#endif
5013 if (!secure_mode) {
5014 pmem_baseaddress = (unsigned char *)mmap(NULL,
5015 (drv_ctx.op_buf.buffer_size *
5016 drv_ctx.op_buf.actualcount),
5017 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5018 if (pmem_baseaddress == MAP_FAILED)
5019 {
5020 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5021 drv_ctx.op_buf.buffer_size);
5022 close(pmem_fd);
5023#ifdef USE_ION
5024 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5025#endif
5026 return OMX_ErrorInsufficientResources;
5027 }
5028 }
5029 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5030 // Alloc mem for platform specific info
5031 char *pPtr=NULL;
5032 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5033 nPMEMInfoSize,1);
5034 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5035 calloc (sizeof(struct vdec_bufferpayload),
5036 drv_ctx.op_buf.actualcount);
5037 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5038 calloc (sizeof (struct vdec_output_frameinfo),
5039 drv_ctx.op_buf.actualcount);
5040#ifdef USE_ION
5041 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5042 calloc (sizeof(struct vdec_ion),
5043 drv_ctx.op_buf.actualcount);
5044#endif
5045
5046 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5047 && drv_ctx.ptr_respbuffer)
5048 {
5049 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5050 (drv_ctx.op_buf.buffer_size *
5051 drv_ctx.op_buf.actualcount);
5052 bufHdr = m_out_mem_ptr;
5053 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5054 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5055 (((char *) m_platform_list) + nPlatformListSize);
5056 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5057 (((char *) m_platform_entry) + nPlatformEntrySize);
5058 pPlatformList = m_platform_list;
5059 pPlatformEntry = m_platform_entry;
5060 pPMEMInfo = m_pmem_info;
5061
5062 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5063
5064 // Settting the entire storage nicely
5065 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5066 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5067 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5068 {
5069 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5070 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5071 // Set the values when we determine the right HxW param
5072 bufHdr->nAllocLen = bytes;
5073 bufHdr->nFilledLen = 0;
5074 bufHdr->pAppPrivate = appData;
5075 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5076 // Platform specific PMEM Information
5077 // Initialize the Platform Entry
5078 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5079 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5080 pPlatformEntry->entry = pPMEMInfo;
5081 // Initialize the Platform List
5082 pPlatformList->nEntries = 1;
5083 pPlatformList->entryList = pPlatformEntry;
5084 // Keep pBuffer NULL till vdec is opened
5085 bufHdr->pBuffer = NULL;
5086 bufHdr->nOffset = 0;
5087
5088 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5089 pPMEMInfo->pmem_fd = 0;
5090 bufHdr->pPlatformPrivate = pPlatformList;
5091
5092 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005093 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005094#ifdef USE_ION
5095 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5096 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5097 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5098#endif
5099
5100 /*Create a mapping between buffers*/
5101 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5102 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5103 &drv_ctx.ptr_outputbuffer[i];
5104 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5105 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5106 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5107
5108 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5109 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5110 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5111 // Move the buffer and buffer header pointers
5112 bufHdr++;
5113 pPMEMInfo++;
5114 pPlatformEntry++;
5115 pPlatformList++;
5116 }
5117 }
5118 else
5119 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005120 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005121 m_out_mem_ptr, pPtr);
5122 if(m_out_mem_ptr)
5123 {
5124 free(m_out_mem_ptr);
5125 m_out_mem_ptr = NULL;
5126 }
5127 if(pPtr)
5128 {
5129 free(pPtr);
5130 pPtr = NULL;
5131 }
5132 if(drv_ctx.ptr_outputbuffer)
5133 {
5134 free(drv_ctx.ptr_outputbuffer);
5135 drv_ctx.ptr_outputbuffer = NULL;
5136 }
5137 if(drv_ctx.ptr_respbuffer)
5138 {
5139 free(drv_ctx.ptr_respbuffer);
5140 drv_ctx.ptr_respbuffer = NULL;
5141 }
5142#ifdef USE_ION
5143 if (drv_ctx.op_buf_ion_info) {
5144 DEBUG_PRINT_LOW("\n Free o/p ion context");
5145 free(drv_ctx.op_buf_ion_info);
5146 drv_ctx.op_buf_ion_info = NULL;
5147 }
5148#endif
5149 eRet = OMX_ErrorInsufficientResources;
5150 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005151 if (eRet == OMX_ErrorNone)
5152 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005153 }
5154
5155 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5156 {
5157 if(BITMASK_ABSENT(&m_out_bm_count,i))
5158 {
5159 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5160 break;
5161 }
5162 }
5163
5164 if (eRet == OMX_ErrorNone)
5165 {
5166 if(i < drv_ctx.op_buf.actualcount)
5167 {
5168 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005169 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170 int rc;
5171 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5172
5173 drv_ctx.ptr_outputbuffer[i].buffer_len =
5174 drv_ctx.op_buf.buffer_size;
5175
5176 *bufferHdr = (m_out_mem_ptr + i );
5177 if (secure_mode) {
5178 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5179 }
5180 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5181
5182 buf.index = i;
5183 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5184 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005185 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005186 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5187 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005188#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005189 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005190#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005191 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5192 plane[0].data_offset = 0;
5193 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5194 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5195 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5196 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5197#ifdef USE_ION
5198 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5199#endif
5200 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5201 plane[extra_idx].data_offset = 0;
5202 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5203 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5204 return OMX_ErrorBadParameter;
5205 }
5206 buf.m.planes = plane;
5207 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005208 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 -07005209 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5210 if (rc) {
5211 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005212 return OMX_ErrorInsufficientResources;
5213 }
5214
5215 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5216 enum v4l2_buf_type buf_type;
5217 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5218 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5219 if (rc) {
5220 return OMX_ErrorInsufficientResources;
5221 } else {
5222 streaming[CAPTURE_PORT] = true;
5223 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5224 }
5225 }
5226
5227 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5228 (*bufferHdr)->pAppPrivate = appData;
5229 BITMASK_SET(&m_out_bm_count,i);
5230 }
5231 else
5232 {
5233 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5234 eRet = OMX_ErrorInsufficientResources;
5235 }
5236 }
5237
5238 return eRet;
5239}
5240
5241
5242// AllocateBuffer -- API Call
5243/* ======================================================================
5244FUNCTION
5245 omx_vdec::AllocateBuffer
5246
5247DESCRIPTION
5248 Returns zero if all the buffers released..
5249
5250PARAMETERS
5251 None.
5252
5253RETURN VALUE
5254 true/false
5255
5256========================================================================== */
5257OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5258 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5259 OMX_IN OMX_U32 port,
5260 OMX_IN OMX_PTR appData,
5261 OMX_IN OMX_U32 bytes)
5262{
5263 unsigned i = 0;
5264 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5265
5266 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5267 if(m_state == OMX_StateInvalid)
5268 {
5269 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5270 return OMX_ErrorInvalidState;
5271 }
5272
5273 if(port == OMX_CORE_INPUT_PORT_INDEX)
5274 {
5275 if (arbitrary_bytes)
5276 {
5277 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5278 }
5279 else
5280 {
5281 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5282 }
5283 }
5284 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5285 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005286 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5287 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005288 }
5289 else
5290 {
5291 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5292 eRet = OMX_ErrorBadPortIndex;
5293 }
5294 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5295 if(eRet == OMX_ErrorNone)
5296 {
5297 if(allocate_done()){
5298 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5299 {
5300 // Send the callback now
5301 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5302 post_event(OMX_CommandStateSet,OMX_StateIdle,
5303 OMX_COMPONENT_GENERATE_EVENT);
5304 }
5305 }
5306 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5307 {
5308 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5309 {
5310 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5311 post_event(OMX_CommandPortEnable,
5312 OMX_CORE_INPUT_PORT_INDEX,
5313 OMX_COMPONENT_GENERATE_EVENT);
5314 }
5315 }
5316 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5317 {
5318 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5319 {
5320 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5321 post_event(OMX_CommandPortEnable,
5322 OMX_CORE_OUTPUT_PORT_INDEX,
5323 OMX_COMPONENT_GENERATE_EVENT);
5324 }
5325 }
5326 }
5327 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5328 return eRet;
5329}
5330
5331// Free Buffer - API call
5332/* ======================================================================
5333FUNCTION
5334 omx_vdec::FreeBuffer
5335
5336DESCRIPTION
5337
5338PARAMETERS
5339 None.
5340
5341RETURN VALUE
5342 true/false
5343
5344========================================================================== */
5345OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5346 OMX_IN OMX_U32 port,
5347 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5348{
5349 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5350 unsigned int nPortIndex;
5351 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5352
5353 if(m_state == OMX_StateIdle &&
5354 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5355 {
5356 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5357 }
5358 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5359 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5360 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005361 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362 }
5363 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5364 {
5365 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5366 post_event(OMX_EventError,
5367 OMX_ErrorPortUnpopulated,
5368 OMX_COMPONENT_GENERATE_EVENT);
5369
5370 return OMX_ErrorIncorrectStateOperation;
5371 }
5372 else if (m_state != OMX_StateInvalid)
5373 {
5374 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5375 post_event(OMX_EventError,
5376 OMX_ErrorPortUnpopulated,
5377 OMX_COMPONENT_GENERATE_EVENT);
5378 }
5379
5380 if(port == OMX_CORE_INPUT_PORT_INDEX)
5381 {
5382 /*Check if arbitrary bytes*/
5383 if(!arbitrary_bytes && !input_use_buffer)
5384 nPortIndex = buffer - m_inp_mem_ptr;
5385 else
5386 nPortIndex = buffer - m_inp_heap_ptr;
5387
5388 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5389 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5390 {
5391 // Clear the bit associated with it.
5392 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5393 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5394 if (input_use_buffer == true)
5395 {
5396
5397 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5398 if(m_phdr_pmem_ptr)
5399 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5400 }
5401 else
5402 {
5403 if (arbitrary_bytes)
5404 {
5405 if(m_phdr_pmem_ptr)
5406 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5407 else
5408 free_input_buffer(nPortIndex,NULL);
5409 }
5410 else
5411 free_input_buffer(buffer);
5412 }
5413 m_inp_bPopulated = OMX_FALSE;
5414 /*Free the Buffer Header*/
5415 if (release_input_done())
5416 {
5417 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5418 free_input_buffer_header();
5419 }
5420 }
5421 else
5422 {
5423 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5424 eRet = OMX_ErrorBadPortIndex;
5425 }
5426
5427 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5428 && release_input_done())
5429 {
5430 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5431 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5432 post_event(OMX_CommandPortDisable,
5433 OMX_CORE_INPUT_PORT_INDEX,
5434 OMX_COMPONENT_GENERATE_EVENT);
5435 }
5436 }
5437 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5438 {
5439 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005440 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005441 if(nPortIndex < drv_ctx.op_buf.actualcount)
5442 {
5443 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5444 // Clear the bit associated with it.
5445 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5446 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005447 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005448
5449 if (release_output_done())
5450 {
5451 free_output_buffer_header();
5452 }
5453 }
5454 else
5455 {
5456 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5457 eRet = OMX_ErrorBadPortIndex;
5458 }
5459 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5460 && release_output_done())
5461 {
5462 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5463
5464 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5465 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5466#ifdef _ANDROID_ICS_
5467 if (m_enable_android_native_buffers)
5468 {
5469 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5470 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5471 }
5472#endif
5473
5474 post_event(OMX_CommandPortDisable,
5475 OMX_CORE_OUTPUT_PORT_INDEX,
5476 OMX_COMPONENT_GENERATE_EVENT);
5477 }
5478 }
5479 else
5480 {
5481 eRet = OMX_ErrorBadPortIndex;
5482 }
5483 if((eRet == OMX_ErrorNone) &&
5484 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5485 {
5486 if(release_done())
5487 {
5488 // Send the callback now
5489 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5490 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5491 OMX_COMPONENT_GENERATE_EVENT);
5492 }
5493 }
5494 return eRet;
5495}
5496
5497
5498/* ======================================================================
5499FUNCTION
5500 omx_vdec::EmptyThisBuffer
5501
5502DESCRIPTION
5503 This routine is used to push the encoded video frames to
5504 the video decoder.
5505
5506PARAMETERS
5507 None.
5508
5509RETURN VALUE
5510 OMX Error None if everything went successful.
5511
5512========================================================================== */
5513OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5514 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5515{
5516 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5517 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5518
5519 if(m_state == OMX_StateInvalid)
5520 {
5521 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5522 return OMX_ErrorInvalidState;
5523 }
5524
5525 if (buffer == NULL)
5526 {
5527 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5528 return OMX_ErrorBadParameter;
5529 }
5530
5531 if (!m_inp_bEnabled)
5532 {
5533 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5534 return OMX_ErrorIncorrectStateOperation;
5535 }
5536
5537 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5538 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005539 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540 return OMX_ErrorBadPortIndex;
5541 }
5542
5543#ifdef _ANDROID_
5544 if(iDivXDrmDecrypt)
5545 {
5546 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5547 if(drmErr != OMX_ErrorNone) {
5548 // this error can be ignored
5549 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5550 }
5551 }
5552#endif //_ANDROID_
5553 if (perf_flag)
5554 {
5555 if (!latency)
5556 {
5557 dec_time.stop();
5558 latency = dec_time.processing_time_us();
5559 dec_time.start();
5560 }
5561 }
5562
5563 if (arbitrary_bytes)
5564 {
5565 nBufferIndex = buffer - m_inp_heap_ptr;
5566 }
5567 else
5568 {
5569 if (input_use_buffer == true)
5570 {
5571 nBufferIndex = buffer - m_inp_heap_ptr;
5572 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5573 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5574 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5575 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005576 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 -07005577 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5578 }
5579 else{
5580 nBufferIndex = buffer - m_inp_mem_ptr;
5581 }
5582 }
5583
5584 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5585 {
5586 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5587 return OMX_ErrorBadParameter;
5588 }
5589
5590 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5591 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5592 if (arbitrary_bytes)
5593 {
5594 post_event ((unsigned)hComp,(unsigned)buffer,
5595 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5596 }
5597 else
5598 {
5599 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5600 set_frame_rate(buffer->nTimeStamp);
5601 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5602 }
5603 return OMX_ErrorNone;
5604}
5605
5606/* ======================================================================
5607FUNCTION
5608 omx_vdec::empty_this_buffer_proxy
5609
5610DESCRIPTION
5611 This routine is used to push the encoded video frames to
5612 the video decoder.
5613
5614PARAMETERS
5615 None.
5616
5617RETURN VALUE
5618 OMX Error None if everything went successful.
5619
5620========================================================================== */
5621OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5622 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5623{
5624 int push_cnt = 0,i=0;
5625 unsigned nPortIndex = 0;
5626 OMX_ERRORTYPE ret = OMX_ErrorNone;
5627 struct vdec_input_frameinfo frameinfo;
5628 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005629 struct vdec_seqheader seq_header;
5630 bool port_setting_changed = true;
5631 bool not_coded_vop = false;
5632
5633 /*Should we generate a Aync error event*/
5634 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5635 {
5636 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5637 return OMX_ErrorBadParameter;
5638 }
5639
5640 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5641
5642 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5643 {
5644 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5645 nPortIndex);
5646 return OMX_ErrorBadParameter;
5647 }
5648
5649 pending_input_buffers++;
5650
5651 /* return zero length and not an EOS buffer */
5652 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5653 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5654 {
5655 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5656 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5657 OMX_COMPONENT_GENERATE_EBD);
5658 return OMX_ErrorNone;
5659 }
5660
5661
5662 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5663 mp4StreamType psBits;
5664 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5665 psBits.numBytes = buffer->nFilledLen;
5666 mp4_headerparser.parseHeader(&psBits);
5667 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5668 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5669 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005670 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005671 buffer->nFilledLen,frame_count);
5672 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5673 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5674 not_coded_vop = false;
5675 buffer->nFilledLen = 0;
5676 }
5677 }
5678 }
5679
5680 if(input_flush_progress == true
5681
5682 || not_coded_vop
5683
5684 )
5685 {
5686 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5687 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5688 OMX_COMPONENT_GENERATE_EBD);
5689 return OMX_ErrorNone;
5690 }
5691
5692 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5693
5694 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5695 {
5696 return OMX_ErrorBadParameter;
5697 }
5698
5699 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5700 /*for use buffer we need to memcpy the data*/
5701 temp_buffer->buffer_len = buffer->nFilledLen;
5702
5703 if (input_use_buffer)
5704 {
5705 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5706 {
5707 if(arbitrary_bytes)
5708 {
5709 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5710 }
5711 else
5712 {
5713 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5714 buffer->nFilledLen);
5715 }
5716 }
5717 else
5718 {
5719 return OMX_ErrorBadParameter;
5720 }
5721
5722 }
5723
5724 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5725 frameinfo.client_data = (void *) buffer;
5726 frameinfo.datalen = temp_buffer->buffer_len;
5727 frameinfo.flags = 0;
5728 frameinfo.offset = buffer->nOffset;
5729 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5730 frameinfo.pmem_offset = temp_buffer->offset;
5731 frameinfo.timestamp = buffer->nTimeStamp;
5732 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5733 {
5734 DEBUG_PRINT_LOW("ETB: dmx enabled");
5735 if (m_demux_entries == 0)
5736 {
5737 extract_demux_addr_offsets(buffer);
5738 }
5739
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005740 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741 handle_demux_data(buffer);
5742 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5743 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5744 }
5745 else
5746 {
5747 frameinfo.desc_addr = NULL;
5748 frameinfo.desc_size = 0;
5749 }
5750 if(!arbitrary_bytes)
5751 {
5752 frameinfo.flags |= buffer->nFlags;
5753 }
5754
5755#ifdef _ANDROID_
5756 if (m_debug_timestamp)
5757 {
5758 if(arbitrary_bytes)
5759 {
5760 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5761 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5762 }
5763 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5764 {
5765 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5766 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5767 }
5768 }
5769#endif
5770
5771#ifdef INPUT_BUFFER_LOG
5772 if (inputBufferFile1)
5773 {
5774 fwrite((const char *)temp_buffer->bufferaddr,
5775 temp_buffer->buffer_len,1,inputBufferFile1);
5776 }
5777#endif
5778
5779 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5780 {
5781 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5782 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5783 }
5784
5785 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5786 {
5787 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5788 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5789 h264_scratch.nFilledLen = 0;
5790 nal_count = 0;
5791 look_ahead_nal = false;
5792 frame_count = 0;
5793 if (m_frame_parser.mutils)
5794 m_frame_parser.mutils->initialize_frame_checking_environment();
5795 m_frame_parser.flush();
5796 h264_last_au_ts = LLONG_MAX;
5797 h264_last_au_flags = 0;
5798 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5799 m_demux_entries = 0;
5800 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005801 struct v4l2_buffer buf;
5802 struct v4l2_plane plane;
5803 memset( (void *)&buf, 0, sizeof(buf));
5804 memset( (void *)&plane, 0, sizeof(plane));
5805 int rc;
5806 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5808 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005809 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005810 }
5811 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5812 buf.index = nPortIndex;
5813 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5814 buf.memory = V4L2_MEMORY_USERPTR;
5815 plane.bytesused = temp_buffer->buffer_len;
5816 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005817 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5818 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819 plane.reserved[0] = temp_buffer->pmem_fd;
5820 plane.reserved[1] = temp_buffer->offset;
5821 plane.data_offset = 0;
5822 buf.m.planes = &plane;
5823 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005824 if (frameinfo.timestamp >= LLONG_MAX) {
5825 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5826 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005827 //assumption is that timestamp is in milliseconds
5828 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5829 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005830 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5831
Shalaj Jain273b3e02012-06-22 19:08:03 -07005832 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005833 if(rc)
5834 {
5835 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5836 return OMX_ErrorHardware;
5837 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005838 if(!streaming[OUTPUT_PORT])
5839 {
5840 enum v4l2_buf_type buf_type;
5841 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005842
Shalaj Jain273b3e02012-06-22 19:08:03 -07005843 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5844 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5845 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5846 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005847 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005848 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005849 } else{
5850 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005851 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005852 }
5853}
5854 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5855 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5856 time_stamp_dts.insert_timestamp(buffer);
5857
5858 return ret;
5859}
5860
5861/* ======================================================================
5862FUNCTION
5863 omx_vdec::FillThisBuffer
5864
5865DESCRIPTION
5866 IL client uses this method to release the frame buffer
5867 after displaying them.
5868
5869PARAMETERS
5870 None.
5871
5872RETURN VALUE
5873 true/false
5874
5875========================================================================== */
5876OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5877 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5878{
5879
5880 if(m_state == OMX_StateInvalid)
5881 {
5882 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5883 return OMX_ErrorInvalidState;
5884 }
5885
5886 if (!m_out_bEnabled)
5887 {
5888 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5889 return OMX_ErrorIncorrectStateOperation;
5890 }
5891
Vinay Kaliada4f4422013-01-09 10:45:03 -08005892 if (buffer == NULL ||
5893 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005894 {
5895 return OMX_ErrorBadParameter;
5896 }
5897
5898 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5899 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005900 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901 return OMX_ErrorBadPortIndex;
5902 }
5903
5904 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005905 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906 return OMX_ErrorNone;
5907}
5908/* ======================================================================
5909FUNCTION
5910 omx_vdec::fill_this_buffer_proxy
5911
5912DESCRIPTION
5913 IL client uses this method to release the frame buffer
5914 after displaying them.
5915
5916PARAMETERS
5917 None.
5918
5919RETURN VALUE
5920 true/false
5921
5922========================================================================== */
5923OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5924 OMX_IN OMX_HANDLETYPE hComp,
5925 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5926{
5927 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005928 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5929 unsigned nPortIndex = 0;
5930 struct vdec_fillbuffer_cmd fillbuffer;
5931 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5932 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5933
Vinay Kaliada4f4422013-01-09 10:45:03 -08005934 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005935
Vinay Kaliada4f4422013-01-09 10:45:03 -08005936 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005937 return OMX_ErrorBadParameter;
5938
5939 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5940 bufferAdd, bufferAdd->pBuffer);
5941 /*Return back the output buffer to client*/
5942 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5943 {
5944 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5945 buffer->nFilledLen = 0;
5946 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5947 return OMX_ErrorNone;
5948 }
5949 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005950 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005951 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5952 if (ptr_respbuffer)
5953 {
5954 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5955 }
5956
5957 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5958 {
5959 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5960 buffer->nFilledLen = 0;
5961 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5962 pending_output_buffers--;
5963 return OMX_ErrorBadParameter;
5964 }
5965
Shalaj Jain286b0062013-02-21 20:35:48 -08005966 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005967 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08005968 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005969
5970#ifdef _ANDROID_ICS_
5971 if (m_enable_android_native_buffers)
5972 {
5973 // Acquire a write lock on this buffer.
5974 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5975 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5976 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5977 buffer->nFilledLen = 0;
5978 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5979 pending_output_buffers--;
5980 return OMX_ErrorInsufficientResources;
5981 } else {
5982 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5983 }
5984 }
5985#endif
5986 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08005987 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005988 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08005989 memset( (void *)&buf, 0, sizeof(buf));
5990 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005991 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005992
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005993 buf.index = nPortIndex;
5994 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5995 buf.memory = V4L2_MEMORY_USERPTR;
5996 plane[0].bytesused = buffer->nFilledLen;
5997 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005998 plane[0].m.userptr =
5999 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6000 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006001 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6002 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6003 plane[0].data_offset = 0;
6004 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6005 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6006 plane[extra_idx].bytesused = 0;
6007 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6008 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
6009#ifdef USE_ION
6010 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
6011#endif
6012 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6013 plane[extra_idx].data_offset = 0;
6014 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6015 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6016 return OMX_ErrorBadParameter;
6017 }
6018 buf.m.planes = plane;
6019 buf.length = drv_ctx.num_planes;
6020 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6021 if (rc) {
6022 /*TODO: How to handle this case */
6023 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6024 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025//#ifdef _ANDROID_ICS_
6026 // if (m_enable_android_native_buffers)
6027 // {
6028 // Unlock the buffer
6029 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6030 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6031 // return OMX_ErrorInsufficientResources;
6032 /// } else {
6033 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6034 // }
6035 // }
6036//#endif
6037 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6038 // pending_output_buffers--;
6039 // return OMX_ErrorBadParameter;
6040 //}
6041 return OMX_ErrorNone;
6042}
6043
6044/* ======================================================================
6045FUNCTION
6046 omx_vdec::SetCallbacks
6047
6048DESCRIPTION
6049 Set the callbacks.
6050
6051PARAMETERS
6052 None.
6053
6054RETURN VALUE
6055 OMX Error None if everything successful.
6056
6057========================================================================== */
6058OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6059 OMX_IN OMX_CALLBACKTYPE* callbacks,
6060 OMX_IN OMX_PTR appData)
6061{
6062
6063 m_cb = *callbacks;
6064 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6065 m_cb.EventHandler,m_cb.FillBufferDone);
6066 m_app_data = appData;
6067 return OMX_ErrorNotImplemented;
6068}
6069
6070/* ======================================================================
6071FUNCTION
6072 omx_vdec::ComponentDeInit
6073
6074DESCRIPTION
6075 Destroys the component and release memory allocated to the heap.
6076
6077PARAMETERS
6078 <TBD>.
6079
6080RETURN VALUE
6081 OMX Error None if everything successful.
6082
6083========================================================================== */
6084OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6085{
6086#ifdef _ANDROID_
6087 if(iDivXDrmDecrypt)
6088 {
6089 delete iDivXDrmDecrypt;
6090 iDivXDrmDecrypt=NULL;
6091 }
6092#endif //_ANDROID_
6093
Shalaj Jain286b0062013-02-21 20:35:48 -08006094 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006095 if (OMX_StateLoaded != m_state)
6096 {
6097 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6098 m_state);
6099 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6100 }
6101 else
6102 {
6103 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6104 }
6105
6106 /*Check if the output buffers have to be cleaned up*/
6107 if(m_out_mem_ptr)
6108 {
6109 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006110 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111 {
6112 free_output_buffer (&m_out_mem_ptr[i]);
6113#ifdef _ANDROID_ICS_
6114 if (m_enable_android_native_buffers)
6115 {
6116 if (native_buffer[i].inuse)
6117 {
6118 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6119 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6120 }
6121 native_buffer[i].inuse = false;
6122 }
6123 }
6124#endif
6125 }
6126#ifdef _ANDROID_ICS_
6127 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6128#endif
6129 }
6130
6131 /*Check if the input buffers have to be cleaned up*/
6132 if(m_inp_mem_ptr || m_inp_heap_ptr)
6133 {
6134 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006135 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006136 {
6137 if (m_inp_mem_ptr)
6138 free_input_buffer (i,&m_inp_mem_ptr[i]);
6139 else
6140 free_input_buffer (i,NULL);
6141 }
6142 }
6143 free_input_buffer_header();
6144 free_output_buffer_header();
6145 if(h264_scratch.pBuffer)
6146 {
6147 free(h264_scratch.pBuffer);
6148 h264_scratch.pBuffer = NULL;
6149 }
6150
6151 if (h264_parser)
6152 {
6153 delete h264_parser;
6154 h264_parser = NULL;
6155 }
6156
6157 if(m_platform_list)
6158 {
6159 free(m_platform_list);
6160 m_platform_list = NULL;
6161 }
6162 if(m_vendor_config.pData)
6163 {
6164 free(m_vendor_config.pData);
6165 m_vendor_config.pData = NULL;
6166 }
6167
6168 // Reset counters in mesg queues
6169 m_ftb_q.m_size=0;
6170 m_cmd_q.m_size=0;
6171 m_etb_q.m_size=0;
6172 m_ftb_q.m_read = m_ftb_q.m_write =0;
6173 m_cmd_q.m_read = m_cmd_q.m_write =0;
6174 m_etb_q.m_read = m_etb_q.m_write =0;
6175#ifdef _ANDROID_
6176 if (m_debug_timestamp)
6177 {
6178 m_timestamp_list.reset_ts_list();
6179 }
6180#endif
6181
6182 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6183 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6184 // NULL);
6185 DEBUG_PRINT_HIGH("\n Close the driver instance");
6186
6187#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006188 if (inputBufferFile1)
6189 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006190#endif
6191#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006192 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006193 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006194#endif
6195#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006196 if (outputExtradataFile)
6197 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006198#endif
6199 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6200 return OMX_ErrorNone;
6201}
6202
6203/* ======================================================================
6204FUNCTION
6205 omx_vdec::UseEGLImage
6206
6207DESCRIPTION
6208 OMX Use EGL Image method implementation <TBD>.
6209
6210PARAMETERS
6211 <TBD>.
6212
6213RETURN VALUE
6214 Not Implemented error.
6215
6216========================================================================== */
6217OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6218 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6219 OMX_IN OMX_U32 port,
6220 OMX_IN OMX_PTR appData,
6221 OMX_IN void* eglImage)
6222{
6223 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6224 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6225 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6226
6227#ifdef USE_EGL_IMAGE_GPU
6228 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6229 EGLint fd = -1, offset = 0,pmemPtr = 0;
6230#else
6231 int fd = -1, offset = 0;
6232#endif
6233 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6234 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6235 DEBUG_PRINT_ERROR("\n ");
6236 }
6237#ifdef USE_EGL_IMAGE_GPU
6238 if(m_display_id == NULL) {
6239 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6240 return OMX_ErrorInsufficientResources;
6241 }
6242 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6243 eglGetProcAddress("eglQueryImageKHR");
6244 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6245 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6246 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6247#else //with OMX test app
6248 struct temp_egl {
6249 int pmem_fd;
6250 int offset;
6251 };
6252 struct temp_egl *temp_egl_id = NULL;
6253 void * pmemPtr = (void *) eglImage;
6254 temp_egl_id = (struct temp_egl *)eglImage;
6255 if (temp_egl_id != NULL)
6256 {
6257 fd = temp_egl_id->pmem_fd;
6258 offset = temp_egl_id->offset;
6259 }
6260#endif
6261 if (fd < 0) {
6262 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6263 return OMX_ErrorInsufficientResources;
6264 }
6265 pmem_info.pmem_fd = (OMX_U32) fd;
6266 pmem_info.offset = (OMX_U32) offset;
6267 pmem_entry.entry = (void *) &pmem_info;
6268 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6269 pmem_list.entryList = &pmem_entry;
6270 pmem_list.nEntries = 1;
6271 ouput_egl_buffers = true;
6272 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6273 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6274 (OMX_U8 *)pmemPtr)) {
6275 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6276 return OMX_ErrorInsufficientResources;
6277 }
6278 return OMX_ErrorNone;
6279}
6280
6281/* ======================================================================
6282FUNCTION
6283 omx_vdec::ComponentRoleEnum
6284
6285DESCRIPTION
6286 OMX Component Role Enum method implementation.
6287
6288PARAMETERS
6289 <TBD>.
6290
6291RETURN VALUE
6292 OMX Error None if everything is successful.
6293========================================================================== */
6294OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6295 OMX_OUT OMX_U8* role,
6296 OMX_IN OMX_U32 index)
6297{
6298 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6299
6300 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6301 {
6302 if((0 == index) && role)
6303 {
6304 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6305 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6306 }
6307 else
6308 {
6309 eRet = OMX_ErrorNoMore;
6310 }
6311 }
6312 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6313 {
6314 if((0 == index) && role)
6315 {
6316 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6317 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6318 }
6319 else
6320 {
6321 eRet = OMX_ErrorNoMore;
6322 }
6323 }
6324 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6325 {
6326 if((0 == index) && role)
6327 {
6328 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6329 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6330 }
6331 else
6332 {
6333 DEBUG_PRINT_LOW("\n No more roles \n");
6334 eRet = OMX_ErrorNoMore;
6335 }
6336 }
6337
6338 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6339 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6340 )
6341
6342 {
6343 if((0 == index) && role)
6344 {
6345 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6346 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6347 }
6348 else
6349 {
6350 DEBUG_PRINT_LOW("\n No more roles \n");
6351 eRet = OMX_ErrorNoMore;
6352 }
6353 }
6354 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6355 {
6356 if((0 == index) && role)
6357 {
6358 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6359 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6360 }
6361 else
6362 {
6363 DEBUG_PRINT_LOW("\n No more roles \n");
6364 eRet = OMX_ErrorNoMore;
6365 }
6366 }
6367 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6368 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6369 )
6370 {
6371 if((0 == index) && role)
6372 {
6373 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6374 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6375 }
6376 else
6377 {
6378 DEBUG_PRINT_LOW("\n No more roles \n");
6379 eRet = OMX_ErrorNoMore;
6380 }
6381 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006382 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6383 {
6384 if((0 == index) && role)
6385 {
6386 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6387 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6388 }
6389 else
6390 {
6391 DEBUG_PRINT_LOW("\n No more roles \n");
6392 eRet = OMX_ErrorNoMore;
6393 }
6394 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006395 else
6396 {
6397 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6398 eRet = OMX_ErrorInvalidComponentName;
6399 }
6400 return eRet;
6401}
6402
6403
6404
6405
6406/* ======================================================================
6407FUNCTION
6408 omx_vdec::AllocateDone
6409
6410DESCRIPTION
6411 Checks if entire buffer pool is allocated by IL Client or not.
6412 Need this to move to IDLE state.
6413
6414PARAMETERS
6415 None.
6416
6417RETURN VALUE
6418 true/false.
6419
6420========================================================================== */
6421bool omx_vdec::allocate_done(void)
6422{
6423 bool bRet = false;
6424 bool bRet_In = false;
6425 bool bRet_Out = false;
6426
6427 bRet_In = allocate_input_done();
6428 bRet_Out = allocate_output_done();
6429
6430 if(bRet_In && bRet_Out)
6431 {
6432 bRet = true;
6433 }
6434
6435 return bRet;
6436}
6437/* ======================================================================
6438FUNCTION
6439 omx_vdec::AllocateInputDone
6440
6441DESCRIPTION
6442 Checks if I/P buffer pool is allocated by IL Client or not.
6443
6444PARAMETERS
6445 None.
6446
6447RETURN VALUE
6448 true/false.
6449
6450========================================================================== */
6451bool omx_vdec::allocate_input_done(void)
6452{
6453 bool bRet = false;
6454 unsigned i=0;
6455
6456 if (m_inp_mem_ptr == NULL)
6457 {
6458 return bRet;
6459 }
6460 if(m_inp_mem_ptr )
6461 {
6462 for(;i<drv_ctx.ip_buf.actualcount;i++)
6463 {
6464 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6465 {
6466 break;
6467 }
6468 }
6469 }
6470 if(i == drv_ctx.ip_buf.actualcount)
6471 {
6472 bRet = true;
6473 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6474 }
6475 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6476 {
6477 m_inp_bPopulated = OMX_TRUE;
6478 }
6479 return bRet;
6480}
6481/* ======================================================================
6482FUNCTION
6483 omx_vdec::AllocateOutputDone
6484
6485DESCRIPTION
6486 Checks if entire O/P buffer pool is allocated by IL Client or not.
6487
6488PARAMETERS
6489 None.
6490
6491RETURN VALUE
6492 true/false.
6493
6494========================================================================== */
6495bool omx_vdec::allocate_output_done(void)
6496{
6497 bool bRet = false;
6498 unsigned j=0;
6499
6500 if (m_out_mem_ptr == NULL)
6501 {
6502 return bRet;
6503 }
6504
6505 if (m_out_mem_ptr)
6506 {
6507 for(;j < drv_ctx.op_buf.actualcount;j++)
6508 {
6509 if(BITMASK_ABSENT(&m_out_bm_count,j))
6510 {
6511 break;
6512 }
6513 }
6514 }
6515
6516 if(j == drv_ctx.op_buf.actualcount)
6517 {
6518 bRet = true;
6519 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6520 if(m_out_bEnabled)
6521 m_out_bPopulated = OMX_TRUE;
6522 }
6523
6524 return bRet;
6525}
6526
6527/* ======================================================================
6528FUNCTION
6529 omx_vdec::ReleaseDone
6530
6531DESCRIPTION
6532 Checks if IL client has released all the buffers.
6533
6534PARAMETERS
6535 None.
6536
6537RETURN VALUE
6538 true/false
6539
6540========================================================================== */
6541bool omx_vdec::release_done(void)
6542{
6543 bool bRet = false;
6544
6545 if(release_input_done())
6546 {
6547 if(release_output_done())
6548 {
6549 bRet = true;
6550 }
6551 }
6552 return bRet;
6553}
6554
6555
6556/* ======================================================================
6557FUNCTION
6558 omx_vdec::ReleaseOutputDone
6559
6560DESCRIPTION
6561 Checks if IL client has released all the buffers.
6562
6563PARAMETERS
6564 None.
6565
6566RETURN VALUE
6567 true/false
6568
6569========================================================================== */
6570bool omx_vdec::release_output_done(void)
6571{
6572 bool bRet = false;
6573 unsigned i=0,j=0;
6574
6575 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6576 if(m_out_mem_ptr)
6577 {
6578 for(;j < drv_ctx.op_buf.actualcount ; j++)
6579 {
6580 if(BITMASK_PRESENT(&m_out_bm_count,j))
6581 {
6582 break;
6583 }
6584 }
6585 if(j == drv_ctx.op_buf.actualcount)
6586 {
6587 m_out_bm_count = 0;
6588 bRet = true;
6589 }
6590 }
6591 else
6592 {
6593 m_out_bm_count = 0;
6594 bRet = true;
6595 }
6596 return bRet;
6597}
6598/* ======================================================================
6599FUNCTION
6600 omx_vdec::ReleaseInputDone
6601
6602DESCRIPTION
6603 Checks if IL client has released all the buffers.
6604
6605PARAMETERS
6606 None.
6607
6608RETURN VALUE
6609 true/false
6610
6611========================================================================== */
6612bool omx_vdec::release_input_done(void)
6613{
6614 bool bRet = false;
6615 unsigned i=0,j=0;
6616
6617 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6618 if(m_inp_mem_ptr)
6619 {
6620 for(;j<drv_ctx.ip_buf.actualcount;j++)
6621 {
6622 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6623 {
6624 break;
6625 }
6626 }
6627 if(j==drv_ctx.ip_buf.actualcount)
6628 {
6629 bRet = true;
6630 }
6631 }
6632 else
6633 {
6634 bRet = true;
6635 }
6636 return bRet;
6637}
6638
6639OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6640 OMX_BUFFERHEADERTYPE * buffer)
6641{
6642 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6643 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6644 {
6645 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6646 return OMX_ErrorBadParameter;
6647 }
6648 else if (output_flush_progress)
6649 {
6650 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6651 buffer->nFilledLen = 0;
6652 buffer->nTimeStamp = 0;
6653 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6654 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6655 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6656 }
6657
6658 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6659 buffer, buffer->pBuffer);
6660 pending_output_buffers --;
6661
6662 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6663 {
6664 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6665 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006666 post_event((unsigned)NULL, (unsigned)NULL,
6667 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006668
6669 if (psource_frame)
6670 {
6671 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6672 psource_frame = NULL;
6673 }
6674 if (pdest_frame)
6675 {
6676 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006677 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6678 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006679 pdest_frame = NULL;
6680 }
6681 }
6682
6683 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6684#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006685 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006686 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006687 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006688 int stride = drv_ctx.video_resolution.stride;
6689 int scanlines = drv_ctx.video_resolution.scan_lines;
6690 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006691 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006692 int bytes_written = 0;
6693 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6694 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6695 temp += stride;
6696 }
6697 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006698 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006699 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6700 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6701 temp += stride_c;
6702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006703 }
6704#endif
6705
6706 /* For use buffer we need to copy the data */
6707 if (!output_flush_progress)
6708 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006709 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006710 bool is_duplicate_ts_valid = true;
6711 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6712 output_capability == V4L2_PIX_FMT_DIVX ||
6713 output_capability == V4L2_PIX_FMT_DIVX_311)
6714 is_duplicate_ts_valid = false;
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006715 if (buffer->nFilledLen > 0)
6716 time_stamp_dts.get_next_timestamp(buffer,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006717 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6718 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006719 else {
6720 m_inp_err_count++;
6721 time_stamp_dts.remove_time_stamp(
6722 buffer->nTimeStamp,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006723 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6724 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006725 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006726 if (m_debug_timestamp)
6727 {
6728 {
6729 OMX_TICKS expected_ts = 0;
6730 m_timestamp_list.pop_min_ts(expected_ts);
6731 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6732 buffer->nTimeStamp, expected_ts);
6733
6734 if (buffer->nTimeStamp != expected_ts)
6735 {
6736 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6737 }
6738 }
6739 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006740 }
6741 if (m_cb.FillBufferDone)
6742 {
6743 if (buffer->nFilledLen > 0)
6744 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006745 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006746 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6747 // Keep min timestamp interval to handle corrupted bit stream scenario
6748 set_frame_rate(buffer->nTimeStamp);
6749 else if (arbitrary_bytes)
6750 adjust_timestamp(buffer->nTimeStamp);
6751 if (perf_flag)
6752 {
6753 if (!proc_frms)
6754 {
6755 dec_time.stop();
6756 latency = dec_time.processing_time_us() - latency;
6757 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6758 dec_time.start();
6759 fps_metrics.start();
6760 }
6761 proc_frms++;
6762 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6763 {
6764 OMX_U64 proc_time = 0;
6765 fps_metrics.stop();
6766 proc_time = fps_metrics.processing_time_us();
6767 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6768 proc_frms, (float)proc_time / 1e6,
6769 (float)(1e6 * proc_frms) / proc_time);
6770 proc_frms = 0;
6771 }
6772 }
6773
6774#ifdef OUTPUT_EXTRADATA_LOG
6775 if (outputExtradataFile)
6776 {
6777
6778 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6779 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6780 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6781 buffer->nFilledLen + 3)&(~3));
6782 while(p_extra &&
6783 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6784 {
6785 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6786 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6787 if (p_extra->eType == OMX_ExtraDataNone)
6788 {
6789 break;
6790 }
6791 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6792 }
6793 }
6794#endif
6795 }
6796 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6797 prev_ts = LLONG_MAX;
6798 rst_prev_ts = true;
6799 }
6800
6801 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6802 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6803 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006804 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006805#ifdef _ANDROID_ICS_
6806 if (m_enable_android_native_buffers)
6807 {
6808 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6809 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6810 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6811 return OMX_ErrorInsufficientResources;
6812 }
6813 else {
6814 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6815 }
6816 }
6817 }
6818#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006819 OMX_BUFFERHEADERTYPE *il_buffer;
6820 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6821 if (il_buffer)
6822 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6823 else {
6824 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6825 return OMX_ErrorBadParameter;
6826 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006827 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006828 }
6829 else
6830 {
6831 return OMX_ErrorBadParameter;
6832 }
6833
6834 return OMX_ErrorNone;
6835}
6836
6837OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6838 OMX_BUFFERHEADERTYPE* buffer)
6839{
6840
6841 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6842 {
6843 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6844 return OMX_ErrorBadParameter;
6845 }
6846
6847 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6848 buffer, buffer->pBuffer);
6849 pending_input_buffers--;
6850
6851 if (arbitrary_bytes)
6852 {
6853 if (pdest_frame == NULL && input_flush_progress == false)
6854 {
6855 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6856 pdest_frame = buffer;
6857 buffer->nFilledLen = 0;
6858 buffer->nTimeStamp = LLONG_MAX;
6859 push_input_buffer (hComp);
6860 }
6861 else
6862 {
6863 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6864 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006865 if (!m_input_free_q.insert_entry((unsigned)buffer,
6866 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006867 {
6868 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6869 }
6870 }
6871 }
6872 else if(m_cb.EmptyBufferDone)
6873 {
6874 buffer->nFilledLen = 0;
6875 if (input_use_buffer == true){
6876 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6877 }
6878 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6879 }
6880 return OMX_ErrorNone;
6881}
6882
Shalaj Jain273b3e02012-06-22 19:08:03 -07006883int omx_vdec::async_message_process (void *context, void* message)
6884{
6885 omx_vdec* omx = NULL;
6886 struct vdec_msginfo *vdec_msg = NULL;
6887 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006888 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006889 struct vdec_output_frameinfo *output_respbuf = NULL;
6890 int rc=1;
6891 if (context == NULL || message == NULL)
6892 {
6893 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6894 return -1;
6895 }
6896 vdec_msg = (struct vdec_msginfo *)message;
6897
6898 omx = reinterpret_cast<omx_vdec*>(context);
6899
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900 switch (vdec_msg->msgcode)
6901 {
6902
6903 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006904 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006905 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6906 break;
6907
6908 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006909 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006910 OMX_COMPONENT_GENERATE_START_DONE);
6911 break;
6912
6913 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006914 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006915 OMX_COMPONENT_GENERATE_STOP_DONE);
6916 break;
6917
6918 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006919 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006920 OMX_COMPONENT_GENERATE_RESUME_DONE);
6921 break;
6922
6923 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006924 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006925 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6926 break;
6927
6928 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006929 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006930 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6931 break;
6932 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006933 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006934 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6935 break;
6936 case VDEC_MSG_RESP_INPUT_FLUSHED:
6937 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6938
Shalaj Jain286b0062013-02-21 20:35:48 -08006939 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6940 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006941
6942 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6943 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6944 if (omxhdr == NULL ||
6945 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6946 {
6947 omxhdr = NULL;
6948 vdec_msg->status_code = VDEC_S_EFATAL;
6949 }
6950
6951 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6952 OMX_COMPONENT_GENERATE_EBD);
6953 break;
6954 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6955 int64_t *timestamp;
6956 timestamp = (int64_t *) malloc(sizeof(int64_t));
6957 if (timestamp) {
6958 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6959 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6960 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6961 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6962 vdec_msg->msgdata.output_frame.time_stamp);
6963 }
6964 break;
6965 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6966 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6967
6968 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6969 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6970 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6971 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6972 vdec_msg->msgdata.output_frame.pic_type);
6973
6974 if (omxhdr && omxhdr->pOutputPortPrivate &&
6975 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6976 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6977 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6978 {
6979 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6980 {
6981 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6982 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006983 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6985
6986 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6987 {
6988 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6989 //rc = -1;
6990 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006991 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6992 {
6993 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6994 }
Shalaj Jain286b0062013-02-21 20:35:48 -08006995 vdec_msg->msgdata.output_frame.bufferaddr =
6996 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Vinay Kaliab9e98102013-04-02 19:31:43 -07006997 int format_notably_changed = 0;
6998 if (omxhdr->nFilledLen &&
6999 (omxhdr->nFilledLen != omx->prev_n_filled_len))
7000 {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007001 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7002 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7003 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7004 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7005 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7006 format_notably_changed = 1;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007007 }
7008 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007009 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7010 vdec_msg->msgdata.output_frame.framesize.left)
7011 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08007012 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7013 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007014 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7015 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
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 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
7019 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
7020 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kaliafa7cc352013-04-03 17:02:37 -07007021 }
Vinay Kalia0321dc12013-04-08 20:45:54 -07007022 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
7023 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
7024 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007025 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7026 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7027 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7028 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007029 format_notably_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08007030 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007031 if (format_notably_changed) {
7032 if(omx->is_video_session_supported()) {
7033 omx->post_event (NULL, vdec_msg->status_code,
7034 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7035 } else {
7036 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7037 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7038 }
7039 }
7040 if (omxhdr->nFilledLen)
7041 omx->prev_n_filled_len = omxhdr->nFilledLen;
7042
Shalaj Jain273b3e02012-06-22 19:08:03 -07007043 output_respbuf = (struct vdec_output_frameinfo *)\
7044 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007045 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7046 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08007047 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7048 {
7049 output_respbuf->pic_type = PICTURE_TYPE_I;
7050 }
7051 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7052 {
7053 output_respbuf->pic_type = PICTURE_TYPE_P;
7054 }
7055 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7056 output_respbuf->pic_type = PICTURE_TYPE_B;
7057 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007058
7059 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007060 memcpy ( omxhdr->pBuffer, (void *)
7061 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7062 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7063 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007064 }
7065 else
7066 omxhdr->nFilledLen = 0;
7067 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7068 OMX_COMPONENT_GENERATE_FBD);
7069 }
7070 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007071 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007072 OMX_COMPONENT_GENERATE_EOS_DONE);
7073 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007074 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007075 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7076 break;
7077 case VDEC_MSG_EVT_CONFIG_CHANGED:
7078 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007079 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7080 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007081 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007082 default:
7083 break;
7084 }
7085 return rc;
7086}
7087
7088OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7089 OMX_HANDLETYPE hComp,
7090 OMX_BUFFERHEADERTYPE *buffer
7091 )
7092{
7093 unsigned address,p2,id;
7094 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7095
7096 if (buffer == NULL)
7097 {
7098 return OMX_ErrorBadParameter;
7099 }
7100 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007101 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7102 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007103
7104 /* return zero length and not an EOS buffer */
7105 /* return buffer if input flush in progress */
7106 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7107 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7108 {
7109 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7110 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7111 return OMX_ErrorNone;
7112 }
7113
7114 if (psource_frame == NULL)
7115 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007116 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007117 psource_frame = buffer;
7118 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7119 push_input_buffer (hComp);
7120 }
7121 else
7122 {
7123 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007124 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7125 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007126 {
7127 return OMX_ErrorBadParameter;
7128 }
7129 }
7130
7131
7132 return OMX_ErrorNone;
7133}
7134
7135OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7136{
7137 unsigned address,p2,id;
7138 OMX_ERRORTYPE ret = OMX_ErrorNone;
7139
7140 if (pdest_frame == NULL || psource_frame == NULL)
7141 {
7142 /*Check if we have a destination buffer*/
7143 if (pdest_frame == NULL)
7144 {
7145 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7146 if (m_input_free_q.m_size)
7147 {
7148 m_input_free_q.pop_entry(&address,&p2,&id);
7149 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7150 pdest_frame->nFilledLen = 0;
7151 pdest_frame->nTimeStamp = LLONG_MAX;
7152 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7153 }
7154 }
7155
7156 /*Check if we have a destination buffer*/
7157 if (psource_frame == NULL)
7158 {
7159 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7160 if (m_input_pending_q.m_size)
7161 {
7162 m_input_pending_q.pop_entry(&address,&p2,&id);
7163 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007164 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007165 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007166 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007167 psource_frame->nFlags,psource_frame->nFilledLen);
7168
7169 }
7170 }
7171
7172 }
7173
7174 while ((pdest_frame != NULL) && (psource_frame != NULL))
7175 {
7176 switch (codec_type_parse)
7177 {
7178 case CODEC_TYPE_MPEG4:
7179 case CODEC_TYPE_H263:
7180 case CODEC_TYPE_MPEG2:
7181 ret = push_input_sc_codec(hComp);
7182 break;
7183 case CODEC_TYPE_H264:
7184 ret = push_input_h264(hComp);
7185 break;
7186 case CODEC_TYPE_VC1:
7187 ret = push_input_vc1(hComp);
7188 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007189 default:
7190 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007191 }
7192 if (ret != OMX_ErrorNone)
7193 {
7194 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7195 omx_report_error ();
7196 break;
7197 }
7198 }
7199
7200 return ret;
7201}
7202
7203OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7204{
7205 OMX_U32 partial_frame = 1;
7206 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007207 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007208
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007209 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210 psource_frame,psource_frame->nTimeStamp);
7211 if (m_frame_parser.parse_sc_frame(psource_frame,
7212 pdest_frame,&partial_frame) == -1)
7213 {
7214 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7215 return OMX_ErrorBadParameter;
7216 }
7217
7218 if (partial_frame == 0)
7219 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007220 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007221 pdest_frame->nFilledLen,psource_frame,frame_count);
7222
7223
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007224 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007225 /*First Parsed buffer will have only header Hence skip*/
7226 if (frame_count == 0)
7227 {
7228 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7229
7230 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7231 codec_type_parse == CODEC_TYPE_DIVX) {
7232 mp4StreamType psBits;
7233 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7234 psBits.numBytes = pdest_frame->nFilledLen;
7235 mp4_headerparser.parseHeader(&psBits);
7236 }
7237
7238 frame_count++;
7239 }
7240 else
7241 {
7242 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7243 if(pdest_frame->nFilledLen)
7244 {
7245 /*Push the frame to the Decoder*/
7246 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7247 {
7248 return OMX_ErrorBadParameter;
7249 }
7250 frame_count++;
7251 pdest_frame = NULL;
7252
7253 if (m_input_free_q.m_size)
7254 {
7255 m_input_free_q.pop_entry(&address,&p2,&id);
7256 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7257 pdest_frame->nFilledLen = 0;
7258 }
7259 }
7260 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7261 {
7262 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007263 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7264 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007265 pdest_frame = NULL;
7266 }
7267 }
7268 }
7269 else
7270 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007271 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007272 /*Check if Destination Buffer is full*/
7273 if (pdest_frame->nAllocLen ==
7274 pdest_frame->nFilledLen + pdest_frame->nOffset)
7275 {
7276 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7277 return OMX_ErrorStreamCorrupt;
7278 }
7279 }
7280
7281 if (psource_frame->nFilledLen == 0)
7282 {
7283 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7284 {
7285 if (pdest_frame)
7286 {
7287 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007288 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007289 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007290 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007291 pdest_frame->nFilledLen,frame_count++);
7292 /*Push the frame to the Decoder*/
7293 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7294 {
7295 return OMX_ErrorBadParameter;
7296 }
7297 frame_count++;
7298 pdest_frame = NULL;
7299 }
7300 else
7301 {
7302 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7303 generate_ebd = OMX_FALSE;
7304 }
7305 }
7306 if(generate_ebd)
7307 {
7308 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7309 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7310 psource_frame = NULL;
7311
7312 if (m_input_pending_q.m_size)
7313 {
7314 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7315 m_input_pending_q.pop_entry(&address,&p2,&id);
7316 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007317 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007318 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007319 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007320 psource_frame->nFlags,psource_frame->nFilledLen);
7321 }
7322 }
7323 }
7324 return OMX_ErrorNone;
7325}
7326
7327OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7328{
7329 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007330 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007331 OMX_BOOL isNewFrame = OMX_FALSE;
7332 OMX_BOOL generate_ebd = OMX_TRUE;
7333
7334 if (h264_scratch.pBuffer == NULL)
7335 {
7336 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7337 return OMX_ErrorBadParameter;
7338 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007339 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007340 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007341 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007342 if (h264_scratch.nFilledLen && look_ahead_nal)
7343 {
7344 look_ahead_nal = false;
7345 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7346 h264_scratch.nFilledLen)
7347 {
7348 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7349 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7350 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7351 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7352 h264_scratch.nFilledLen = 0;
7353 }
7354 else
7355 {
7356 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7357 return OMX_ErrorBadParameter;
7358 }
7359 }
7360 if (nal_length == 0)
7361 {
7362 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7363 if (m_frame_parser.parse_sc_frame(psource_frame,
7364 &h264_scratch,&partial_frame) == -1)
7365 {
7366 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7367 return OMX_ErrorBadParameter;
7368 }
7369 }
7370 else
7371 {
7372 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7373 if (m_frame_parser.parse_h264_nallength(psource_frame,
7374 &h264_scratch,&partial_frame) == -1)
7375 {
7376 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7377 return OMX_ErrorBadParameter;
7378 }
7379 }
7380
7381 if (partial_frame == 0)
7382 {
7383 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7384 {
7385 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7386 nal_count++;
7387 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7388 h264_scratch.nFlags = psource_frame->nFlags;
7389 }
7390 else
7391 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007392 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007393 if(h264_scratch.nFilledLen)
7394 {
7395 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7396 NALU_TYPE_SPS);
7397#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7398 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7399 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7400 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7401 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7402 // If timeinfo is present frame info from SEI is already processed
7403 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7404 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7405#endif
7406 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7407 nal_count++;
7408 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7409 pdest_frame->nTimeStamp = h264_last_au_ts;
7410 pdest_frame->nFlags = h264_last_au_flags;
7411#ifdef PANSCAN_HDLR
7412 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7413 h264_parser->update_panscan_data(h264_last_au_ts);
7414#endif
7415 }
7416 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7417 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7418 h264_last_au_ts = h264_scratch.nTimeStamp;
7419 h264_last_au_flags = h264_scratch.nFlags;
7420#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7421 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7422 {
7423 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7424 if (!VALID_TS(h264_last_au_ts))
7425 h264_last_au_ts = ts_in_sei;
7426 }
7427#endif
7428 } else
7429 h264_last_au_ts = LLONG_MAX;
7430 }
7431
7432 if (!isNewFrame)
7433 {
7434 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7435 h264_scratch.nFilledLen)
7436 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007437 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007438 h264_scratch.nFilledLen);
7439 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7440 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7441 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7442 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7443 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7444 h264_scratch.nFilledLen = 0;
7445 }
7446 else
7447 {
7448 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7449 return OMX_ErrorBadParameter;
7450 }
7451 }
7452 else
7453 {
7454 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007455 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007456 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007457 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007458 pdest_frame->nFilledLen,frame_count++);
7459
7460 if (pdest_frame->nFilledLen == 0)
7461 {
7462 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7463 look_ahead_nal = false;
7464 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7465 h264_scratch.nFilledLen)
7466 {
7467 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7468 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7469 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7470 h264_scratch.nFilledLen = 0;
7471 }
7472 else
7473 {
7474 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7475 return OMX_ErrorBadParameter;
7476 }
7477 }
7478 else
7479 {
7480 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7481 {
7482 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7483 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7484 }
7485 /*Push the frame to the Decoder*/
7486 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7487 {
7488 return OMX_ErrorBadParameter;
7489 }
7490 //frame_count++;
7491 pdest_frame = NULL;
7492 if (m_input_free_q.m_size)
7493 {
7494 m_input_free_q.pop_entry(&address,&p2,&id);
7495 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7496 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7497 pdest_frame->nFilledLen = 0;
7498 pdest_frame->nFlags = 0;
7499 pdest_frame->nTimeStamp = LLONG_MAX;
7500 }
7501 }
7502 }
7503 }
7504 }
7505 else
7506 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007507 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007508 /*Check if Destination Buffer is full*/
7509 if (h264_scratch.nAllocLen ==
7510 h264_scratch.nFilledLen + h264_scratch.nOffset)
7511 {
7512 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7513 return OMX_ErrorStreamCorrupt;
7514 }
7515 }
7516
7517 if (!psource_frame->nFilledLen)
7518 {
7519 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7520
7521 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7522 {
7523 if (pdest_frame)
7524 {
7525 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7526 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7527 h264_scratch.nFilledLen)
7528 {
7529 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7530 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7531 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7532 h264_scratch.nFilledLen = 0;
7533 }
7534 else
7535 {
7536 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7537 return OMX_ErrorBadParameter;
7538 }
7539 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7540 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7541
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007542 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007543 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7544 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7545#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7546 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7547 {
7548 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7549 if (!VALID_TS(pdest_frame->nTimeStamp))
7550 pdest_frame->nTimeStamp = ts_in_sei;
7551 }
7552#endif
7553 /*Push the frame to the Decoder*/
7554 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7555 {
7556 return OMX_ErrorBadParameter;
7557 }
7558 frame_count++;
7559 pdest_frame = NULL;
7560 }
7561 else
7562 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007563 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007564 pdest_frame,h264_scratch.nFilledLen);
7565 generate_ebd = OMX_FALSE;
7566 }
7567 }
7568 }
7569 if(generate_ebd && !psource_frame->nFilledLen)
7570 {
7571 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7572 psource_frame = NULL;
7573 if (m_input_pending_q.m_size)
7574 {
7575 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7576 m_input_pending_q.pop_entry(&address,&p2,&id);
7577 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007578 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007579 psource_frame->nFlags,psource_frame->nFilledLen);
7580 }
7581 }
7582 return OMX_ErrorNone;
7583}
7584
7585OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7586{
7587 OMX_U8 *buf, *pdest;
7588 OMX_U32 partial_frame = 1;
7589 OMX_U32 buf_len, dest_len;
7590
7591 if(first_frame == 0)
7592 {
7593 first_frame = 1;
7594 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7595 if(!m_vendor_config.pData)
7596 {
7597 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7598 buf = psource_frame->pBuffer;
7599 buf_len = psource_frame->nFilledLen;
7600
7601 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7602 VC1_SP_MP_START_CODE)
7603 {
7604 m_vc1_profile = VC1_SP_MP_RCV;
7605 }
7606 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7607 {
7608 m_vc1_profile = VC1_AP;
7609 }
7610 else
7611 {
7612 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7613 return OMX_ErrorStreamCorrupt;
7614 }
7615 }
7616 else
7617 {
7618 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7619 pdest_frame->nOffset;
7620 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7621 pdest_frame->nOffset);
7622
7623 if(dest_len < m_vendor_config.nDataSize)
7624 {
7625 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7626 return OMX_ErrorBadParameter;
7627 }
7628 else
7629 {
7630 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7631 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7632 }
7633 }
7634 }
7635
7636 switch(m_vc1_profile)
7637 {
7638 case VC1_AP:
7639 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7640 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7641 {
7642 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7643 return OMX_ErrorBadParameter;
7644 }
7645 break;
7646
7647 case VC1_SP_MP_RCV:
7648 default:
7649 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7650 return OMX_ErrorBadParameter;
7651 }
7652 return OMX_ErrorNone;
7653}
7654
David Ng38e2d232013-03-15 20:05:58 -07007655#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007656bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7657 OMX_U32 alignment)
7658{
7659 struct pmem_allocation allocation;
7660 allocation.size = buffer_size;
7661 allocation.align = clip2(alignment);
7662 if (allocation.align < 4096)
7663 {
7664 allocation.align = 4096;
7665 }
7666 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7667 {
7668 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7669 allocation.align, allocation.size);
7670 return false;
7671 }
7672 return true;
7673}
David Ng38e2d232013-03-15 20:05:58 -07007674#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007675#ifdef USE_ION
7676int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7677 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7678 struct ion_fd_data *fd_data, int flag)
7679{
7680 int fd = -EINVAL;
7681 int rc = -EINVAL;
7682 int ion_dev_flag;
7683 struct vdec_ion ion_buf_info;
7684 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7685 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7686 return -EINVAL;
7687 }
Arun Menon737de532012-09-14 14:48:18 -07007688 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007689 fd = open (MEM_DEVICE, ion_dev_flag);
7690 if (fd < 0) {
7691 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7692 return fd;
7693 }
Arun Menon737de532012-09-14 14:48:18 -07007694 alloc_data->flags = 0;
7695 if(!secure_mode && (flag & ION_FLAG_CACHED))
7696 {
7697 alloc_data->flags |= ION_FLAG_CACHED;
7698 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007699 alloc_data->len = buffer_size;
7700 alloc_data->align = clip2(alignment);
7701 if (alloc_data->align < 4096)
7702 {
7703 alloc_data->align = 4096;
7704 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007705 if ((secure_mode) && (flag & ION_SECURE))
7706 alloc_data->flags |= ION_SECURE;
7707
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007708 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7709 if (secure_mode)
7710 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007711 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7712 if (rc || !alloc_data->handle) {
7713 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7714 alloc_data->handle = NULL;
7715 close(fd);
7716 fd = -ENOMEM;
7717 return fd;
7718 }
7719 fd_data->handle = alloc_data->handle;
7720 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7721 if (rc) {
7722 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7723 ion_buf_info.ion_alloc_data = *alloc_data;
7724 ion_buf_info.ion_device_fd = fd;
7725 ion_buf_info.fd_ion_data = *fd_data;
7726 free_ion_memory(&ion_buf_info);
7727 fd_data->fd =-1;
7728 close(fd);
7729 fd = -ENOMEM;
7730 }
7731
7732 return fd;
7733}
7734
7735void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7736
7737 if(!buf_ion_info) {
7738 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7739 return;
7740 }
7741 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7742 &buf_ion_info->ion_alloc_data.handle)) {
7743 DEBUG_PRINT_ERROR("\n ION: free failed" );
7744 }
7745 close(buf_ion_info->ion_device_fd);
7746 buf_ion_info->ion_device_fd = -1;
7747 buf_ion_info->ion_alloc_data.handle = NULL;
7748 buf_ion_info->fd_ion_data.fd = -1;
7749}
7750#endif
7751void omx_vdec::free_output_buffer_header()
7752{
7753 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7754 output_use_buffer = false;
7755 ouput_egl_buffers = false;
7756
7757 if (m_out_mem_ptr)
7758 {
7759 free (m_out_mem_ptr);
7760 m_out_mem_ptr = NULL;
7761 }
7762
7763 if(m_platform_list)
7764 {
7765 free(m_platform_list);
7766 m_platform_list = NULL;
7767 }
7768
7769 if (drv_ctx.ptr_respbuffer)
7770 {
7771 free (drv_ctx.ptr_respbuffer);
7772 drv_ctx.ptr_respbuffer = NULL;
7773 }
7774 if (drv_ctx.ptr_outputbuffer)
7775 {
7776 free (drv_ctx.ptr_outputbuffer);
7777 drv_ctx.ptr_outputbuffer = NULL;
7778 }
7779#ifdef USE_ION
7780 if (drv_ctx.op_buf_ion_info) {
7781 DEBUG_PRINT_LOW("\n Free o/p ion context");
7782 free(drv_ctx.op_buf_ion_info);
7783 drv_ctx.op_buf_ion_info = NULL;
7784 }
7785#endif
7786}
7787
7788void omx_vdec::free_input_buffer_header()
7789{
7790 input_use_buffer = false;
7791 if (arbitrary_bytes)
7792 {
7793 if (m_frame_parser.mutils)
7794 {
7795 DEBUG_PRINT_LOW("\n Free utils parser");
7796 delete (m_frame_parser.mutils);
7797 m_frame_parser.mutils = NULL;
7798 }
7799
7800 if (m_inp_heap_ptr)
7801 {
7802 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7803 free (m_inp_heap_ptr);
7804 m_inp_heap_ptr = NULL;
7805 }
7806
7807 if (m_phdr_pmem_ptr)
7808 {
7809 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7810 free (m_phdr_pmem_ptr);
7811 m_phdr_pmem_ptr = NULL;
7812 }
7813 }
7814 if (m_inp_mem_ptr)
7815 {
7816 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7817 free (m_inp_mem_ptr);
7818 m_inp_mem_ptr = NULL;
7819 }
7820 if (drv_ctx.ptr_inputbuffer)
7821 {
7822 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7823 free (drv_ctx.ptr_inputbuffer);
7824 drv_ctx.ptr_inputbuffer = NULL;
7825 }
7826#ifdef USE_ION
7827 if (drv_ctx.ip_buf_ion_info) {
7828 DEBUG_PRINT_LOW("\n Free ion context");
7829 free(drv_ctx.ip_buf_ion_info);
7830 drv_ctx.ip_buf_ion_info = NULL;
7831 }
7832#endif
7833}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007834
7835int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007836{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007837 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007838 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007839 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007840
7841 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7842 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7843 v4l2_port = OUTPUT_PORT;
7844 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7845 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7846 v4l2_port = CAPTURE_PORT;
7847 } else if (port == OMX_ALL) {
7848 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7849 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7850
7851 if (!rc_input)
7852 return rc_input;
7853 else
7854 return rc_output;
7855 }
7856
7857 if (!streaming[v4l2_port]) {
7858 // already streamed off, warn and move on
7859 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7860 " which is already streamed off", v4l2_port);
7861 return 0;
7862 }
7863
7864 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7865
Shalaj Jain273b3e02012-06-22 19:08:03 -07007866 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7867 if (rc) {
7868 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007869 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007870 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007871 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007872 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007873
7874 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007875}
7876
7877OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7878{
7879 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7880 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007881 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007882 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007883 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007884 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7885 buffer_prop->actualcount, buffer_prop->buffer_size);
7886 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007887 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007888 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7889 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7890 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7891 fmt.fmt.pix_mp.pixelformat = output_capability;
7892 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7893 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7894 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7895 fmt.fmt.pix_mp.pixelformat = capture_capability;
7896 }else {eRet = OMX_ErrorBadParameter;}
7897 if(eRet==OMX_ErrorNone){
7898 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7899 }
7900 if(ret)
7901 {
7902 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7903 /*TODO: How to handle this case */
7904 eRet = OMX_ErrorInsufficientResources;
7905 return eRet;
7906 }
7907 else
7908 {
7909 buffer_prop->actualcount = bufreq.count;
7910 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007911 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007912 }
7913 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7914 buffer_prop->actualcount, buffer_prop->buffer_size);
7915
7916 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7917 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7918
7919 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7920
Vinay Kalia21649b32013-03-18 17:28:07 -07007921 update_resolution(fmt.fmt.pix_mp.width,
7922 fmt.fmt.pix_mp.height,
7923 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7924 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007925 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7926 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007927 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007928
7929 if(ret)
7930 {
7931 /*TODO: How to handle this case */
7932 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7933 eRet = OMX_ErrorInsufficientResources;
7934 }
7935 else
7936 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007937 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08007938
7939 eRet = is_video_session_supported();
7940 if (eRet)
7941 return eRet;
7942
Shalaj Jain273b3e02012-06-22 19:08:03 -07007943 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7944 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007945 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7946 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7947 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7948 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7949 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7950 return OMX_ErrorBadParameter;
7951 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007952 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7953 {
7954 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007955 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956 }
7957 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7958 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007959 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007960 }
7961 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7962 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007963 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7964 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7965 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007966 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007967 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007968 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007969 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007970 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7971 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007972 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7973 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7974 drv_ctx.extradata_info.buffer_size = extra_data_size;
7975 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007976 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7977 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007978 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007979 if (in_reconfig) // BufReq will be set to driver when port is disabled
7980 buffer_prop->buffer_size = buf_size;
7981 else if (buf_size != buffer_prop->buffer_size)
7982 {
7983 buffer_prop->buffer_size = buf_size;
7984 eRet = set_buffer_req(buffer_prop);
7985 }
7986 }
7987 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7988 buffer_prop->actualcount, buffer_prop->buffer_size);
7989 return eRet;
7990}
7991
7992OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7993{
7994 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7995 unsigned buf_size = 0;
7996 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007997 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998 int ret;
7999 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8000 buffer_prop->actualcount, buffer_prop->buffer_size);
8001 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8002 if (buf_size != buffer_prop->buffer_size)
8003 {
8004 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8005 buffer_prop->buffer_size, buf_size);
8006 eRet = OMX_ErrorBadParameter;
8007 }
8008 else
8009 {
8010 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8011 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008012
8013 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8014 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8015 fmt.fmt.pix_mp.pixelformat = output_capability;
8016 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8017 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8018 fmt.fmt.pix_mp.pixelformat = capture_capability;
8019 } else {eRet = OMX_ErrorBadParameter;}
8020
8021 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8022 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008023 {
8024 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008025 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008026 eRet = OMX_ErrorInsufficientResources;
8027 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008028
8029 bufreq.memory = V4L2_MEMORY_USERPTR;
8030 bufreq.count = buffer_prop->actualcount;
8031 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8032 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8033 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8034 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8035 } else {eRet = OMX_ErrorBadParameter;}
8036
8037 if (eRet==OMX_ErrorNone) {
8038 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8039 }
8040
8041 if (ret)
8042 {
8043 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8044 /*TODO: How to handle this case */
8045 eRet = OMX_ErrorInsufficientResources;
8046 } else if (bufreq.count < buffer_prop->actualcount) {
8047 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8048 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8049 buffer_prop->actualcount, bufreq.count);
8050 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008051 } else {
8052 if (!client_buffers.update_buffer_req()) {
8053 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8054 eRet = OMX_ErrorInsufficientResources;
8055 }
8056 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008057 }
8058 return eRet;
8059}
8060
Shalaj Jain273b3e02012-06-22 19:08:03 -07008061OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8062{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008063 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008064 return eRet;
8065}
8066
8067OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8068{
8069 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8070 if (!portDefn)
8071 {
8072 return OMX_ErrorBadParameter;
8073 }
8074 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8075 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8076 portDefn->nSize = sizeof(portDefn);
8077 portDefn->eDomain = OMX_PortDomainVideo;
8078 if (drv_ctx.frame_rate.fps_denominator > 0)
8079 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8080 drv_ctx.frame_rate.fps_denominator;
8081 else {
8082 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8083 return OMX_ErrorBadParameter;
8084 }
8085 if (0 == portDefn->nPortIndex)
8086 {
8087 portDefn->eDir = OMX_DirInput;
8088 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8089 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8090 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8091 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8092 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8093 portDefn->bEnabled = m_inp_bEnabled;
8094 portDefn->bPopulated = m_inp_bPopulated;
8095 }
8096 else if (1 == portDefn->nPortIndex)
8097 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008098 unsigned int buf_size = 0;
8099 if (!client_buffers.update_buffer_req()) {
8100 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8101 return OMX_ErrorHardware;
8102 }
8103 if (!client_buffers.get_buffer_req(buf_size)) {
8104 DEBUG_PRINT_ERROR("\n update buffer requirements");
8105 return OMX_ErrorHardware;
8106 }
8107 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008108 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008109 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8110 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008111 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8112 portDefn->bEnabled = m_out_bEnabled;
8113 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008114 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8115 DEBUG_PRINT_ERROR("\n Error in getting color format");
8116 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008117 }
8118 }
8119 else
8120 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008121 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008122 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8123 (int)portDefn->nPortIndex);
8124 eRet = OMX_ErrorBadPortIndex;
8125 }
8126 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8127 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8128 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8129 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008130 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8131 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008132 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008133 portDefn->format.video.nStride,
8134 portDefn->format.video.nSliceHeight);
8135 return eRet;
8136
8137}
8138
8139OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8140{
8141 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8142 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8143 unsigned i= 0;
8144
8145 if(!m_out_mem_ptr) {
8146 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8147 int nBufHdrSize = 0;
8148 int nPlatformEntrySize = 0;
8149 int nPlatformListSize = 0;
8150 int nPMEMInfoSize = 0;
8151 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8152 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8153 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8154
8155 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8156 drv_ctx.op_buf.actualcount);
8157 nBufHdrSize = drv_ctx.op_buf.actualcount *
8158 sizeof(OMX_BUFFERHEADERTYPE);
8159
8160 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8161 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8162 nPlatformListSize = drv_ctx.op_buf.actualcount *
8163 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8164 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8165 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8166
8167 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8168 sizeof(OMX_BUFFERHEADERTYPE),
8169 nPMEMInfoSize,
8170 nPlatformListSize);
8171 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8172 m_out_bm_count);
8173 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8174 // Alloc mem for platform specific info
8175 char *pPtr=NULL;
8176 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8177 nPMEMInfoSize,1);
8178 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8179 calloc (sizeof(struct vdec_bufferpayload),
8180 drv_ctx.op_buf.actualcount);
8181 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8182 calloc (sizeof (struct vdec_output_frameinfo),
8183 drv_ctx.op_buf.actualcount);
8184#ifdef USE_ION
8185 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8186 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8187#endif
8188
8189 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8190 && drv_ctx.ptr_respbuffer)
8191 {
8192 bufHdr = m_out_mem_ptr;
8193 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8194 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8195 (((char *) m_platform_list) + nPlatformListSize);
8196 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8197 (((char *) m_platform_entry) + nPlatformEntrySize);
8198 pPlatformList = m_platform_list;
8199 pPlatformEntry = m_platform_entry;
8200 pPMEMInfo = m_pmem_info;
8201
8202 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8203
8204 // Settting the entire storage nicely
8205 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8206 m_out_mem_ptr,pPlatformEntry);
8207 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8208 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8209 {
8210 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8211 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8212 // Set the values when we determine the right HxW param
8213 bufHdr->nAllocLen = 0;
8214 bufHdr->nFilledLen = 0;
8215 bufHdr->pAppPrivate = NULL;
8216 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8217 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8218 pPlatformEntry->entry = pPMEMInfo;
8219 // Initialize the Platform List
8220 pPlatformList->nEntries = 1;
8221 pPlatformList->entryList = pPlatformEntry;
8222 // Keep pBuffer NULL till vdec is opened
8223 bufHdr->pBuffer = NULL;
8224 pPMEMInfo->offset = 0;
8225 pPMEMInfo->pmem_fd = 0;
8226 bufHdr->pPlatformPrivate = pPlatformList;
8227 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8228#ifdef USE_ION
8229 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8230#endif
8231 /*Create a mapping between buffers*/
8232 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8233 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8234 &drv_ctx.ptr_outputbuffer[i];
8235 // Move the buffer and buffer header pointers
8236 bufHdr++;
8237 pPMEMInfo++;
8238 pPlatformEntry++;
8239 pPlatformList++;
8240 }
8241 }
8242 else
8243 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008244 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008245 m_out_mem_ptr, pPtr);
8246 if(m_out_mem_ptr)
8247 {
8248 free(m_out_mem_ptr);
8249 m_out_mem_ptr = NULL;
8250 }
8251 if(pPtr)
8252 {
8253 free(pPtr);
8254 pPtr = NULL;
8255 }
8256 if(drv_ctx.ptr_outputbuffer)
8257 {
8258 free(drv_ctx.ptr_outputbuffer);
8259 drv_ctx.ptr_outputbuffer = NULL;
8260 }
8261 if(drv_ctx.ptr_respbuffer)
8262 {
8263 free(drv_ctx.ptr_respbuffer);
8264 drv_ctx.ptr_respbuffer = NULL;
8265 }
8266#ifdef USE_ION
8267 if (drv_ctx.op_buf_ion_info) {
8268 DEBUG_PRINT_LOW("\n Free o/p ion context");
8269 free(drv_ctx.op_buf_ion_info);
8270 drv_ctx.op_buf_ion_info = NULL;
8271 }
8272#endif
8273 eRet = OMX_ErrorInsufficientResources;
8274 }
8275 } else {
8276 eRet = OMX_ErrorInsufficientResources;
8277 }
8278 return eRet;
8279}
8280
8281void omx_vdec::complete_pending_buffer_done_cbs()
8282{
8283 unsigned p1;
8284 unsigned p2;
8285 unsigned ident;
8286 omx_cmd_queue tmp_q, pending_bd_q;
8287 pthread_mutex_lock(&m_lock);
8288 // pop all pending GENERATE FDB from ftb queue
8289 while (m_ftb_q.m_size)
8290 {
8291 m_ftb_q.pop_entry(&p1,&p2,&ident);
8292 if(ident == OMX_COMPONENT_GENERATE_FBD)
8293 {
8294 pending_bd_q.insert_entry(p1,p2,ident);
8295 }
8296 else
8297 {
8298 tmp_q.insert_entry(p1,p2,ident);
8299 }
8300 }
8301 //return all non GENERATE FDB to ftb queue
8302 while(tmp_q.m_size)
8303 {
8304 tmp_q.pop_entry(&p1,&p2,&ident);
8305 m_ftb_q.insert_entry(p1,p2,ident);
8306 }
8307 // pop all pending GENERATE EDB from etb queue
8308 while (m_etb_q.m_size)
8309 {
8310 m_etb_q.pop_entry(&p1,&p2,&ident);
8311 if(ident == OMX_COMPONENT_GENERATE_EBD)
8312 {
8313 pending_bd_q.insert_entry(p1,p2,ident);
8314 }
8315 else
8316 {
8317 tmp_q.insert_entry(p1,p2,ident);
8318 }
8319 }
8320 //return all non GENERATE FDB to etb queue
8321 while(tmp_q.m_size)
8322 {
8323 tmp_q.pop_entry(&p1,&p2,&ident);
8324 m_etb_q.insert_entry(p1,p2,ident);
8325 }
8326 pthread_mutex_unlock(&m_lock);
8327 // process all pending buffer dones
8328 while(pending_bd_q.m_size)
8329 {
8330 pending_bd_q.pop_entry(&p1,&p2,&ident);
8331 switch(ident)
8332 {
8333 case OMX_COMPONENT_GENERATE_EBD:
8334 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8335 {
8336 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8337 omx_report_error ();
8338 }
8339 break;
8340
8341 case OMX_COMPONENT_GENERATE_FBD:
8342 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8343 {
8344 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8345 omx_report_error ();
8346 }
8347 break;
8348 }
8349 }
8350}
8351
8352void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8353{
8354 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008355 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8356 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8357 {
8358 new_frame_interval = (act_timestamp > prev_ts)?
8359 act_timestamp - prev_ts :
8360 prev_ts - act_timestamp;
8361 if (new_frame_interval < frm_int || frm_int == 0)
8362 {
8363 frm_int = new_frame_interval;
8364 if(frm_int)
8365 {
8366 drv_ctx.frame_rate.fps_numerator = 1e6;
8367 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008368 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008369 frm_int, drv_ctx.frame_rate.fps_numerator /
8370 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07008371 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008372 }
8373 }
8374 }
8375 prev_ts = act_timestamp;
8376}
8377
8378void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8379{
8380 if (rst_prev_ts && VALID_TS(act_timestamp))
8381 {
8382 prev_ts = act_timestamp;
8383 rst_prev_ts = false;
8384 }
8385 else if (VALID_TS(prev_ts))
8386 {
8387 bool codec_cond = (drv_ctx.timestamp_adjust)?
8388 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8389 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8390 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8391 if(frm_int > 0 && codec_cond)
8392 {
8393 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8394 act_timestamp = prev_ts + frm_int;
8395 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8396 prev_ts = act_timestamp;
8397 }
8398 else
8399 set_frame_rate(act_timestamp);
8400 }
8401 else if (frm_int > 0) // In this case the frame rate was set along
8402 { // with the port definition, start ts with 0
8403 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8404 rst_prev_ts = true;
8405 }
8406}
8407
8408void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8409{
8410 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8411 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008412 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008413 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008414 OMX_U32 num_MB_in_frame;
8415 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008416 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008417 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008418 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8419 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008420 if (!drv_ctx.extradata_info.uaddr) {
8421 return;
8422 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008423 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008424 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8425 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8426 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008427 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008428 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008429 if (data) {
8430 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008431 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008432 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008433 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008434 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008435 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008436 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008437 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008438 struct msm_vidc_interlace_payload *payload;
8439 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008440 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8441 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008442 OMX_U32 mbaff = 0;
8443 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8444 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8445 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8446 else
8447 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8448 if(m_enable_android_native_buffers)
8449 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008450 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008451 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008452 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8453 append_interlace_extradata(p_extra, payload->format);
8454 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8455 }
8456 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008457 case EXTRADATA_FRAME_RATE:
8458 struct msm_vidc_framerate_payload *frame_rate_payload;
8459 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8460 frame_rate = frame_rate_payload->frame_rate;
8461 break;
8462 case EXTRADATA_TIMESTAMP:
8463 struct msm_vidc_ts_payload *time_stamp_payload;
8464 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008465 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008466 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008467 break;
8468 case EXTRADATA_NUM_CONCEALED_MB:
8469 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8470 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8471 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8472 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8473 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8474 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008475 case EXTRADATA_ASPECT_RATIO:
8476 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8477 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8478 ((struct vdec_output_frameinfo *)
8479 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8480 ((struct vdec_output_frameinfo *)
8481 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8482 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008483 case EXTRADATA_RECOVERY_POINT_SEI:
8484 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8485 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8486 recovery_sei_flags = recovery_sei_payload->flags;
8487 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8488 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008489 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008490 }
8491 break;
8492 case EXTRADATA_PANSCAN_WINDOW:
8493 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8494 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008495 default:
8496 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008497 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008498 consumed_len += data->nSize;
8499 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008500 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008501 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008502 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008503 append_frame_info_extradata(p_extra,
8504 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008505 panscan_payload,&((struct vdec_output_frameinfo *)
8506 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008507 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008508unrecognized_extradata:
8509 if(!secure_mode && client_extradata)
8510 append_terminator_extradata(p_extra);
8511 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008512}
8513
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008514OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8515 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008516{
8517 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008518 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008519 if(m_state != OMX_StateLoaded)
8520 {
8521 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8522 return OMX_ErrorIncorrectStateOperation;
8523 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008524 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008525 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008526
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008527 if (!is_internal) {
8528 if (enable)
8529 client_extradata |= requested_extradata;
8530 else
8531 client_extradata = client_extradata & ~requested_extradata;
8532 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008533
8534 if (enable) {
8535 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8536 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8537 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8538 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8539 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8540 " Quality of interlaced clips might be impacted.\n");
8541 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008542 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8543 {
8544 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8545 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8546 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8547 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8548 }
8549 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8550 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8551 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8552 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8553 }
8554 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8555 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8556 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8557 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8558 }
8559 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8560 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8561 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8562 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8563 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008564 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8565 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8566 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8567 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8568 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008569 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8570 {
8571 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8572 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8573 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8574 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8575 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008576 }
8577 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008578 return ret;
8579}
8580
8581OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8582{
8583 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8584 OMX_U8 *data_ptr = extra->data, data = 0;
8585 while (byte_count < extra->nDataSize)
8586 {
8587 data = *data_ptr;
8588 while (data)
8589 {
8590 num_MB += (data&0x01);
8591 data >>= 1;
8592 }
8593 data_ptr++;
8594 byte_count++;
8595 }
8596 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8597 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8598 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8599}
8600
8601void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8602{
8603 if (!m_debug_extradata)
8604 return;
8605
8606 DEBUG_PRINT_HIGH(
8607 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008608 " Size: %lu \n"
8609 " Version: %lu \n"
8610 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008611 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008612 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008613 extra->nSize, extra->nVersion.nVersion,
8614 extra->nPortIndex, extra->eType, extra->nDataSize);
8615
Shalaj Jain286b0062013-02-21 20:35:48 -08008616 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008617 {
8618 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8619 DEBUG_PRINT_HIGH(
8620 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008621 " Size: %lu \n"
8622 " Version: %lu \n"
8623 " PortIndex: %lu \n"
8624 " Is Interlace Format: %d \n"
8625 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008626 "=========== End of Interlace ===========\n",
8627 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8628 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8629 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008630 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008631 {
8632 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8633
8634 DEBUG_PRINT_HIGH(
8635 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008636 " Picture Type: %d \n"
8637 " Interlace Type: %d \n"
8638 " Pan Scan Total Frame Num: %lu \n"
8639 " Concealed Macro Blocks: %lu \n"
8640 " frame rate: %lu \n"
8641 " Aspect Ratio X: %lu \n"
8642 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008643 fminfo->ePicType,
8644 fminfo->interlaceType,
8645 fminfo->panScan.numWindows,
8646 fminfo->nConcealedMacroblocks,
8647 fminfo->nFrameRate,
8648 fminfo->aspectRatio.aspectRatioX,
8649 fminfo->aspectRatio.aspectRatioY);
8650
Praneeth Paladugu32284302013-02-14 22:53:06 -08008651 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008652 {
8653 DEBUG_PRINT_HIGH(
8654 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008655 " Pan Scan Frame Num: %lu \n"
8656 " Rectangle x: %ld \n"
8657 " Rectangle y: %ld \n"
8658 " Rectangle dx: %ld \n"
8659 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008660 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8661 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8662 }
8663
8664 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8665 }
8666 else if (extra->eType == OMX_ExtraDataNone)
8667 {
8668 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8669 }
8670 else
8671 {
8672 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8673 }
8674}
8675
8676void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8677 OMX_U32 interlaced_format_type)
8678{
8679 OMX_STREAMINTERLACEFORMAT *interlace_format;
8680 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008681 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8682 return;
8683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008684 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8685 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8686 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8687 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8688 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8689 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8690 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8691 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8692 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8693 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008694 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008695 {
8696 interlace_format->bInterlaceFormat = OMX_FALSE;
8697 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8698 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8699 }
8700 else
8701 {
8702 interlace_format->bInterlaceFormat = OMX_TRUE;
8703 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8704 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8705 }
8706 print_debug_extradata(extra);
8707}
8708
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008709void omx_vdec::fill_aspect_ratio_info(
8710 struct vdec_aspectratioinfo *aspect_ratio_info,
8711 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8712{
8713 m_extradata = frame_info;
8714 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8715 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008716 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008717 m_extradata->aspectRatio.aspectRatioY);
8718}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008719
8720void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008721 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008722 struct msm_vidc_panscan_window_payload *panscan_payload,
8723 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008724{
8725 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008726 struct msm_vidc_panscan_window *panscan_window;
8727 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8728 return;
8729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008730 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8731 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8732 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8733 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8734 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8735 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8736 switch (picture_type)
8737 {
8738 case PICTURE_TYPE_I:
8739 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8740 break;
8741 case PICTURE_TYPE_P:
8742 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8743 break;
8744 case PICTURE_TYPE_B:
8745 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8746 break;
8747 default:
8748 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8749 }
8750 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8751 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8752 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8753 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8754 else
8755 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008756 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008757 frame_info->nConcealedMacroblocks = num_conceal_mb;
8758 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008759 frame_info->panScan.numWindows = 0;
8760 if(panscan_payload) {
8761 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8762 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008763 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008764 {
8765 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8766 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8767 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8768 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8769 panscan_window++;
8770 }
8771 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008772 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008773 print_debug_extradata(extra);
8774}
8775
8776void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8777{
8778 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8779 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8780 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8781 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8782 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8783 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8784 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8785 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008786 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8787 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008788 portDefn->format.video.nFrameWidth,
8789 portDefn->format.video.nStride,
8790 portDefn->format.video.nSliceHeight);
8791}
8792
8793void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8794{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008795 if (!client_extradata) {
8796 return;
8797 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008798 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8799 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8800 extra->eType = OMX_ExtraDataNone;
8801 extra->nDataSize = 0;
8802 extra->data[0] = 0;
8803
8804 print_debug_extradata(extra);
8805}
8806
8807OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8808{
8809 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8810 if (index >= drv_ctx.ip_buf.actualcount)
8811 {
8812 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8813 return OMX_ErrorInsufficientResources;
8814 }
8815 if (m_desc_buffer_ptr == NULL)
8816 {
8817 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8818 calloc( (sizeof(desc_buffer_hdr)),
8819 drv_ctx.ip_buf.actualcount);
8820 if (m_desc_buffer_ptr == NULL)
8821 {
8822 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8823 return OMX_ErrorInsufficientResources;
8824 }
8825 }
8826
8827 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8828 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8829 {
8830 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8831 return OMX_ErrorInsufficientResources;
8832 }
8833
8834 return eRet;
8835}
8836
8837void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8838{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008839 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008840 if (m_demux_entries < 8192)
8841 {
8842 m_demux_offsets[m_demux_entries++] = address_offset;
8843 }
8844 return;
8845}
8846
8847void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8848{
8849 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8850 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8851 OMX_U32 index = 0;
8852
8853 m_demux_entries = 0;
8854
8855 while (index < bytes_to_parse)
8856 {
8857 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8858 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8859 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8860 (buf[index+2] == 0x01)) )
8861 {
8862 //Found start code, insert address offset
8863 insert_demux_addr_offset(index);
8864 if (buf[index+2] == 0x01) // 3 byte start code
8865 index += 3;
8866 else //4 byte start code
8867 index += 4;
8868 }
8869 else
8870 index++;
8871 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008872 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008873 return;
8874}
8875
8876OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8877{
8878 //fix this, handle 3 byte start code, vc1 terminator entry
8879 OMX_U8 *p_demux_data = NULL;
8880 OMX_U32 desc_data = 0;
8881 OMX_U32 start_addr = 0;
8882 OMX_U32 nal_size = 0;
8883 OMX_U32 suffix_byte = 0;
8884 OMX_U32 demux_index = 0;
8885 OMX_U32 buffer_index = 0;
8886
8887 if (m_desc_buffer_ptr == NULL)
8888 {
8889 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8890 return OMX_ErrorBadParameter;
8891 }
8892
8893 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8894 if (buffer_index > drv_ctx.ip_buf.actualcount)
8895 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008896 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008897 return OMX_ErrorBadParameter;
8898 }
8899
8900 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8901
8902 if ( ((OMX_U8*)p_demux_data == NULL) ||
8903 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8904 {
8905 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8906 return OMX_ErrorBadParameter;
8907 }
8908 else
8909 {
8910 for (; demux_index < m_demux_entries; demux_index++)
8911 {
8912 desc_data = 0;
8913 start_addr = m_demux_offsets[demux_index];
8914 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8915 {
8916 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8917 }
8918 else
8919 {
8920 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8921 }
8922 if (demux_index < (m_demux_entries - 1))
8923 {
8924 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8925 }
8926 else
8927 {
8928 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8929 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008930 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8931 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008932 suffix_byte,
8933 nal_size,
8934 demux_index);
8935 desc_data = (start_addr >> 3) << 1;
8936 desc_data |= (start_addr & 7) << 21;
8937 desc_data |= suffix_byte << 24;
8938
8939 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8940 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8941 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8942 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8943
8944 p_demux_data += 16;
8945 }
8946 if (codec_type_parse == CODEC_TYPE_VC1)
8947 {
8948 DEBUG_PRINT_LOW("VC1 terminator entry");
8949 desc_data = 0;
8950 desc_data = 0x82 << 24;
8951 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8952 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8953 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8954 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8955 p_demux_data += 16;
8956 m_demux_entries++;
8957 }
8958 //Add zero word to indicate end of descriptors
8959 memset(p_demux_data, 0, sizeof(OMX_U32));
8960
8961 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008962 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008963 }
8964 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8965 m_demux_entries = 0;
8966 DEBUG_PRINT_LOW("Demux table complete!");
8967 return OMX_ErrorNone;
8968}
8969
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008970OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008971{
8972 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008973 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008974 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008975 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8976 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008977 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008978 delete iDivXDrmDecrypt;
8979 iDivXDrmDecrypt = NULL;
8980 }
8981 }
8982 else {
8983 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008984 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008985 }
8986 return err;
8987}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008988
Vinay Kaliada4f4422013-01-09 10:45:03 -08008989omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8990{
8991 enabled = false;
8992 omx = NULL;
8993 init_members();
8994 ColorFormat = OMX_COLOR_FormatMax;
8995}
8996
8997void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8998{
8999 omx = reinterpret_cast<omx_vdec*>(client);
9000}
9001
9002void omx_vdec::allocate_color_convert_buf::init_members() {
9003 allocated_count = 0;
9004 buffer_size_req = 0;
9005 buffer_alignment_req = 0;
9006 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9007 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9008 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9009 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9010#ifdef USE_ION
9011 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9012#endif
9013 for (int i = 0; i < MAX_COUNT;i++)
9014 pmem_fd[i] = -1;
9015}
9016
9017omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
9018 c2d.destroy();
9019}
9020
9021bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9022{
9023 bool status = true;
9024 unsigned int src_size = 0, destination_size = 0;
9025 OMX_COLOR_FORMATTYPE drv_color_format;
9026 if (!omx){
9027 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9028 return false;
9029 }
9030 if (!enabled){
9031 DEBUG_PRINT_ERROR("\n No color conversion required");
9032 return status;
9033 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009034 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009035 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9036 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9037 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009038 status = false;
9039 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009040 }
9041 c2d.close();
9042 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9043 omx->drv_ctx.video_resolution.frame_width,
9044 NV12_128m,YCbCr420P);
9045 if (status) {
9046 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9047 if (status)
9048 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9049 }
9050 if (status) {
9051 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9052 !destination_size) {
9053 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9054 "driver size %d destination size %d",
9055 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9056 status = false;
9057 c2d.close();
9058 buffer_size_req = 0;
9059 } else {
9060 buffer_size_req = destination_size;
9061 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9062 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9063 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9064 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9065 }
9066 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009067fail_update_buf_req:
9068 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009069 return status;
9070}
9071
9072bool omx_vdec::allocate_color_convert_buf::set_color_format(
9073 OMX_COLOR_FORMATTYPE dest_color_format)
9074{
9075 bool status = true;
9076 OMX_COLOR_FORMATTYPE drv_color_format;
9077 if (!omx){
9078 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9079 return false;
9080 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009081 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009082 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9083 drv_color_format = (OMX_COLOR_FORMATTYPE)
9084 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9085 else {
9086 DEBUG_PRINT_ERROR("\n Incorrect color format");
9087 status = false;
9088 }
9089 if (status && (drv_color_format != dest_color_format)) {
9090 DEBUG_PRINT_LOW("Enabling C2D\n");
9091 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9092 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9093 status = false;
9094 } else {
9095 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9096 if (enabled)
9097 c2d.destroy();
9098 enabled = false;
9099 if (!c2d.init()) {
9100 DEBUG_PRINT_ERROR("\n open failed for c2d");
9101 status = false;
9102 } else
9103 enabled = true;
9104 }
9105 } else {
9106 if (enabled)
9107 c2d.destroy();
9108 enabled = false;
9109 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009110 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009111 return status;
9112}
9113
9114OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9115{
9116 if (!omx){
9117 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9118 return NULL;
9119 }
9120 if (!enabled)
9121 return omx->m_out_mem_ptr;
9122 return m_out_mem_ptr_client;
9123}
9124
9125OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9126 (OMX_BUFFERHEADERTYPE *bufadd)
9127{
9128 if (!omx){
9129 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9130 return NULL;
9131 }
9132 if (!enabled)
9133 return bufadd;
9134
9135 unsigned index = 0;
9136 index = bufadd - omx->m_out_mem_ptr;
9137 if (index < omx->drv_ctx.op_buf.actualcount) {
9138 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9139 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9140 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009141 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009142 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009143 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9144 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009145 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009146 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9147 if (!status){
9148 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009149 m_out_mem_ptr_client[index].nFilledLen = 0;
9150 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009151 }
9152 } else
9153 m_out_mem_ptr_client[index].nFilledLen = 0;
9154 return &m_out_mem_ptr_client[index];
9155 }
9156 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9157 return NULL;
9158}
9159
9160OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9161 (OMX_BUFFERHEADERTYPE *bufadd)
9162{
9163 if (!omx){
9164 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9165 return NULL;
9166 }
9167 if (!enabled)
9168 return bufadd;
9169 unsigned index = 0;
9170 index = bufadd - m_out_mem_ptr_client;
9171 if (index < omx->drv_ctx.op_buf.actualcount) {
9172 return &omx->m_out_mem_ptr[index];
9173 }
9174 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9175 return NULL;
9176}
9177bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9178 (unsigned int &buffer_size)
9179{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009180 bool status = true;
9181 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009182 if (!enabled)
9183 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009184 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009185 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9186 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009187 status = false;
9188 goto fail_get_buffer_size;
9189 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009190 }
9191 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9192 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9193 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9194 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009195fail_get_buffer_size:
9196 pthread_mutex_unlock(&omx->c_lock);
9197 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009198}
9199OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9200 OMX_BUFFERHEADERTYPE *bufhdr) {
9201 unsigned int index = 0;
9202
9203 if (!enabled)
9204 return omx->free_output_buffer(bufhdr);
9205 if (enabled && omx->is_component_secure())
9206 return OMX_ErrorNone;
9207 if (!allocated_count || !bufhdr) {
9208 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9209 return OMX_ErrorBadParameter;
9210 }
9211 index = bufhdr - m_out_mem_ptr_client;
9212 if (index >= omx->drv_ctx.op_buf.actualcount){
9213 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9214 return OMX_ErrorBadParameter;
9215 }
9216 if (pmem_fd[index] > 0) {
9217 munmap(pmem_baseaddress[index], buffer_size_req);
9218 close(pmem_fd[index]);
9219 }
9220 pmem_fd[index] = -1;
9221#ifdef USE_ION
9222 omx->free_ion_memory(&op_buf_ion_info[index]);
9223#endif
9224 m_heap_ptr[index].video_heap_ptr = NULL;
9225 if (allocated_count > 0)
9226 allocated_count--;
9227 else
9228 allocated_count = 0;
9229 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009230 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009231 c2d.close();
9232 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009233 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009234 }
9235 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9236}
9237
9238OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9239 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9240{
9241 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9242 if (!enabled){
9243 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9244 return eRet;
9245 }
9246 if (enabled && omx->is_component_secure()) {
9247 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9248 omx->is_component_secure());
9249 return OMX_ErrorUnsupportedSetting;
9250 }
9251 if (!bufferHdr || bytes > buffer_size_req) {
9252 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009253 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009254 buffer_size_req,bytes);
9255 return OMX_ErrorBadParameter;
9256 }
9257 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9258 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9259 return OMX_ErrorInsufficientResources;
9260 }
9261 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9262 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9263 port,appData,omx->drv_ctx.op_buf.buffer_size);
9264 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9265 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9266 return eRet;
9267 }
9268 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9269 omx->drv_ctx.op_buf.actualcount) {
9270 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9271 (temp_bufferHdr - omx->m_out_mem_ptr));
9272 return OMX_ErrorUndefined;
9273 }
9274 unsigned int i = allocated_count;
9275#ifdef USE_ION
9276 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9277 buffer_size_req,buffer_alignment_req,
9278 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009279 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009280 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9281 if (op_buf_ion_info[i].ion_device_fd < 0) {
9282 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9283 return OMX_ErrorInsufficientResources;
9284 }
9285 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9286 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9287
9288 if (pmem_baseaddress[i] == MAP_FAILED) {
9289 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9290 close(pmem_fd[i]);
9291 omx->free_ion_memory(&op_buf_ion_info[i]);
9292 return OMX_ErrorInsufficientResources;
9293 }
9294 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9295 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9296 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9297#endif
9298 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9299 m_pmem_info_client[i].offset = 0;
9300 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9301 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9302 m_platform_list_client[i].nEntries = 1;
9303 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9304 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9305 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9306 m_out_mem_ptr_client[i].nFilledLen = 0;
9307 m_out_mem_ptr_client[i].nFlags = 0;
9308 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9309 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9310 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9311 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9312 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9313 m_out_mem_ptr_client[i].pAppPrivate = appData;
9314 *bufferHdr = &m_out_mem_ptr_client[i];
9315 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9316 allocated_count++;
9317 return eRet;
9318}
9319
9320bool omx_vdec::is_component_secure()
9321{
9322 return secure_mode;
9323}
9324
9325bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9326{
9327 bool status = true;
9328 if (!enabled) {
9329 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9330 dest_color_format = (OMX_COLOR_FORMATTYPE)
9331 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9332 else
9333 status = false;
9334 } else {
9335 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9336 status = false;
9337 } else
9338 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9339 }
9340 return status;
9341}
Praneeth Paladugu53478562013-03-12 14:49:46 -07009342
9343void omx_vdec::enableAdditionalCores(int frame_interval)
9344{
9345 DEBUG_PRINT_LOW("Setting frame rate to 1/(%dusec)", frame_interval);
9346 if (frame_interval < 33000)
9347 {
9348 DEBUG_PRINT_HIGH("Turning on additional CPU cores");
9349 if (NULL == opt_handle) {
9350 char opt_lib_path[PATH_MAX] = {0};
9351
9352 if (property_get("ro.vendor.extension_library", opt_lib_path, NULL) != 0) {
9353 if ((opt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
9354 DEBUG_PRINT_ERROR("Unable to open %s: %s\n", opt_lib_path, dlerror());
9355 } else {
9356 perf_lock_acq = (int(*)(int, int, int*,int))dlsym(opt_handle, "perf_lock_acq");
9357 if (perf_lock_acq == NULL) {
9358 DEBUG_PRINT_ERROR("failed to get lock_acq sym");
9359 }
9360
9361 perf_lock_rel = (int(*)(int))dlsym(opt_handle, "perf_lock_rel");
9362 if (perf_lock_rel == NULL) {
9363 DEBUG_PRINT_ERROR("failed to get lock_rel sym");
9364 }
9365 }
9366 } else {
9367 DEBUG_PRINT_ERROR("Property ro.vendor.extension_library does not exist.");
9368 }
9369 }
9370
9371 int decode_opts[1] = {0x704}; //value of last nibble == # of cores
9372 if (perf_lock_acq && perf_lock_handle < 0) {
9373 DEBUG_PRINT_LOW("Lock acquired");
9374 perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, decode_opts, 1);
9375 }
9376 }
9377}