blob: 6b1069fd6ae5233c8d83369d93a2555df8498267 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -08002Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080051#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070052
53#ifndef _ANDROID_
54#include <sys/ioctl.h>
55#include <sys/mman.h>
56#endif //_ANDROID_
57
58#ifdef _ANDROID_
59#include <cutils/properties.h>
60#undef USE_EGL_IMAGE_GPU
61#endif
62
63#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
64#include <gralloc_priv.h>
65#endif
66
67#if defined (_ANDROID_ICS_)
68#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070069#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070070#endif
71
72#ifdef _ANDROID_
73#include "DivXDrmDecrypt.h"
74#endif //_ANDROID_
75
76#ifdef USE_EGL_IMAGE_GPU
77#include <EGL/egl.h>
78#include <EGL/eglQCOM.h>
79#define EGL_BUFFER_HANDLE_QCOM 0x4F00
80#define EGL_BUFFER_OFFSET_QCOM 0x4F01
81#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -070082#ifdef INPUT_BUFFER_LOG
83#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
84#define INPUT_BUFFER_FILE_NAME_LEN 30
85FILE *inputBufferFile1;
86char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
87#endif
88#ifdef OUTPUT_BUFFER_LOG
89FILE *outputBufferFile1;
90char outputfilename [] = "/data/output.yuv";
Vinay Kalia21649b32013-03-18 17:28:07 -070091
Shalaj Jain273b3e02012-06-22 19:08:03 -070092#endif
93#ifdef OUTPUT_EXTRADATA_LOG
94FILE *outputExtradataFile;
95char ouputextradatafilename [] = "/data/extradata";
96#endif
97
98#define DEFAULT_FPS 30
99#define MAX_INPUT_ERROR DEFAULT_FPS
100#define MAX_SUPPORTED_FPS 120
101
102#define VC1_SP_MP_START_CODE 0xC5000000
103#define VC1_SP_MP_START_CODE_MASK 0xFF000000
104#define VC1_AP_SEQ_START_CODE 0x0F010000
105#define VC1_STRUCT_C_PROFILE_MASK 0xF0
106#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
107#define VC1_SIMPLE_PROFILE 0
108#define VC1_MAIN_PROFILE 1
109#define VC1_ADVANCE_PROFILE 3
110#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
111#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
112#define VC1_STRUCT_C_LEN 4
113#define VC1_STRUCT_C_POS 8
114#define VC1_STRUCT_A_POS 12
115#define VC1_STRUCT_B_POS 24
116#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700117#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700118
119#define MEM_DEVICE "/dev/ion"
120#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
121
122#ifdef _ANDROID_
123 extern "C"{
124 #include<utils/Log.h>
125 }
126#endif//_ANDROID_
127
Vinay Kalia53fa6832012-10-11 17:55:30 -0700128#define SZ_4K 0x1000
129#define SZ_1M 0x100000
130
Shalaj Jain273b3e02012-06-22 19:08:03 -0700131#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
132#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700133#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
134
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800135#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700136void* async_message_thread (void *input)
137{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
Praneeth Paladugu32284302013-02-14 22:53:06 -0800141 struct v4l2_buffer v4l2_buf;
142 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700143 struct v4l2_event dqevent;
144 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
145 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
146 pfd.fd = omx->drv_ctx.video_driver_fd;
147 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
148 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
149 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
150 while (1)
151 {
152 rc = poll(&pfd, 1, POLL_TIMEOUT);
153 if (!rc) {
154 DEBUG_PRINT_ERROR("Poll timedout\n");
155 break;
156 } else if (rc < 0) {
157 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
158 break;
159 }
160 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
161 struct vdec_msginfo vdec_msg;
162 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
163 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
164 v4l2_buf.length = omx->drv_ctx.num_planes;
165 v4l2_buf.m.planes = plane;
166 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
167 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
168 vdec_msg.status_code=VDEC_S_SUCCESS;
169 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
170 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
171 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
Eric (Quicee1674a2012-12-21 15:29:08 -0800172 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
173 (uint64_t)v4l2_buf.timestamp.tv_usec;
Vinay Kalia592e4b42012-12-19 15:55:47 -0800174 if (vdec_msg.msgdata.output_frame.len) {
175 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
176 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
177 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
178 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
179 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700180 if (omx->async_message_process(input,&vdec_msg) < 0) {
181 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
182 break;
183 }
184 }
185 }
186 if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
187 struct vdec_msginfo vdec_msg;
188 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
189 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
190 v4l2_buf.length = 1;
191 v4l2_buf.m.planes = plane;
192 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
193 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
194 vdec_msg.status_code=VDEC_S_SUCCESS;
195 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
196 if (omx->async_message_process(input,&vdec_msg) < 0) {
197 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
198 break;
199 }
200 }
201 }
202 if (pfd.revents & POLLPRI){
203 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700204 if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700205 struct vdec_msginfo vdec_msg;
206 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
207 vdec_msg.status_code=VDEC_S_SUCCESS;
Vinay Kaliab9e98102013-04-02 19:31:43 -0700208 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700209 if (omx->async_message_process(input,&vdec_msg) < 0) {
210 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
211 break;
212 }
213 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
214 struct vdec_msginfo vdec_msg;
215 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
216 vdec_msg.status_code=VDEC_S_SUCCESS;
217 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
218 if (omx->async_message_process(input,&vdec_msg) < 0) {
219 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
220 break;
221 }
222 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
223 vdec_msg.status_code=VDEC_S_SUCCESS;
224 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
225 if (omx->async_message_process(input,&vdec_msg) < 0) {
226 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
227 break;
228 }
229 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
230 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
231 break;
232 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
233 struct vdec_msginfo vdec_msg;
234 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
235 vdec_msg.status_code=VDEC_S_SUCCESS;
236 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
237 if (omx->async_message_process(input,&vdec_msg) < 0) {
238 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
239 break;
240 }
241 } else {
242 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
243 continue;
244 }
245 }
246 }
247 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
248 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700249}
250
251void* message_thread(void *input)
252{
253 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
254 unsigned char id;
255 int n;
256
257 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
258 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
259 while (1)
260 {
261
262 n = read(omx->m_pipe_in, &id, 1);
263
264 if(0 == n)
265 {
266 break;
267 }
268
269 if (1 == n)
270 {
271 omx->process_event_cb(omx, id);
272 }
273 if ((n < 0) && (errno != EINTR))
274 {
275 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
276 break;
277 }
278 }
279 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
280 return 0;
281}
282
283void post_message(omx_vdec *omx, unsigned char id)
284{
285 int ret_value;
286 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
287 ret_value = write(omx->m_pipe_out, &id, 1);
288 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
289}
290
291// omx_cmd_queue destructor
292omx_vdec::omx_cmd_queue::~omx_cmd_queue()
293{
294 // Nothing to do
295}
296
297// omx cmd queue constructor
298omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
299{
300 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
301}
302
303// omx cmd queue insert
304bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
305{
306 bool ret = true;
307 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
308 {
309 m_q[m_write].id = id;
310 m_q[m_write].param1 = p1;
311 m_q[m_write].param2 = p2;
312 m_write++;
313 m_size ++;
314 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
315 {
316 m_write = 0;
317 }
318 }
319 else
320 {
321 ret = false;
322 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
323 }
324 return ret;
325}
326
327// omx cmd queue pop
328bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
329{
330 bool ret = true;
331 if (m_size > 0)
332 {
333 *id = m_q[m_read].id;
334 *p1 = m_q[m_read].param1;
335 *p2 = m_q[m_read].param2;
336 // Move the read pointer ahead
337 ++m_read;
338 --m_size;
339 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
340 {
341 m_read = 0;
342 }
343 }
344 else
345 {
346 ret = false;
347 }
348 return ret;
349}
350
351// Retrieve the first mesg type in the queue
352unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
353{
354 return m_q[m_read].id;
355}
356
357#ifdef _ANDROID_
358omx_vdec::ts_arr_list::ts_arr_list()
359{
360 //initialize timestamps array
361 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
362}
363omx_vdec::ts_arr_list::~ts_arr_list()
364{
365 //free m_ts_arr_list?
366}
367
368bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
369{
370 bool ret = true;
371 bool duplicate_ts = false;
372 int idx = 0;
373
374 //insert at the first available empty location
375 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
376 {
377 if (!m_ts_arr_list[idx].valid)
378 {
379 //found invalid or empty entry, save timestamp
380 m_ts_arr_list[idx].valid = true;
381 m_ts_arr_list[idx].timestamp = ts;
382 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
383 ts, idx);
384 break;
385 }
386 }
387
388 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
389 {
390 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
391 ret = false;
392 }
393 return ret;
394}
395
396bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
397{
398 bool ret = true;
399 int min_idx = -1;
400 OMX_TICKS min_ts = 0;
401 int idx = 0;
402
403 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
404 {
405
406 if (m_ts_arr_list[idx].valid)
407 {
408 //found valid entry, save index
409 if (min_idx < 0)
410 {
411 //first valid entry
412 min_ts = m_ts_arr_list[idx].timestamp;
413 min_idx = idx;
414 }
415 else if (m_ts_arr_list[idx].timestamp < min_ts)
416 {
417 min_ts = m_ts_arr_list[idx].timestamp;
418 min_idx = idx;
419 }
420 }
421
422 }
423
424 if (min_idx < 0)
425 {
426 //no valid entries found
427 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
428 ts = 0;
429 ret = false;
430 }
431 else
432 {
433 ts = m_ts_arr_list[min_idx].timestamp;
434 m_ts_arr_list[min_idx].valid = false;
435 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
436 ts, min_idx);
437 }
438
439 return ret;
440
441}
442
443
444bool omx_vdec::ts_arr_list::reset_ts_list()
445{
446 bool ret = true;
447 int idx = 0;
448
449 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
450 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
451 {
452 m_ts_arr_list[idx].valid = false;
453 }
454 return ret;
455}
456#endif
457
458// factory function executed by the core to create instances
459void *get_omx_component_factory_fn(void)
460{
461 return (new omx_vdec);
462}
463
464#ifdef _ANDROID_
465#ifdef USE_ION
466VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
467 struct ion_handle *handle, int ionMapfd)
468{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700469// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700470}
471#else
472VideoHeap::VideoHeap(int fd, size_t size, void* base)
473{
474 // dup file descriptor, map once, use pmem
475 init(dup(fd), base, size, 0 , MEM_DEVICE);
476}
477#endif
478#endif // _ANDROID_
479/* ======================================================================
480FUNCTION
481 omx_vdec::omx_vdec
482
483DESCRIPTION
484 Constructor
485
486PARAMETERS
487 None
488
489RETURN VALUE
490 None.
491========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800492omx_vdec::omx_vdec(): m_error_propogated(false),
493 m_state(OMX_StateInvalid),
494 m_app_data(NULL),
495 m_inp_mem_ptr(NULL),
496 m_out_mem_ptr(NULL),
497 m_inp_err_count(0),
498 input_flush_progress (false),
499 output_flush_progress (false),
500 input_use_buffer (false),
501 output_use_buffer (false),
502 ouput_egl_buffers(false),
503 m_use_output_pmem(OMX_FALSE),
504 m_out_mem_region_smi(OMX_FALSE),
505 m_out_pvt_entry_pmem(OMX_FALSE),
506 pending_input_buffers(0),
507 pending_output_buffers(0),
508 m_out_bm_count(0),
509 m_inp_bm_count(0),
510 m_inp_bPopulated(OMX_FALSE),
511 m_out_bPopulated(OMX_FALSE),
512 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700513#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800514 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700515#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800516 m_inp_bEnabled(OMX_TRUE),
517 m_out_bEnabled(OMX_TRUE),
518 m_in_alloc_cnt(0),
519 m_platform_list(NULL),
520 m_platform_entry(NULL),
521 m_pmem_info(NULL),
522 arbitrary_bytes (true),
523 psource_frame (NULL),
524 pdest_frame (NULL),
525 m_inp_heap_ptr (NULL),
526 m_phdr_pmem_ptr(NULL),
527 m_heap_inp_bm_count (0),
528 codec_type_parse ((codec_type)0),
529 first_frame_meta (true),
530 frame_count (0),
531 nal_count (0),
532 nal_length(0),
533 look_ahead_nal (false),
534 first_frame(0),
535 first_buffer(NULL),
536 first_frame_size (0),
537 m_device_file_ptr(NULL),
538 m_vc1_profile((vc1_profile_type)0),
539 h264_last_au_ts(LLONG_MAX),
540 h264_last_au_flags(0),
541 prev_ts(LLONG_MAX),
542 rst_prev_ts(true),
543 frm_int(0),
544 in_reconfig(false),
545 m_display_id(NULL),
546 h264_parser(NULL),
547 client_extradata(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700548#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800549 m_enable_android_native_buffers(OMX_FALSE),
550 m_use_android_native_buffers(OMX_FALSE),
551 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700552#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800553 m_desc_buffer_ptr(NULL),
Praneeth Paladugu53478562013-03-12 14:49:46 -0700554 secure_mode(false),
555 opt_handle(NULL),
556 perf_lock_acq(NULL),
557 perf_lock_rel(NULL),
558 perf_lock_handle(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700559{
560 /* Assumption is that , to begin with , we have all the frames with decoder */
561 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
562#ifdef _ANDROID_
563 char property_value[PROPERTY_VALUE_MAX] = {0};
564 property_get("vidc.dec.debug.perf", property_value, "0");
565 perf_flag = atoi(property_value);
566 if (perf_flag)
567 {
568 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
569 dec_time.start();
570 proc_frms = latency = 0;
571 }
Vinay Kaliab9e98102013-04-02 19:31:43 -0700572 prev_n_filled_len = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -0800573 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700574 property_get("vidc.dec.debug.ts", property_value, "0");
575 m_debug_timestamp = atoi(property_value);
576 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
577 if (m_debug_timestamp)
578 {
579 time_stamp_dts.set_timestamp_reorder_mode(true);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800580 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700581 }
582
Shalaj Jain286b0062013-02-21 20:35:48 -0800583 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700584 property_get("vidc.dec.debug.concealedmb", property_value, "0");
585 m_debug_concealedmb = atoi(property_value);
586 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
587
588#endif
589 memset(&m_cmp,0,sizeof(m_cmp));
590 memset(&m_cb,0,sizeof(m_cb));
591 memset (&drv_ctx,0,sizeof(drv_ctx));
592 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
593 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700594 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
595 m_demux_entries = 0;
596#ifdef _ANDROID_ICS_
597 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
598#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700599 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700600 drv_ctx.timestamp_adjust = false;
601 drv_ctx.video_driver_fd = -1;
602 m_vendor_config.pData = NULL;
603 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800604 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700605 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800606 streaming[CAPTURE_PORT] =
607 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700608#ifdef _ANDROID_
609 char extradata_value[PROPERTY_VALUE_MAX] = {0};
610 property_get("vidc.dec.debug.extradata", extradata_value, "0");
611 m_debug_extradata = atoi(extradata_value);
612 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
613#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800614 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
615 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700616}
617
Vinay Kalia85793762012-06-14 19:12:34 -0700618static const int event_type[] = {
619 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
620 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
621 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700622 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
623 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700624};
625
626static OMX_ERRORTYPE subscribe_to_events(int fd)
627{
628 OMX_ERRORTYPE eRet = OMX_ErrorNone;
629 struct v4l2_event_subscription sub;
630 int array_sz = sizeof(event_type)/sizeof(int);
631 int i,rc;
632 if (fd < 0) {
633 printf("Invalid input: %d\n", fd);
634 return OMX_ErrorBadParameter;
635 }
636
637 for (i = 0; i < array_sz; ++i) {
638 memset(&sub, 0, sizeof(sub));
639 sub.type = event_type[i];
640 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
641 if (rc) {
642 printf("Failed to subscribe event: 0x%x\n", sub.type);
643 break;
644 }
645 }
646 if (i < array_sz) {
647 for (--i; i >=0 ; i--) {
648 memset(&sub, 0, sizeof(sub));
649 sub.type = event_type[i];
650 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
651 if (rc)
652 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
653 }
654 eRet = OMX_ErrorNotImplemented;
655 }
656 return eRet;
657}
658
659
660static OMX_ERRORTYPE unsubscribe_to_events(int fd)
661{
662 OMX_ERRORTYPE eRet = OMX_ErrorNone;
663 struct v4l2_event_subscription sub;
664 int array_sz = sizeof(event_type)/sizeof(int);
665 int i,rc;
666 if (fd < 0) {
667 printf("Invalid input: %d\n", fd);
668 return OMX_ErrorBadParameter;
669 }
670
671 for (i = 0; i < array_sz; ++i) {
672 memset(&sub, 0, sizeof(sub));
673 sub.type = event_type[i];
674 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
675 if (rc) {
676 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
677 break;
678 }
679 }
680 return eRet;
681}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700682
683/* ======================================================================
684FUNCTION
685 omx_vdec::~omx_vdec
686
687DESCRIPTION
688 Destructor
689
690PARAMETERS
691 None
692
693RETURN VALUE
694 None.
695========================================================================== */
696omx_vdec::~omx_vdec()
697{
698 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700699 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700700 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
701 if(m_pipe_in) close(m_pipe_in);
702 if(m_pipe_out) close(m_pipe_out);
703 m_pipe_in = -1;
704 m_pipe_out = -1;
705 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
706 pthread_join(msg_thread_id,NULL);
707 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700708 dec.cmd = V4L2_DEC_CMD_STOP;
709 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
710 {
711 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
712 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700713 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700714 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700715 close(drv_ctx.video_driver_fd);
716 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800717 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700718 sem_destroy(&m_cmd_lock);
Praneeth Paladugu53478562013-03-12 14:49:46 -0700719 if (perf_lock_handle >= 0 && perf_lock_rel) {
720 DEBUG_PRINT_LOW("Lock released");
721 perf_lock_rel(perf_lock_handle);
722 perf_lock_handle = -1;
723 }
724 if (opt_handle) {
725 dlclose(opt_handle);
726 opt_handle = NULL;
727 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728 if (perf_flag)
729 {
730 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
731 dec_time.end();
732 }
733 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
734}
735
Vinay Kaliafeef7032012-09-25 19:23:33 -0700736int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
737 struct v4l2_requestbuffers bufreq;
738 int rc = 0;
739 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
740 bufreq.memory = V4L2_MEMORY_USERPTR;
741 bufreq.count = 0;
742 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
743 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
744 }
745 return rc;
746}
747
Shalaj Jain273b3e02012-06-22 19:08:03 -0700748/* ======================================================================
749FUNCTION
750 omx_vdec::OMXCntrlProcessMsgCb
751
752DESCRIPTION
753 IL Client callbacks are generated through this routine. The decoder
754 provides the thread context for this routine.
755
756PARAMETERS
757 ctxt -- Context information related to the self.
758 id -- Event identifier. This could be any of the following:
759 1. Command completion event
760 2. Buffer done callback event
761 3. Frame done callback event
762
763RETURN VALUE
764 None.
765
766========================================================================== */
767void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
768{
Shalaj Jain286b0062013-02-21 20:35:48 -0800769 signed p1; // Parameter - 1
770 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700771 unsigned ident;
772 unsigned qsize=0; // qsize
773 omx_vdec *pThis = (omx_vdec *) ctxt;
774
775 if(!pThis)
776 {
777 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
778 __func__);
779 return;
780 }
781
782 // Protect the shared queue data structure
783 do
784 {
785 /*Read the message id's from the queue*/
786 pthread_mutex_lock(&pThis->m_lock);
787 qsize = pThis->m_cmd_q.m_size;
788 if(qsize)
789 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800790 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700791 }
792
793 if (qsize == 0 && pThis->m_state != OMX_StatePause)
794 {
795 qsize = pThis->m_ftb_q.m_size;
796 if (qsize)
797 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800798 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799 }
800 }
801
802 if (qsize == 0 && pThis->m_state != OMX_StatePause)
803 {
804 qsize = pThis->m_etb_q.m_size;
805 if (qsize)
806 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800807 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700808 }
809 }
810 pthread_mutex_unlock(&pThis->m_lock);
811
812 /*process message if we have one*/
813 if(qsize > 0)
814 {
815 id = ident;
816 switch (id)
817 {
818 case OMX_COMPONENT_GENERATE_EVENT:
819 if (pThis->m_cb.EventHandler)
820 {
821 switch (p1)
822 {
823 case OMX_CommandStateSet:
824 pThis->m_state = (OMX_STATETYPE) p2;
825 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
826 pThis->m_state);
827 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
828 OMX_EventCmdComplete, p1, p2, NULL);
829 break;
830
831 case OMX_EventError:
832 if(p2 == OMX_StateInvalid)
833 {
834 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
835 pThis->m_state = (OMX_STATETYPE) p2;
836 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
837 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
838 }
839 else if (p2 == OMX_ErrorHardware)
840 {
841 pThis->omx_report_error();
842 }
843 else
844 {
845 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800846 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700847 }
848 break;
849
850 case OMX_CommandPortDisable:
851 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
852 if (BITMASK_PRESENT(&pThis->m_flags,
853 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
854 {
855 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
856 break;
857 }
858 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
859 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700860 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700861 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700862 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
863 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
864 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700865 pThis->in_reconfig = false;
866 if(eRet != OMX_ErrorNone)
867 {
868 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
869 pThis->omx_report_error();
870 break;
871 }
872 }
873 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
874 OMX_EventCmdComplete, p1, p2, NULL );
875 break;
876 case OMX_CommandPortEnable:
877 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
878 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
879 OMX_EventCmdComplete, p1, p2, NULL );
880 break;
881
882 default:
883 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
884 OMX_EventCmdComplete, p1, p2, NULL );
885 break;
886
887 }
888 }
889 else
890 {
891 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
892 }
893 break;
894 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
895 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
896 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
897 {
898 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
899 pThis->omx_report_error ();
900 }
901 break;
902 case OMX_COMPONENT_GENERATE_ETB:
903 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
904 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
905 {
906 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
907 pThis->omx_report_error ();
908 }
909 break;
910
911 case OMX_COMPONENT_GENERATE_FTB:
912 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
913 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
914 {
915 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
916 pThis->omx_report_error ();
917 }
918 break;
919
920 case OMX_COMPONENT_GENERATE_COMMAND:
921 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
922 (OMX_U32)p2,(OMX_PTR)NULL);
923 break;
924
925 case OMX_COMPONENT_GENERATE_EBD:
926
927 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
928 {
929 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
930 pThis->omx_report_error ();
931 }
932 else
933 {
934 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
935 {
936 pThis->m_inp_err_count++;
937 pThis->time_stamp_dts.remove_time_stamp(
938 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
939 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
940 ?true:false);
941 }
942 else
943 {
944 pThis->m_inp_err_count = 0;
945 }
946 if ( pThis->empty_buffer_done(&pThis->m_cmp,
947 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
948 {
949 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
950 pThis->omx_report_error ();
951 }
952 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
953 {
954 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
955 pThis->omx_report_error ();
956 }
957 }
958 break;
959 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
960 {
961 int64_t *timestamp = (int64_t *)p1;
962 if (p1)
963 {
964 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
965 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
966 ?true:false);
967 free(timestamp);
968 }
969 }
970 break;
971 case OMX_COMPONENT_GENERATE_FBD:
972 if (p2 != VDEC_S_SUCCESS)
973 {
974 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
975 pThis->omx_report_error ();
976 }
977 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
978 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
979 {
980 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
986 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
987 if (!pThis->input_flush_progress)
988 {
989 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
990 }
991 else
992 {
993 pThis->execute_input_flush();
994 if (pThis->m_cb.EventHandler)
995 {
996 if (p2 != VDEC_S_SUCCESS)
997 {
998 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
999 pThis->omx_report_error ();
1000 }
1001 else
1002 {
1003 /*Check if we need generate event for Flush done*/
1004 if(BITMASK_PRESENT(&pThis->m_flags,
1005 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1006 {
1007 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1008 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1009 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1010 OMX_EventCmdComplete,OMX_CommandFlush,
1011 OMX_CORE_INPUT_PORT_INDEX,NULL );
1012 }
1013 if (BITMASK_PRESENT(&pThis->m_flags,
1014 OMX_COMPONENT_IDLE_PENDING))
1015 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001016 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001017 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1018 pThis->omx_report_error ();
1019 } else {
1020 pThis->streaming[OUTPUT_PORT] = false;
1021 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001022 if (!pThis->output_flush_progress)
1023 {
Vinay Kalia22046272012-09-28 20:16:05 -07001024 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001025 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001026 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001027 }
1028 }
1029 }
1030 }
1031 else
1032 {
1033 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1034 }
1035 }
1036 break;
1037
1038 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1039 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1040 if (!pThis->output_flush_progress)
1041 {
1042 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1043 }
1044 else
1045 {
1046 pThis->execute_output_flush();
1047 if (pThis->m_cb.EventHandler)
1048 {
1049 if (p2 != VDEC_S_SUCCESS)
1050 {
1051 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1052 pThis->omx_report_error ();
1053 }
1054 else
1055 {
1056 /*Check if we need generate event for Flush done*/
1057 if(BITMASK_PRESENT(&pThis->m_flags,
1058 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1059 {
1060 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1061 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1062 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1063 OMX_EventCmdComplete,OMX_CommandFlush,
1064 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1065 }
1066 if(BITMASK_PRESENT(&pThis->m_flags,
1067 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1068 {
1069 DEBUG_PRINT_LOW("\n Internal flush complete");
1070 BITMASK_CLEAR (&pThis->m_flags,
1071 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1072 if (BITMASK_PRESENT(&pThis->m_flags,
1073 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1074 {
1075 pThis->post_event(OMX_CommandPortDisable,
1076 OMX_CORE_OUTPUT_PORT_INDEX,
1077 OMX_COMPONENT_GENERATE_EVENT);
1078 BITMASK_CLEAR (&pThis->m_flags,
1079 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1080
1081 }
1082 }
1083
1084 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1085 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001086 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001087 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1088 pThis->omx_report_error ();
1089 break;
1090 }
1091 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001092 if (!pThis->input_flush_progress)
1093 {
Vinay Kalia22046272012-09-28 20:16:05 -07001094 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001095 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001096 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001097 }
1098 }
1099 }
1100 }
1101 else
1102 {
1103 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1104 }
1105 }
1106 break;
1107
1108 case OMX_COMPONENT_GENERATE_START_DONE:
1109 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1110
1111 if (pThis->m_cb.EventHandler)
1112 {
1113 if (p2 != VDEC_S_SUCCESS)
1114 {
1115 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1116 pThis->omx_report_error ();
1117 }
1118 else
1119 {
1120 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1121 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1122 {
1123 DEBUG_PRINT_LOW("\n Move to executing");
1124 // Send the callback now
1125 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1126 pThis->m_state = OMX_StateExecuting;
1127 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1128 OMX_EventCmdComplete,OMX_CommandStateSet,
1129 OMX_StateExecuting, NULL);
1130 }
1131 else if (BITMASK_PRESENT(&pThis->m_flags,
1132 OMX_COMPONENT_PAUSE_PENDING))
1133 {
1134 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1135 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1136 {
1137 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1138 pThis->omx_report_error ();
1139 }
1140 }
1141 }
1142 }
1143 else
1144 {
1145 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1146 }
1147 break;
1148
1149 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1150 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1151 if (pThis->m_cb.EventHandler)
1152 {
1153 if (p2 != VDEC_S_SUCCESS)
1154 {
1155 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1156 pThis->omx_report_error ();
1157 }
1158 else
1159 {
1160 pThis->complete_pending_buffer_done_cbs();
1161 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1162 {
1163 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1164 //Send the callback now
1165 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1166 pThis->m_state = OMX_StatePause;
1167 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1168 OMX_EventCmdComplete,OMX_CommandStateSet,
1169 OMX_StatePause, NULL);
1170 }
1171 }
1172 }
1173 else
1174 {
1175 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1176 }
1177
1178 break;
1179
1180 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1181 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1182 if (pThis->m_cb.EventHandler)
1183 {
1184 if (p2 != VDEC_S_SUCCESS)
1185 {
1186 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1187 pThis->omx_report_error ();
1188 }
1189 else
1190 {
1191 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1192 {
1193 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1194 // Send the callback now
1195 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1196 pThis->m_state = OMX_StateExecuting;
1197 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1198 OMX_EventCmdComplete,OMX_CommandStateSet,
1199 OMX_StateExecuting,NULL);
1200 }
1201 }
1202 }
1203 else
1204 {
1205 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1206 }
1207
1208 break;
1209
1210 case OMX_COMPONENT_GENERATE_STOP_DONE:
1211 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1212 if (pThis->m_cb.EventHandler)
1213 {
1214 if (p2 != VDEC_S_SUCCESS)
1215 {
1216 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1217 pThis->omx_report_error ();
1218 }
1219 else
1220 {
1221 pThis->complete_pending_buffer_done_cbs();
1222 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1223 {
1224 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1225 // Send the callback now
1226 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1227 pThis->m_state = OMX_StateIdle;
1228 DEBUG_PRINT_LOW("\n Move to Idle State");
1229 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1230 OMX_EventCmdComplete,OMX_CommandStateSet,
1231 OMX_StateIdle,NULL);
1232 }
1233 }
1234 }
1235 else
1236 {
1237 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1238 }
1239
1240 break;
1241
1242 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1243 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001244
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 if (p2 == OMX_IndexParamPortDefinition) {
1246 pThis->in_reconfig = true;
1247 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001248 if (pThis->m_cb.EventHandler) {
1249 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001250 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001251 } else {
1252 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1253 }
1254
1255 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001256 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001257 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1258 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1259 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1260 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1261 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1262 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1263 else //unsupported interlace format; raise a error
1264 event = OMX_EventError;
1265 if (pThis->m_cb.EventHandler) {
1266 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1267 event, format, 0, NULL );
1268 } else {
1269 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001270 }
1271 }
1272 break;
1273
1274 case OMX_COMPONENT_GENERATE_EOS_DONE:
1275 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1276 if (pThis->m_cb.EventHandler) {
1277 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1278 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1279 } else {
1280 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1281 }
1282 pThis->prev_ts = LLONG_MAX;
1283 pThis->rst_prev_ts = true;
1284 break;
1285
1286 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1287 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1288 pThis->omx_report_error ();
1289 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001290
1291 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1292 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1293 pThis->omx_report_unsupported_setting();
1294 break;
1295
Shalaj Jain273b3e02012-06-22 19:08:03 -07001296 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1297 {
1298 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1299 if (pThis->m_cb.EventHandler) {
1300 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1301 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1302 } else {
1303 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1304 }
1305 }
1306 default:
1307 break;
1308 }
1309 }
1310 pthread_mutex_lock(&pThis->m_lock);
1311 qsize = pThis->m_cmd_q.m_size;
1312 if (pThis->m_state != OMX_StatePause)
1313 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1314 pthread_mutex_unlock(&pThis->m_lock);
1315 }
1316 while(qsize>0);
1317
1318}
1319
Vinay Kaliab9e98102013-04-02 19:31:43 -07001320int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001321{
Vinay Kaliab9e98102013-04-02 19:31:43 -07001322 int format_changed = 0;
1323 if ((height != drv_ctx.video_resolution.frame_height) ||
1324 (width != drv_ctx.video_resolution.frame_width))
1325 format_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001326 drv_ctx.video_resolution.frame_height = height;
1327 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001328 drv_ctx.video_resolution.scan_lines = scan_lines;
1329 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001330 rectangle.nLeft = 0;
1331 rectangle.nTop = 0;
1332 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1333 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Vinay Kaliab9e98102013-04-02 19:31:43 -07001334 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001335}
1336
Arun Menon6836ba02013-02-19 20:37:40 -08001337OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1338{
1339 if (drv_ctx.video_resolution.frame_width < m_decoder_capability.min_width ||
1340 drv_ctx.video_resolution.frame_width > m_decoder_capability.max_width ||
1341 drv_ctx.video_resolution.frame_height < m_decoder_capability.min_height ||
1342 drv_ctx.video_resolution.frame_height > m_decoder_capability.max_height) {
1343 DEBUG_PRINT_ERROR("\n Unsupported video resolution width = %u height = %u\n",
1344 drv_ctx.video_resolution.frame_width,
1345 drv_ctx.video_resolution.frame_height);
1346 DEBUG_PRINT_ERROR("\n supported range width - min(%u) max(%u\n",
1347 m_decoder_capability.min_width,
1348 m_decoder_capability.max_width);
1349 DEBUG_PRINT_ERROR("\n supported range height - min(%u) max(%u)\n",
1350 m_decoder_capability.min_height,
1351 m_decoder_capability.max_height);
1352 return OMX_ErrorUnsupportedSetting;
1353 }
1354 DEBUG_PRINT_HIGH("\n video session supported\n");
1355 return OMX_ErrorNone;
1356}
1357
Shalaj Jain273b3e02012-06-22 19:08:03 -07001358/* ======================================================================
1359FUNCTION
1360 omx_vdec::ComponentInit
1361
1362DESCRIPTION
1363 Initialize the component.
1364
1365PARAMETERS
1366 ctxt -- Context information related to the self.
1367 id -- Event identifier. This could be any of the following:
1368 1. Command completion event
1369 2. Buffer done callback event
1370 3. Frame done callback event
1371
1372RETURN VALUE
1373 None.
1374
1375========================================================================== */
1376OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1377{
1378
1379 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001380 struct v4l2_fmtdesc fdesc;
1381 struct v4l2_format fmt;
1382 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001383 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001384 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001385 unsigned int alignment = 0,buffer_size = 0;
1386 int fds[2];
1387 int r,ret=0;
1388 bool codec_ambiguous = false;
Sachin Shahc82a18f2013-03-29 14:45:38 -07001389 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
1390
1391#ifdef _ANDROID_
1392 char platform_name[64];
1393 property_get("ro.board.platform", platform_name, "0");
1394 if (!strncmp(platform_name, "msm8610", 7)) {
1395 device_name = (OMX_STRING)"/dev/video/q6_dec";
1396 }
1397#endif
1398
Vinay Kalia53fa6832012-10-11 17:55:30 -07001399 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1400 struct v4l2_control control;
1401 secure_mode = true;
1402 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001403 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001404 }
1405
Sachin Shahc82a18f2013-03-29 14:45:38 -07001406 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001407
1408 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1409 drv_ctx.video_driver_fd, errno);
1410
1411 if(drv_ctx.video_driver_fd == 0){
Sachin Shahc82a18f2013-03-29 14:45:38 -07001412 DEBUG_PRINT_ERROR("Omx_vdec:: Got fd as 0 for msm_vidc_dec, Opening again\n");
1413 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001414 }
1415
1416 if(drv_ctx.video_driver_fd < 0)
1417 {
1418 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1419 return OMX_ErrorInsufficientResources;
1420 }
1421 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1422 drv_ctx.frame_rate.fps_denominator = 1;
1423
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001424 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1425 if(ret < 0) {
1426 close(drv_ctx.video_driver_fd);
1427 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1428 return OMX_ErrorInsufficientResources;
1429 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001430
1431#ifdef INPUT_BUFFER_LOG
1432 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1433#endif
1434#ifdef OUTPUT_BUFFER_LOG
1435 outputBufferFile1 = fopen (outputfilename, "ab");
1436#endif
1437#ifdef OUTPUT_EXTRADATA_LOG
1438 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1439#endif
1440
1441 // Copy the role information which provides the decoder kind
1442 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001443
Shalaj Jain273b3e02012-06-22 19:08:03 -07001444 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1445 OMX_MAX_STRINGNAME_SIZE))
1446 {
1447 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1448 OMX_MAX_STRINGNAME_SIZE);
1449 drv_ctx.timestamp_adjust = true;
1450 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1451 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001452 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001453 /*Initialize Start Code for MPEG4*/
1454 codec_type_parse = CODEC_TYPE_MPEG4;
1455 m_frame_parser.init_start_codes (codec_type_parse);
1456#ifdef INPUT_BUFFER_LOG
1457 strcat(inputfilename, "m4v");
1458#endif
1459 }
1460 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1461 OMX_MAX_STRINGNAME_SIZE))
1462 {
1463 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1464 OMX_MAX_STRINGNAME_SIZE);
1465 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001466 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001467 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1468 /*Initialize Start Code for MPEG2*/
1469 codec_type_parse = CODEC_TYPE_MPEG2;
1470 m_frame_parser.init_start_codes (codec_type_parse);
1471#ifdef INPUT_BUFFER_LOG
1472 strcat(inputfilename, "mpg");
1473#endif
1474 }
1475 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1476 OMX_MAX_STRINGNAME_SIZE))
1477 {
1478 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1479 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1480 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1481 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001482 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001483 codec_type_parse = CODEC_TYPE_H263;
1484 m_frame_parser.init_start_codes (codec_type_parse);
1485#ifdef INPUT_BUFFER_LOG
1486 strcat(inputfilename, "263");
1487#endif
1488 }
1489 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1490 OMX_MAX_STRINGNAME_SIZE))
1491 {
1492 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1493 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1494 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1495 output_capability = V4L2_PIX_FMT_DIVX_311;
1496 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1497 codec_type_parse = CODEC_TYPE_DIVX;
1498 m_frame_parser.init_start_codes (codec_type_parse);
1499
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001500 eRet = createDivxDrmContext();
1501 if (eRet != OMX_ErrorNone) {
1502 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1503 return eRet;
1504 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001505 }
1506 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1507 OMX_MAX_STRINGNAME_SIZE))
1508 {
1509 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1510 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1511 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1512 output_capability = V4L2_PIX_FMT_DIVX;
1513 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1514 codec_type_parse = CODEC_TYPE_DIVX;
1515 codec_ambiguous = true;
1516 m_frame_parser.init_start_codes (codec_type_parse);
1517
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001518 eRet = createDivxDrmContext();
1519 if (eRet != OMX_ErrorNone) {
1520 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1521 return eRet;
1522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001523 }
1524 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1525 OMX_MAX_STRINGNAME_SIZE))
1526 {
1527 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1528 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1529 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1530 output_capability = V4L2_PIX_FMT_DIVX;
1531 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1532 codec_type_parse = CODEC_TYPE_DIVX;
1533 codec_ambiguous = true;
1534 m_frame_parser.init_start_codes (codec_type_parse);
1535
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001536 eRet = createDivxDrmContext();
1537 if (eRet != OMX_ErrorNone) {
1538 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1539 return eRet;
1540 }
1541
Shalaj Jain273b3e02012-06-22 19:08:03 -07001542 }
1543 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1544 OMX_MAX_STRINGNAME_SIZE))
1545 {
1546 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1547 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1548 output_capability=V4L2_PIX_FMT_H264;
1549 eCompressionFormat = OMX_VIDEO_CodingAVC;
1550 codec_type_parse = CODEC_TYPE_H264;
1551 m_frame_parser.init_start_codes (codec_type_parse);
1552 m_frame_parser.init_nal_length(nal_length);
1553#ifdef INPUT_BUFFER_LOG
1554 strcat(inputfilename, "264");
1555#endif
1556 }
1557 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1558 OMX_MAX_STRINGNAME_SIZE))
1559 {
1560 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1561 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1562 eCompressionFormat = OMX_VIDEO_CodingWMV;
1563 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001564 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001565 m_frame_parser.init_start_codes (codec_type_parse);
1566#ifdef INPUT_BUFFER_LOG
1567 strcat(inputfilename, "vc1");
1568#endif
1569 }
1570 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1571 OMX_MAX_STRINGNAME_SIZE))
1572 {
1573 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1574 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1575 eCompressionFormat = OMX_VIDEO_CodingWMV;
1576 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001577 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001578 m_frame_parser.init_start_codes (codec_type_parse);
1579#ifdef INPUT_BUFFER_LOG
1580 strcat(inputfilename, "vc1");
1581#endif
1582 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001583 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1584 OMX_MAX_STRINGNAME_SIZE))
1585 {
1586 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1587 output_capability=V4L2_PIX_FMT_VP8;
1588 eCompressionFormat = OMX_VIDEO_CodingVPX;
1589 codec_type_parse = CODEC_TYPE_VP8;
1590 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001591#ifdef INPUT_BUFFER_LOG
1592 strcat(inputfilename, "ivf");
1593#endif
1594
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001595 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001596 else
1597 {
1598 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1599 eRet = OMX_ErrorInvalidComponentName;
1600 }
1601#ifdef INPUT_BUFFER_LOG
1602 inputBufferFile1 = fopen (inputfilename, "ab");
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001603 if (output_capability == V4L2_PIX_FMT_VP8) {
1604 struct ivf_file_header
1605 {
1606 OMX_U8 signature[4]; //='DKIF';
1607 OMX_U8 version ; //= 0;
1608 OMX_U8 headersize ; //= 32;
1609 OMX_U32 FourCC;
1610 OMX_U8 width;
1611 OMX_U8 height;
1612 OMX_U32 rate;
1613 OMX_U32 scale;
1614 OMX_U32 length;
1615 OMX_U8 unused[4];
1616 } file_header;
1617 memset((void *)&file_header,0,sizeof(file_header));
1618 file_header.signature[0] = 'D';
1619 file_header.signature[1] = 'K';
1620 file_header.signature[2] = 'I';
1621 file_header.signature[3] = 'F';
1622 file_header.version = 0;
1623 file_header.headersize = 32;
1624 file_header.FourCC = 0x30385056;
1625 if (inputBufferFile1)
1626 {
1627 fwrite((const char *)&file_header,
1628 sizeof(file_header),1,inputBufferFile1);
1629 }
1630 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001631#endif
1632 if (eRet == OMX_ErrorNone)
1633 {
1634
Vinay Kaliada4f4422013-01-09 10:45:03 -08001635 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1636 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1637 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1638 if (!client_buffers.set_color_format(dest_color_format)) {
1639 DEBUG_PRINT_ERROR("\n Setting color format failed");
1640 eRet = OMX_ErrorInsufficientResources;
1641 }
1642
Shalaj Jain273b3e02012-06-22 19:08:03 -07001643 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001644 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001646 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1647 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001648 }
1649
1650 struct v4l2_capability cap;
1651 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1652 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001653 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001654 /*TODO: How to handle this case */
1655 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001656 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001657 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1658 cap.bus_info, cap.version, cap.capabilities);
1659 }
1660 ret=0;
1661 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1662 fdesc.index=0;
1663 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001664 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665 fdesc.pixelformat, fdesc.flags);
1666 fdesc.index++;
1667 }
1668 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1669 fdesc.index=0;
1670 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1671
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001672 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673 fdesc.pixelformat, fdesc.flags);
1674 fdesc.index++;
1675 }
Vinay Kalia21649b32013-03-18 17:28:07 -07001676 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001677 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1678 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1679 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1680 fmt.fmt.pix_mp.pixelformat = output_capability;
1681 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1682 if (ret) {
1683 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001684 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001685 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001686 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001687 if (codec_ambiguous) {
1688 if (output_capability == V4L2_PIX_FMT_DIVX) {
1689 struct v4l2_control divx_ctrl;
1690
1691 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001692 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001694 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001695 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001696 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001697 }
1698
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001699 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001700 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001701 if (ret) {
1702 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1703 }
1704 } else {
1705 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1706 }
1707 }
1708
Arun Menon6836ba02013-02-19 20:37:40 -08001709 //Get the hardware capabilities
1710 memset((void *)&frmsize,0,sizeof(frmsize));
1711 frmsize.index = 0;
1712 frmsize.pixel_format = output_capability;
1713 ret = ioctl(drv_ctx.video_driver_fd,
1714 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1715 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1716 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1717 return OMX_ErrorHardware;
1718 }
1719
1720 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1721 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1722 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1723 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1724 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1725 }
1726
Shalaj Jain273b3e02012-06-22 19:08:03 -07001727 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1728 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1729 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001730 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001731 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1732 if (ret) {
1733 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001734 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001735 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001736 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001737 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001738 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1739 control.value = 1;
1740 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1741 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1742 if (ret) {
1743 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1744 close(drv_ctx.video_driver_fd);
1745 return OMX_ErrorInsufficientResources;
1746 }
1747 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001748
1749 /*Get the Buffer requirements for input and output ports*/
1750 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1751 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001752 if (secure_mode) {
1753 drv_ctx.op_buf.alignment=SZ_1M;
1754 drv_ctx.ip_buf.alignment=SZ_1M;
1755 } else {
1756 drv_ctx.op_buf.alignment=SZ_4K;
1757 drv_ctx.ip_buf.alignment=SZ_4K;
1758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001759 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1760 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001761 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1762 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1763 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1764 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001765 drv_ctx.idr_only_decoding = 0;
1766
Vinay Kalia5713bb32013-01-16 18:39:59 -08001767 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001768#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001769 if (eRet == OMX_ErrorNone && !secure_mode)
1770 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001771#endif
Praneeth Paladugu1d654b02013-04-02 10:28:29 -07001772 if (output_capability != V4L2_PIX_FMT_VC1_ANNEX_L &&
1773 output_capability != V4L2_PIX_FMT_VC1_ANNEX_G ) {
1774 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
1775 control.value = 1;
1776 DEBUG_PRINT_HIGH("Enabling smooth streaming!\n");
1777 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
1778 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming");
1779 }
1780 }
Vinay Kalia5713bb32013-01-16 18:39:59 -08001781 eRet=get_buffer_req(&drv_ctx.ip_buf);
1782 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1783 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001784 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1785 {
1786 if (m_frame_parser.mutils == NULL)
1787 {
1788 m_frame_parser.mutils = new H264_Utils();
1789
1790 if (m_frame_parser.mutils == NULL)
1791 {
1792 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1793 eRet = OMX_ErrorInsufficientResources;
1794 }
1795 else
1796 {
1797 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1798 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1799 h264_scratch.nFilledLen = 0;
1800 h264_scratch.nOffset = 0;
1801
1802 if (h264_scratch.pBuffer == NULL)
1803 {
1804 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1805 return OMX_ErrorInsufficientResources;
1806 }
1807 m_frame_parser.mutils->initialize_frame_checking_environment();
1808 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1809 }
1810 }
1811
1812 h264_parser = new h264_stream_parser();
1813 if (!h264_parser)
1814 {
1815 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1816 eRet = OMX_ErrorInsufficientResources;
1817 }
1818 }
1819
1820 if(pipe(fds))
1821 {
1822 DEBUG_PRINT_ERROR("pipe creation failed\n");
1823 eRet = OMX_ErrorInsufficientResources;
1824 }
1825 else
1826 {
1827 int temp1[2];
1828 if(fds[0] == 0 || fds[1] == 0)
1829 {
1830 if (pipe (temp1))
1831 {
1832 DEBUG_PRINT_ERROR("pipe creation failed\n");
1833 return OMX_ErrorInsufficientResources;
1834 }
1835 //close (fds[0]);
1836 //close (fds[1]);
1837 fds[0] = temp1 [0];
1838 fds[1] = temp1 [1];
1839 }
1840 m_pipe_in = fds[0];
1841 m_pipe_out = fds[1];
1842 r = pthread_create(&msg_thread_id,0,message_thread,this);
1843
1844 if(r < 0)
1845 {
1846 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1847 eRet = OMX_ErrorInsufficientResources;
1848 }
1849 }
1850 }
1851
1852 if (eRet != OMX_ErrorNone)
1853 {
1854 DEBUG_PRINT_ERROR("\n Component Init Failed");
1855 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1856 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1857 NULL);
1858 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1859 close (drv_ctx.video_driver_fd);
1860 drv_ctx.video_driver_fd = -1;
1861 }
1862 else
1863 {
1864 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1865 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001866 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1867 return eRet;
1868}
1869
1870/* ======================================================================
1871FUNCTION
1872 omx_vdec::GetComponentVersion
1873
1874DESCRIPTION
1875 Returns the component version.
1876
1877PARAMETERS
1878 TBD.
1879
1880RETURN VALUE
1881 OMX_ErrorNone.
1882
1883========================================================================== */
1884OMX_ERRORTYPE omx_vdec::get_component_version
1885 (
1886 OMX_IN OMX_HANDLETYPE hComp,
1887 OMX_OUT OMX_STRING componentName,
1888 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1889 OMX_OUT OMX_VERSIONTYPE* specVersion,
1890 OMX_OUT OMX_UUIDTYPE* componentUUID
1891 )
1892{
1893 if(m_state == OMX_StateInvalid)
1894 {
1895 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1896 return OMX_ErrorInvalidState;
1897 }
1898 /* TBD -- Return the proper version */
1899 if (specVersion)
1900 {
1901 specVersion->nVersion = OMX_SPEC_VERSION;
1902 }
1903 return OMX_ErrorNone;
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(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 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1926 if(m_state == OMX_StateInvalid)
1927 {
1928 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1929 return OMX_ErrorInvalidState;
1930 }
1931 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1932 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1933 {
1934 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001935 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001936 return OMX_ErrorBadPortIndex;
1937 }
1938 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1939 sem_wait(&m_cmd_lock);
1940 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1941 return OMX_ErrorNone;
1942}
1943
1944/* ======================================================================
1945FUNCTION
1946 omx_vdec::SendCommand
1947
1948DESCRIPTION
1949 Returns zero if all the buffers released..
1950
1951PARAMETERS
1952 None.
1953
1954RETURN VALUE
1955 true/false
1956
1957========================================================================== */
1958OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1959 OMX_IN OMX_COMMANDTYPE cmd,
1960 OMX_IN OMX_U32 param1,
1961 OMX_IN OMX_PTR cmdData
1962 )
1963{
1964 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1965 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1966 int bFlag = 1,sem_posted = 0,ret=0;
1967
1968 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1969 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1970 m_state, eState);
1971
1972 if(cmd == OMX_CommandStateSet)
1973 {
1974 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1975 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1976 /***************************/
1977 /* Current State is Loaded */
1978 /***************************/
1979 if(m_state == OMX_StateLoaded)
1980 {
1981 if(eState == OMX_StateIdle)
1982 {
1983 //if all buffers are allocated or all ports disabled
1984 if(allocate_done() ||
1985 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1986 {
1987 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1988 }
1989 else
1990 {
1991 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1992 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1993 // Skip the event notification
1994 bFlag = 0;
1995 }
1996 }
1997 /* Requesting transition from Loaded to Loaded */
1998 else if(eState == OMX_StateLoaded)
1999 {
2000 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
2001 post_event(OMX_EventError,OMX_ErrorSameState,\
2002 OMX_COMPONENT_GENERATE_EVENT);
2003 eRet = OMX_ErrorSameState;
2004 }
2005 /* Requesting transition from Loaded to WaitForResources */
2006 else if(eState == OMX_StateWaitForResources)
2007 {
2008 /* Since error is None , we will post an event
2009 at the end of this function definition */
2010 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
2011 }
2012 /* Requesting transition from Loaded to Executing */
2013 else if(eState == OMX_StateExecuting)
2014 {
2015 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
2016 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2017 OMX_COMPONENT_GENERATE_EVENT);
2018 eRet = OMX_ErrorIncorrectStateTransition;
2019 }
2020 /* Requesting transition from Loaded to Pause */
2021 else if(eState == OMX_StatePause)
2022 {
2023 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
2024 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2025 OMX_COMPONENT_GENERATE_EVENT);
2026 eRet = OMX_ErrorIncorrectStateTransition;
2027 }
2028 /* Requesting transition from Loaded to Invalid */
2029 else if(eState == OMX_StateInvalid)
2030 {
2031 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
2032 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2033 eRet = OMX_ErrorInvalidState;
2034 }
2035 else
2036 {
2037 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
2038 eState);
2039 eRet = OMX_ErrorBadParameter;
2040 }
2041 }
2042
2043 /***************************/
2044 /* Current State is IDLE */
2045 /***************************/
2046 else if(m_state == OMX_StateIdle)
2047 {
2048 if(eState == OMX_StateLoaded)
2049 {
2050 if(release_done())
2051 {
2052 /*
2053 Since error is None , we will post an event at the end
2054 of this function definition
2055 */
2056 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2057 }
2058 else
2059 {
2060 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2061 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2062 // Skip the event notification
2063 bFlag = 0;
2064 }
2065 }
2066 /* Requesting transition from Idle to Executing */
2067 else if(eState == OMX_StateExecuting)
2068 {
2069 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2070 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2071 bFlag = 1;
2072 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2073 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002074 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002075 }
2076 /* Requesting transition from Idle to Idle */
2077 else if(eState == OMX_StateIdle)
2078 {
2079 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2080 post_event(OMX_EventError,OMX_ErrorSameState,\
2081 OMX_COMPONENT_GENERATE_EVENT);
2082 eRet = OMX_ErrorSameState;
2083 }
2084 /* Requesting transition from Idle to WaitForResources */
2085 else if(eState == OMX_StateWaitForResources)
2086 {
2087 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2088 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2089 OMX_COMPONENT_GENERATE_EVENT);
2090 eRet = OMX_ErrorIncorrectStateTransition;
2091 }
2092 /* Requesting transition from Idle to Pause */
2093 else if(eState == OMX_StatePause)
2094 {
2095 /*To pause the Video core we need to start the driver*/
2096 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2097 NULL) < */0)
2098 {
2099 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2100 omx_report_error ();
2101 eRet = OMX_ErrorHardware;
2102 }
2103 else
2104 {
2105 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2106 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2107 bFlag = 0;
2108 }
2109 }
2110 /* Requesting transition from Idle to Invalid */
2111 else if(eState == OMX_StateInvalid)
2112 {
2113 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2114 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2115 eRet = OMX_ErrorInvalidState;
2116 }
2117 else
2118 {
2119 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2120 eRet = OMX_ErrorBadParameter;
2121 }
2122 }
2123
2124 /******************************/
2125 /* Current State is Executing */
2126 /******************************/
2127 else if(m_state == OMX_StateExecuting)
2128 {
2129 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2130 /* Requesting transition from Executing to Idle */
2131 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002132 {
2133 /* Since error is None , we will post an event
2134 at the end of this function definition
2135 */
2136 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002137 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002138 if(!sem_posted)
2139 {
2140 sem_posted = 1;
2141 sem_post (&m_cmd_lock);
2142 execute_omx_flush(OMX_ALL);
2143 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002144 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002145 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002146 /* Requesting transition from Executing to Paused */
2147 else if(eState == OMX_StatePause)
2148 {
2149 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002150 m_state = OMX_StatePause;
2151 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002152 }
2153 /* Requesting transition from Executing to Loaded */
2154 else if(eState == OMX_StateLoaded)
2155 {
2156 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2157 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2158 OMX_COMPONENT_GENERATE_EVENT);
2159 eRet = OMX_ErrorIncorrectStateTransition;
2160 }
2161 /* Requesting transition from Executing to WaitForResources */
2162 else if(eState == OMX_StateWaitForResources)
2163 {
2164 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2165 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2166 OMX_COMPONENT_GENERATE_EVENT);
2167 eRet = OMX_ErrorIncorrectStateTransition;
2168 }
2169 /* Requesting transition from Executing to Executing */
2170 else if(eState == OMX_StateExecuting)
2171 {
2172 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2173 post_event(OMX_EventError,OMX_ErrorSameState,\
2174 OMX_COMPONENT_GENERATE_EVENT);
2175 eRet = OMX_ErrorSameState;
2176 }
2177 /* Requesting transition from Executing to Invalid */
2178 else if(eState == OMX_StateInvalid)
2179 {
2180 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2181 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2182 eRet = OMX_ErrorInvalidState;
2183 }
2184 else
2185 {
2186 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2187 eRet = OMX_ErrorBadParameter;
2188 }
2189 }
2190 /***************************/
2191 /* Current State is Pause */
2192 /***************************/
2193 else if(m_state == OMX_StatePause)
2194 {
2195 /* Requesting transition from Pause to Executing */
2196 if(eState == OMX_StateExecuting)
2197 {
2198 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002199 m_state = OMX_StateExecuting;
2200 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002201 }
2202 /* Requesting transition from Pause to Idle */
2203 else if(eState == OMX_StateIdle)
2204 {
2205 /* Since error is None , we will post an event
2206 at the end of this function definition */
2207 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2208 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2209 if(!sem_posted)
2210 {
2211 sem_posted = 1;
2212 sem_post (&m_cmd_lock);
2213 execute_omx_flush(OMX_ALL);
2214 }
2215 bFlag = 0;
2216 }
2217 /* Requesting transition from Pause to loaded */
2218 else if(eState == OMX_StateLoaded)
2219 {
2220 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2221 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2222 OMX_COMPONENT_GENERATE_EVENT);
2223 eRet = OMX_ErrorIncorrectStateTransition;
2224 }
2225 /* Requesting transition from Pause to WaitForResources */
2226 else if(eState == OMX_StateWaitForResources)
2227 {
2228 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2229 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2230 OMX_COMPONENT_GENERATE_EVENT);
2231 eRet = OMX_ErrorIncorrectStateTransition;
2232 }
2233 /* Requesting transition from Pause to Pause */
2234 else if(eState == OMX_StatePause)
2235 {
2236 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2237 post_event(OMX_EventError,OMX_ErrorSameState,\
2238 OMX_COMPONENT_GENERATE_EVENT);
2239 eRet = OMX_ErrorSameState;
2240 }
2241 /* Requesting transition from Pause to Invalid */
2242 else if(eState == OMX_StateInvalid)
2243 {
2244 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2245 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2246 eRet = OMX_ErrorInvalidState;
2247 }
2248 else
2249 {
2250 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2251 eRet = OMX_ErrorBadParameter;
2252 }
2253 }
2254 /***************************/
2255 /* Current State is WaitForResources */
2256 /***************************/
2257 else if(m_state == OMX_StateWaitForResources)
2258 {
2259 /* Requesting transition from WaitForResources to Loaded */
2260 if(eState == OMX_StateLoaded)
2261 {
2262 /* Since error is None , we will post an event
2263 at the end of this function definition */
2264 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2265 }
2266 /* Requesting transition from WaitForResources to WaitForResources */
2267 else if (eState == OMX_StateWaitForResources)
2268 {
2269 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2270 post_event(OMX_EventError,OMX_ErrorSameState,
2271 OMX_COMPONENT_GENERATE_EVENT);
2272 eRet = OMX_ErrorSameState;
2273 }
2274 /* Requesting transition from WaitForResources to Executing */
2275 else if(eState == OMX_StateExecuting)
2276 {
2277 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2278 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2279 OMX_COMPONENT_GENERATE_EVENT);
2280 eRet = OMX_ErrorIncorrectStateTransition;
2281 }
2282 /* Requesting transition from WaitForResources to Pause */
2283 else if(eState == OMX_StatePause)
2284 {
2285 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2286 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2287 OMX_COMPONENT_GENERATE_EVENT);
2288 eRet = OMX_ErrorIncorrectStateTransition;
2289 }
2290 /* Requesting transition from WaitForResources to Invalid */
2291 else if(eState == OMX_StateInvalid)
2292 {
2293 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2294 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2295 eRet = OMX_ErrorInvalidState;
2296 }
2297 /* Requesting transition from WaitForResources to Loaded -
2298 is NOT tested by Khronos TS */
2299
2300 }
2301 else
2302 {
2303 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2304 eRet = OMX_ErrorBadParameter;
2305 }
2306 }
2307 /********************************/
2308 /* Current State is Invalid */
2309 /*******************************/
2310 else if(m_state == OMX_StateInvalid)
2311 {
2312 /* State Transition from Inavlid to any state */
2313 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2314 || OMX_StateIdle || OMX_StateExecuting
2315 || OMX_StatePause || OMX_StateInvalid))
2316 {
2317 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2318 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2319 OMX_COMPONENT_GENERATE_EVENT);
2320 eRet = OMX_ErrorInvalidState;
2321 }
2322 }
2323 else if (cmd == OMX_CommandFlush)
2324 {
2325 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002326 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002327 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2328 {
2329 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2330 }
2331 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2332 {
2333 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2334 }
2335 if (!sem_posted){
2336 sem_posted = 1;
2337 DEBUG_PRINT_LOW("\n Set the Semaphore");
2338 sem_post (&m_cmd_lock);
2339 execute_omx_flush(param1);
2340 }
2341 bFlag = 0;
2342 }
2343 else if ( cmd == OMX_CommandPortEnable)
2344 {
2345 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002346 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002347 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2348 {
2349 m_inp_bEnabled = OMX_TRUE;
2350
2351 if( (m_state == OMX_StateLoaded &&
2352 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2353 || allocate_input_done())
2354 {
2355 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2356 OMX_COMPONENT_GENERATE_EVENT);
2357 }
2358 else
2359 {
2360 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2361 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2362 // Skip the event notification
2363 bFlag = 0;
2364 }
2365 }
2366 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2367 {
2368 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2369 m_out_bEnabled = OMX_TRUE;
2370
2371 if( (m_state == OMX_StateLoaded &&
2372 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2373 || (allocate_output_done()))
2374 {
2375 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2376 OMX_COMPONENT_GENERATE_EVENT);
2377
2378 }
2379 else
2380 {
2381 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2382 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2383 // Skip the event notification
2384 bFlag = 0;
2385 }
2386 }
2387 }
2388 else if (cmd == OMX_CommandPortDisable)
2389 {
2390 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002391 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002392 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2393 {
2394 m_inp_bEnabled = OMX_FALSE;
2395 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2396 && release_input_done())
2397 {
2398 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2399 OMX_COMPONENT_GENERATE_EVENT);
2400 }
2401 else
2402 {
2403 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2404 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2405 {
2406 if(!sem_posted)
2407 {
2408 sem_posted = 1;
2409 sem_post (&m_cmd_lock);
2410 }
2411 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2412 }
2413
2414 // Skip the event notification
2415 bFlag = 0;
2416 }
2417 }
2418 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2419 {
2420 m_out_bEnabled = OMX_FALSE;
2421 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2422 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2423 && release_output_done())
2424 {
2425 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2426 OMX_COMPONENT_GENERATE_EVENT);
2427 }
2428 else
2429 {
2430 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2431 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2432 {
2433 if (!sem_posted)
2434 {
2435 sem_posted = 1;
2436 sem_post (&m_cmd_lock);
2437 }
2438 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2439 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2440 }
2441 // Skip the event notification
2442 bFlag = 0;
2443
2444 }
2445 }
2446 }
2447 else
2448 {
2449 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2450 eRet = OMX_ErrorNotImplemented;
2451 }
2452 if(eRet == OMX_ErrorNone && bFlag)
2453 {
2454 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2455 }
2456 if(!sem_posted)
2457 {
2458 sem_post(&m_cmd_lock);
2459 }
2460
2461 return eRet;
2462}
2463
2464/* ======================================================================
2465FUNCTION
2466 omx_vdec::ExecuteOmxFlush
2467
2468DESCRIPTION
2469 Executes the OMX flush.
2470
2471PARAMETERS
2472 flushtype - input flush(1)/output flush(0)/ both.
2473
2474RETURN VALUE
2475 true/false
2476
2477========================================================================== */
2478bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2479{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002480 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002481 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002482 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002483 struct v4l2_decoder_cmd dec;
2484 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002485 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002486 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487 switch (flushType)
2488 {
2489 case OMX_CORE_INPUT_PORT_INDEX:
2490 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002491 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002492 break;
2493 case OMX_CORE_OUTPUT_PORT_INDEX:
2494 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002495 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002496 break;
2497 default:
2498 input_flush_progress = true;
2499 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002500 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2501 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002502 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002503
2504 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002505 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002506 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002507 bRet = false;
2508 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002509
Shalaj Jain273b3e02012-06-22 19:08:03 -07002510 return bRet;
2511}
2512/*=========================================================================
2513FUNCTION : execute_output_flush
2514
2515DESCRIPTION
2516 Executes the OMX flush at OUTPUT PORT.
2517
2518PARAMETERS
2519 None.
2520
2521RETURN VALUE
2522 true/false
2523==========================================================================*/
2524bool omx_vdec::execute_output_flush()
2525{
2526 unsigned p1 = 0; // Parameter - 1
2527 unsigned p2 = 0; // Parameter - 2
2528 unsigned ident = 0;
2529 bool bRet = true;
2530
2531 /*Generate FBD for all Buffers in the FTBq*/
2532 pthread_mutex_lock(&m_lock);
2533 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2534 while (m_ftb_q.m_size)
2535 {
2536 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2537 m_ftb_q.m_size,pending_output_buffers);
2538 m_ftb_q.pop_entry(&p1,&p2,&ident);
2539 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002540 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002541 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002542 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002543 }
2544 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2545 {
2546 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2547 }
2548 }
2549 pthread_mutex_unlock(&m_lock);
2550 output_flush_progress = false;
2551
2552 if (arbitrary_bytes)
2553 {
2554 prev_ts = LLONG_MAX;
2555 rst_prev_ts = true;
2556 }
2557 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2558 return bRet;
2559}
2560/*=========================================================================
2561FUNCTION : execute_input_flush
2562
2563DESCRIPTION
2564 Executes the OMX flush at INPUT PORT.
2565
2566PARAMETERS
2567 None.
2568
2569RETURN VALUE
2570 true/false
2571==========================================================================*/
2572bool omx_vdec::execute_input_flush()
2573{
2574 unsigned i =0;
2575 unsigned p1 = 0; // Parameter - 1
2576 unsigned p2 = 0; // Parameter - 2
2577 unsigned ident = 0;
2578 bool bRet = true;
2579
2580 /*Generate EBD for all Buffers in the ETBq*/
2581 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2582
2583 pthread_mutex_lock(&m_lock);
2584 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2585 while (m_etb_q.m_size)
2586 {
2587 m_etb_q.pop_entry(&p1,&p2,&ident);
2588
2589 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2590 {
2591 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2592 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2593 }
2594 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2595 {
2596 pending_input_buffers++;
2597 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2598 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2599 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2600 }
2601 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2602 {
2603 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2604 (OMX_BUFFERHEADERTYPE *)p1);
2605 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2606 }
2607 }
2608 time_stamp_dts.flush_timestamp();
2609 /*Check if Heap Buffers are to be flushed*/
2610 if (arbitrary_bytes)
2611 {
2612 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2613 h264_scratch.nFilledLen = 0;
2614 nal_count = 0;
2615 look_ahead_nal = false;
2616 frame_count = 0;
2617 h264_last_au_ts = LLONG_MAX;
2618 h264_last_au_flags = 0;
2619 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2620 m_demux_entries = 0;
2621 DEBUG_PRINT_LOW("\n Initialize parser");
2622 if (m_frame_parser.mutils)
2623 {
2624 m_frame_parser.mutils->initialize_frame_checking_environment();
2625 }
2626
2627 while (m_input_pending_q.m_size)
2628 {
2629 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2630 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2631 }
2632
2633 if (psource_frame)
2634 {
2635 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2636 psource_frame = NULL;
2637 }
2638
2639 if (pdest_frame)
2640 {
2641 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002642 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2643 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002644 pdest_frame = NULL;
2645 }
2646 m_frame_parser.flush();
2647 }
2648 pthread_mutex_unlock(&m_lock);
2649 input_flush_progress = false;
2650 if (!arbitrary_bytes)
2651 {
2652 prev_ts = LLONG_MAX;
2653 rst_prev_ts = true;
2654 }
2655#ifdef _ANDROID_
2656 if (m_debug_timestamp)
2657 {
2658 m_timestamp_list.reset_ts_list();
2659 }
2660#endif
2661 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2662 return bRet;
2663}
2664
2665
2666/* ======================================================================
2667FUNCTION
2668 omx_vdec::SendCommandEvent
2669
2670DESCRIPTION
2671 Send the event to decoder pipe. This is needed to generate the callbacks
2672 in decoder thread context.
2673
2674PARAMETERS
2675 None.
2676
2677RETURN VALUE
2678 true/false
2679
2680========================================================================== */
2681bool omx_vdec::post_event(unsigned int p1,
2682 unsigned int p2,
2683 unsigned int id)
2684{
2685 bool bRet = false;
2686
2687
2688 pthread_mutex_lock(&m_lock);
2689
Vinay Kaliada4f4422013-01-09 10:45:03 -08002690 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002691 id == OMX_COMPONENT_GENERATE_FBD)
2692 {
2693 m_ftb_q.insert_entry(p1,p2,id);
2694 }
2695 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2696 id == OMX_COMPONENT_GENERATE_EBD ||
2697 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2698 {
2699 m_etb_q.insert_entry(p1,p2,id);
2700 }
2701 else
2702 {
2703 m_cmd_q.insert_entry(p1,p2,id);
2704 }
2705
2706 bRet = true;
2707 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2708 post_message(this, id);
2709
2710 pthread_mutex_unlock(&m_lock);
2711
2712 return bRet;
2713}
2714
2715OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2716{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002717 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002718 if(!profileLevelType)
2719 return OMX_ErrorBadParameter;
2720
2721 if(profileLevelType->nPortIndex == 0) {
2722 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2723 {
2724 if (profileLevelType->nProfileIndex == 0)
2725 {
2726 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2727 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2728
2729 }
2730 else if (profileLevelType->nProfileIndex == 1)
2731 {
2732 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2733 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2734 }
2735 else if(profileLevelType->nProfileIndex == 2)
2736 {
2737 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2738 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2739 }
2740 else
2741 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002742 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002743 profileLevelType->nProfileIndex);
2744 eRet = OMX_ErrorNoMore;
2745 }
2746 }
2747 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2748 {
2749 if (profileLevelType->nProfileIndex == 0)
2750 {
2751 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2752 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2753 }
2754 else
2755 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002756 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002757 eRet = OMX_ErrorNoMore;
2758 }
2759 }
2760 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2761 {
2762 if (profileLevelType->nProfileIndex == 0)
2763 {
2764 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2765 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2766 }
2767 else if(profileLevelType->nProfileIndex == 1)
2768 {
2769 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2770 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2771 }
2772 else
2773 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002774 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002775 eRet = OMX_ErrorNoMore;
2776 }
2777 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002778 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2779 {
2780 eRet = OMX_ErrorNoMore;
2781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002782 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2783 {
2784 if (profileLevelType->nProfileIndex == 0)
2785 {
2786 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2787 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2788 }
2789 else if(profileLevelType->nProfileIndex == 1)
2790 {
2791 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2792 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2793 }
2794 else
2795 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002796 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002797 eRet = OMX_ErrorNoMore;
2798 }
2799 }
2800 }
2801 else
2802 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002803 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 -07002804 eRet = OMX_ErrorBadPortIndex;
2805 }
2806 return eRet;
2807}
2808
2809/* ======================================================================
2810FUNCTION
2811 omx_vdec::GetParameter
2812
2813DESCRIPTION
2814 OMX Get Parameter method implementation
2815
2816PARAMETERS
2817 <TBD>.
2818
2819RETURN VALUE
2820 Error None if successful.
2821
2822========================================================================== */
2823OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2824 OMX_IN OMX_INDEXTYPE paramIndex,
2825 OMX_INOUT OMX_PTR paramData)
2826{
2827 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2828
2829 DEBUG_PRINT_LOW("get_parameter: \n");
2830 if(m_state == OMX_StateInvalid)
2831 {
2832 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2833 return OMX_ErrorInvalidState;
2834 }
2835 if(paramData == NULL)
2836 {
2837 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2838 return OMX_ErrorBadParameter;
2839 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002840 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002841 {
2842 case OMX_IndexParamPortDefinition:
2843 {
2844 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2845 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2846 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2847 eRet = update_portdef(portDefn);
2848 if (eRet == OMX_ErrorNone)
2849 m_port_def = *portDefn;
2850 break;
2851 }
2852 case OMX_IndexParamVideoInit:
2853 {
2854 OMX_PORT_PARAM_TYPE *portParamType =
2855 (OMX_PORT_PARAM_TYPE *) paramData;
2856 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2857
2858 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2859 portParamType->nSize = sizeof(portParamType);
2860 portParamType->nPorts = 2;
2861 portParamType->nStartPortNumber = 0;
2862 break;
2863 }
2864 case OMX_IndexParamVideoPortFormat:
2865 {
2866 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2867 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2868 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2869
2870 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2871 portFmt->nSize = sizeof(portFmt);
2872
2873 if (0 == portFmt->nPortIndex)
2874 {
2875 if (0 == portFmt->nIndex)
2876 {
2877 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2878 portFmt->eCompressionFormat = eCompressionFormat;
2879 }
2880 else
2881 {
2882 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2883 " NoMore compression formats\n");
2884 eRet = OMX_ErrorNoMore;
2885 }
2886 }
2887 else if (1 == portFmt->nPortIndex)
2888 {
2889 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2890
2891 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002892 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2893 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2894 else if (1 == portFmt->nIndex)
2895 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002896 else
2897 {
2898 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2899 " NoMore Color formats\n");
2900 eRet = OMX_ErrorNoMore;
2901 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002902 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002903 }
2904 else
2905 {
2906 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2907 (int)portFmt->nPortIndex);
2908 eRet = OMX_ErrorBadPortIndex;
2909 }
2910 break;
2911 }
2912 /*Component should support this port definition*/
2913 case OMX_IndexParamAudioInit:
2914 {
2915 OMX_PORT_PARAM_TYPE *audioPortParamType =
2916 (OMX_PORT_PARAM_TYPE *) paramData;
2917 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2918 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2919 audioPortParamType->nSize = sizeof(audioPortParamType);
2920 audioPortParamType->nPorts = 0;
2921 audioPortParamType->nStartPortNumber = 0;
2922 break;
2923 }
2924 /*Component should support this port definition*/
2925 case OMX_IndexParamImageInit:
2926 {
2927 OMX_PORT_PARAM_TYPE *imagePortParamType =
2928 (OMX_PORT_PARAM_TYPE *) paramData;
2929 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2930 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2931 imagePortParamType->nSize = sizeof(imagePortParamType);
2932 imagePortParamType->nPorts = 0;
2933 imagePortParamType->nStartPortNumber = 0;
2934 break;
2935
2936 }
2937 /*Component should support this port definition*/
2938 case OMX_IndexParamOtherInit:
2939 {
2940 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2941 paramIndex);
2942 eRet =OMX_ErrorUnsupportedIndex;
2943 break;
2944 }
2945 case OMX_IndexParamStandardComponentRole:
2946 {
2947 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2948 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2949 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2950 comp_role->nSize = sizeof(*comp_role);
2951
2952 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2953 paramIndex);
2954 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2955 OMX_MAX_STRINGNAME_SIZE);
2956 break;
2957 }
2958 /* Added for parameter test */
2959 case OMX_IndexParamPriorityMgmt:
2960 {
2961
2962 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2963 (OMX_PRIORITYMGMTTYPE *) paramData;
2964 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2965 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2966 priorityMgmType->nSize = sizeof(priorityMgmType);
2967
2968 break;
2969 }
2970 /* Added for parameter test */
2971 case OMX_IndexParamCompBufferSupplier:
2972 {
2973 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2974 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2975 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2976
2977 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2978 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2979 if(0 == bufferSupplierType->nPortIndex)
2980 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2981 else if (1 == bufferSupplierType->nPortIndex)
2982 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2983 else
2984 eRet = OMX_ErrorBadPortIndex;
2985
2986
2987 break;
2988 }
2989 case OMX_IndexParamVideoAvc:
2990 {
2991 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2992 paramIndex);
2993 break;
2994 }
2995 case OMX_IndexParamVideoH263:
2996 {
2997 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2998 paramIndex);
2999 break;
3000 }
3001 case OMX_IndexParamVideoMpeg4:
3002 {
3003 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
3004 paramIndex);
3005 break;
3006 }
3007 case OMX_IndexParamVideoMpeg2:
3008 {
3009 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
3010 paramIndex);
3011 break;
3012 }
3013 case OMX_IndexParamVideoProfileLevelQuerySupported:
3014 {
3015 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
3016 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3017 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3018 eRet = get_supported_profile_level_for_1080p(profileLevelType);
3019 break;
3020 }
3021#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3022 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
3023 {
3024 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
3025 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3026 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3027
3028 if(secure_mode) {
3029 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05303030 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003031 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08003032 nativeBuffersUsage->nUsage =
3033 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
3034 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003035 }
3036 } else {
3037 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
3038 eRet = OMX_ErrorBadParameter;
3039 }
3040 }
3041 break;
3042#endif
3043
3044 default:
3045 {
3046 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
3047 eRet =OMX_ErrorUnsupportedIndex;
3048 }
3049
3050 }
3051
3052 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3053 drv_ctx.video_resolution.frame_width,
3054 drv_ctx.video_resolution.frame_height,
3055 drv_ctx.video_resolution.stride,
3056 drv_ctx.video_resolution.scan_lines);
3057
3058 return eRet;
3059}
3060
3061#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3062OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3063{
3064 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3065 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3066 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3067
3068 if((params == NULL) ||
3069 (params->nativeBuffer == NULL) ||
3070 (params->nativeBuffer->handle == NULL) ||
3071 !m_enable_android_native_buffers)
3072 return OMX_ErrorBadParameter;
3073 m_use_android_native_buffers = OMX_TRUE;
3074 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3075 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3076 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3077 OMX_U8 *buffer = NULL;
3078 if(!secure_mode) {
3079 buffer = (OMX_U8*)mmap(0, handle->size,
3080 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3081 if(buffer == MAP_FAILED) {
3082 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3083 return OMX_ErrorInsufficientResources;
3084 }
3085 }
3086 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3087 } else {
3088 eRet = OMX_ErrorBadParameter;
3089 }
3090 return eRet;
3091}
3092#endif
3093/* ======================================================================
3094FUNCTION
3095 omx_vdec::Setparameter
3096
3097DESCRIPTION
3098 OMX Set Parameter method implementation.
3099
3100PARAMETERS
3101 <TBD>.
3102
3103RETURN VALUE
3104 OMX Error None if successful.
3105
3106========================================================================== */
3107OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3108 OMX_IN OMX_INDEXTYPE paramIndex,
3109 OMX_IN OMX_PTR paramData)
3110{
3111 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003112 int ret=0;
3113 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003114 if(m_state == OMX_StateInvalid)
3115 {
3116 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3117 return OMX_ErrorInvalidState;
3118 }
3119 if(paramData == NULL)
3120 {
3121 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3122 return OMX_ErrorBadParameter;
3123 }
3124 if((m_state != OMX_StateLoaded) &&
3125 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3126 (m_out_bEnabled == OMX_TRUE) &&
3127 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3128 (m_inp_bEnabled == OMX_TRUE)) {
3129 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3130 return OMX_ErrorIncorrectStateOperation;
3131 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003132 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003133 {
3134 case OMX_IndexParamPortDefinition:
3135 {
3136 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3137 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3138 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3139 //been called.
3140 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3141 (int)portDefn->format.video.nFrameHeight,
3142 (int)portDefn->format.video.nFrameWidth);
3143 if(OMX_DirOutput == portDefn->eDir)
3144 {
3145 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3146 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003147 unsigned int buffer_size;
3148 if (!client_buffers.get_buffer_req(buffer_size)) {
3149 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003150 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003151 } else {
3152 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3153 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3154 {
3155 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3156 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3157 eRet = set_buffer_req(&drv_ctx.op_buf);
3158 if (eRet == OMX_ErrorNone)
3159 m_port_def = *portDefn;
3160 }
3161 else
3162 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003163 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003164 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3165 portDefn->nBufferCountActual, portDefn->nBufferSize);
3166 eRet = OMX_ErrorBadParameter;
3167 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003168 }
3169 }
3170 else if(OMX_DirInput == portDefn->eDir)
3171 {
3172 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3173 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3174 {
3175 // Frame rate only should be set if this is a "known value" or to
3176 // activate ts prediction logic (arbitrary mode only) sending input
3177 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003178 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003179 portDefn->format.video.xFramerate >> 16);
3180 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3181 drv_ctx.frame_rate.fps_denominator);
3182 if(!drv_ctx.frame_rate.fps_numerator)
3183 {
3184 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3185 drv_ctx.frame_rate.fps_numerator = 30;
3186 }
3187 if(drv_ctx.frame_rate.fps_denominator)
3188 drv_ctx.frame_rate.fps_numerator = (int)
3189 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3190 drv_ctx.frame_rate.fps_denominator = 1;
3191 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3192 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003193 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003194 frm_int, drv_ctx.frame_rate.fps_numerator /
3195 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07003196 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003197 }
3198 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3199 if(drv_ctx.video_resolution.frame_height !=
3200 portDefn->format.video.nFrameHeight ||
3201 drv_ctx.video_resolution.frame_width !=
3202 portDefn->format.video.nFrameWidth)
3203 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003204 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003205 portDefn->format.video.nFrameWidth,
3206 portDefn->format.video.nFrameHeight);
3207 if (portDefn->format.video.nFrameHeight != 0x0 &&
3208 portDefn->format.video.nFrameWidth != 0x0)
3209 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003210 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003211 portDefn->format.video.nFrameHeight,
3212 portDefn->format.video.nFrameWidth,
3213 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003214 eRet = is_video_session_supported();
3215 if (eRet)
3216 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003217 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3218 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3219 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3220 fmt.fmt.pix_mp.pixelformat = output_capability;
3221 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);
3222 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003223 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003224 {
3225 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3226 eRet = OMX_ErrorUnsupportedSetting;
3227 }
3228 else
3229 eRet = get_buffer_req(&drv_ctx.op_buf);
3230 }
3231 }
3232 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003233 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003234 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003235 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003236 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003237 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3238 (~(buffer_prop->alignment - 1));
3239 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003240 }
3241 else
3242 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003243 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003244 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3245 portDefn->nBufferCountActual, portDefn->nBufferSize);
3246 eRet = OMX_ErrorBadParameter;
3247 }
3248 }
3249 else if (portDefn->eDir == OMX_DirMax)
3250 {
3251 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3252 (int)portDefn->nPortIndex);
3253 eRet = OMX_ErrorBadPortIndex;
3254 }
3255 }
3256 break;
3257 case OMX_IndexParamVideoPortFormat:
3258 {
3259 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3260 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3261 int ret=0;
3262 struct v4l2_format fmt;
3263 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3264 portFmt->eColorFormat);
3265
3266 if(1 == portFmt->nPortIndex)
3267 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003268 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3269 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3270 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3271 fmt.fmt.pix_mp.pixelformat = capture_capability;
3272 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003273 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3274 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003275 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003276 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003277 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003278 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003279 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3280 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3281 else
3282 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003283
Vinay Kaliada4f4422013-01-09 10:45:03 -08003284 if(eRet == OMX_ErrorNone)
3285 {
3286 drv_ctx.output_format = op_format;
3287 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3288 if(ret)
3289 {
3290 DEBUG_PRINT_ERROR("\n Set output format failed");
3291 eRet = OMX_ErrorUnsupportedSetting;
3292 /*TODO: How to handle this case */
3293 }
3294 else
3295 {
3296 eRet = get_buffer_req(&drv_ctx.op_buf);
3297 }
3298 }
3299 if (eRet == OMX_ErrorNone){
3300 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3301 DEBUG_PRINT_ERROR("\n Set color format failed");
3302 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003303 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003304 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003305 }
3306 }
3307 break;
3308
3309 case OMX_QcomIndexPortDefn:
3310 {
3311 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3312 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003313 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003314 portFmt->nFramePackingFormat);
3315
3316 /* Input port */
3317 if (portFmt->nPortIndex == 0)
3318 {
3319 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3320 {
3321 if(secure_mode) {
3322 arbitrary_bytes = false;
3323 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3324 eRet = OMX_ErrorUnsupportedSetting;
3325 } else {
3326 arbitrary_bytes = true;
3327 }
3328 }
3329 else if (portFmt->nFramePackingFormat ==
3330 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3331 {
3332 arbitrary_bytes = false;
3333 }
3334 else
3335 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003336 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003337 portFmt->nFramePackingFormat);
3338 eRet = OMX_ErrorUnsupportedSetting;
3339 }
3340 }
3341 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3342 {
3343 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3344 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3345 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3346 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3347 {
3348 m_out_mem_region_smi = OMX_TRUE;
3349 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3350 {
3351 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3352 m_use_output_pmem = OMX_TRUE;
3353 }
3354 }
3355 }
3356 }
3357 break;
3358
3359 case OMX_IndexParamStandardComponentRole:
3360 {
3361 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3362 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3363 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3364 comp_role->cRole);
3365
3366 if((m_state == OMX_StateLoaded)&&
3367 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3368 {
3369 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3370 }
3371 else
3372 {
3373 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3374 return OMX_ErrorIncorrectStateOperation;
3375 }
3376
3377 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3378 {
3379 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3380 {
3381 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3382 }
3383 else
3384 {
3385 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3386 eRet =OMX_ErrorUnsupportedSetting;
3387 }
3388 }
3389 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3390 {
3391 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3392 {
3393 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3394 }
3395 else
3396 {
3397 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3398 eRet = OMX_ErrorUnsupportedSetting;
3399 }
3400 }
3401 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3402 {
3403 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3404 {
3405 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3406 }
3407 else
3408 {
3409 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3410 eRet =OMX_ErrorUnsupportedSetting;
3411 }
3412 }
3413 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3414 {
3415 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3416 {
3417 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3418 }
3419 else
3420 {
3421 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3422 eRet = OMX_ErrorUnsupportedSetting;
3423 }
3424 }
3425 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3426 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3427 )
3428 {
3429 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3430 {
3431 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3432 }
3433 else
3434 {
3435 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3436 eRet =OMX_ErrorUnsupportedSetting;
3437 }
3438 }
3439 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3440 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3441 )
3442 {
3443 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3444 {
3445 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3446 }
3447 else
3448 {
3449 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3450 eRet =OMX_ErrorUnsupportedSetting;
3451 }
3452 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003453 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3454 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003455 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3456 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003457 {
3458 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3459 }
3460 else
3461 {
3462 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3463 eRet = OMX_ErrorUnsupportedSetting;
3464 }
3465 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003466 else
3467 {
3468 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3469 eRet = OMX_ErrorInvalidComponentName;
3470 }
3471 break;
3472 }
3473
3474 case OMX_IndexParamPriorityMgmt:
3475 {
3476 if(m_state != OMX_StateLoaded)
3477 {
3478 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3479 return OMX_ErrorIncorrectStateOperation;
3480 }
3481 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003482 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003483 priorityMgmtype->nGroupID);
3484
Shalaj Jainaf08f302013-03-18 13:15:35 -07003485 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003486 priorityMgmtype->nGroupPriority);
3487
3488 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3489 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3490
3491 break;
3492 }
3493
3494 case OMX_IndexParamCompBufferSupplier:
3495 {
3496 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3497 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3498 bufferSupplierType->eBufferSupplier);
3499 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3500 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3501
3502 else
3503
3504 eRet = OMX_ErrorBadPortIndex;
3505
3506 break;
3507
3508 }
3509 case OMX_IndexParamVideoAvc:
3510 {
3511 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3512 paramIndex);
3513 break;
3514 }
3515 case OMX_IndexParamVideoH263:
3516 {
3517 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3518 paramIndex);
3519 break;
3520 }
3521 case OMX_IndexParamVideoMpeg4:
3522 {
3523 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3524 paramIndex);
3525 break;
3526 }
3527 case OMX_IndexParamVideoMpeg2:
3528 {
3529 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3530 paramIndex);
3531 break;
3532 }
3533 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3534 {
3535 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3536 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003537 struct v4l2_control control;
3538 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003539 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3540 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003541 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3542 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3543 }
3544 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3545 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003546 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003547 }
3548 else
3549 eRet = OMX_ErrorBadParameter;
3550 if (eRet == OMX_ErrorNone)
3551 {
3552 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3553 control.value = pic_order;
3554 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3555 if(rc)
3556 {
3557 DEBUG_PRINT_ERROR("\n Set picture order failed");
3558 eRet = OMX_ErrorUnsupportedSetting;
3559 }
3560 }
3561 break;
3562 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003563 case OMX_QcomIndexParamConcealMBMapExtraData:
3564 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003565 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003566 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3567 else {
3568 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3569 eRet = OMX_ErrorUnsupportedSetting;
3570 }
3571 break;
3572 case OMX_QcomIndexParamFrameInfoExtraData:
3573 {
3574 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003575 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003576 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3577 else {
3578 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3579 eRet = OMX_ErrorUnsupportedSetting;
3580 }
3581 break;
3582 }
3583 case OMX_QcomIndexParamInterlaceExtraData:
3584 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003585 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003586 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3587 else {
3588 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3589 eRet = OMX_ErrorUnsupportedSetting;
3590 }
3591 break;
3592 case OMX_QcomIndexParamH264TimeInfo:
3593 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003594 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003595 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3596 else {
3597 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3598 eRet = OMX_ErrorUnsupportedSetting;
3599 }
3600 break;
3601 case OMX_QcomIndexParamVideoDivx:
3602 {
3603 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003604 }
3605 break;
3606 case OMX_QcomIndexPlatformPvt:
3607 {
3608 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3609 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3610 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3611 {
3612 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3613 eRet = OMX_ErrorUnsupportedSetting;
3614 }
3615 else
3616 {
3617 m_out_pvt_entry_pmem = OMX_TRUE;
3618 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3619 {
3620 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3621 m_use_output_pmem = OMX_TRUE;
3622 }
3623 }
3624
3625 }
3626 break;
3627 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3628 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003629 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3630 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3631 struct v4l2_control control;
3632 int rc;
3633 drv_ctx.idr_only_decoding = 1;
3634 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3635 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3636 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3637 if(rc)
3638 {
3639 DEBUG_PRINT_ERROR("\n Set picture order failed");
3640 eRet = OMX_ErrorUnsupportedSetting;
3641 } else {
3642 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3643 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3644 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3645 if(rc)
3646 {
3647 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3648 eRet = OMX_ErrorUnsupportedSetting;
3649 }
3650 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003651 }
3652 break;
3653
3654 case OMX_QcomIndexParamIndexExtraDataType:
3655 {
3656 if(!secure_mode) {
3657 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3658 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3659 (extradataIndexType->bEnabled == OMX_TRUE) &&
3660 (extradataIndexType->nPortIndex == 1))
3661 {
3662 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003663 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003664
Shalaj Jain273b3e02012-06-22 19:08:03 -07003665 }
3666 }
3667 }
3668 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003669 case OMX_QcomIndexParamEnableSmoothStreaming:
3670 {
3671 struct v4l2_control control;
3672 struct v4l2_format fmt;
3673 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3674 control.value = 1;
3675 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3676 if(rc < 0) {
3677 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3678 eRet = OMX_ErrorHardware;
3679 }
3680 }
3681 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003682#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3683 /* Need to allow following two set_parameters even in Idle
3684 * state. This is ANDROID architecture which is not in sync
3685 * with openmax standard. */
3686 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3687 {
3688 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3689 if(enableNativeBuffers) {
3690 m_enable_android_native_buffers = enableNativeBuffers->enable;
3691 }
3692 }
3693 break;
3694 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3695 {
3696 eRet = use_android_native_buffer(hComp, paramData);
3697 }
3698 break;
3699#endif
3700 case OMX_QcomIndexParamEnableTimeStampReorder:
3701 {
3702 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003703 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003704 if (reorder->bEnable == OMX_TRUE) {
3705 frm_int =0;
3706 time_stamp_dts.set_timestamp_reorder_mode(true);
3707 }
3708 else
3709 time_stamp_dts.set_timestamp_reorder_mode(false);
3710 } else {
3711 time_stamp_dts.set_timestamp_reorder_mode(false);
3712 if (reorder->bEnable == OMX_TRUE)
3713 {
3714 eRet = OMX_ErrorUnsupportedSetting;
3715 }
3716 }
3717 }
3718 break;
3719 default:
3720 {
3721 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3722 eRet = OMX_ErrorUnsupportedIndex;
3723 }
3724 }
3725 return eRet;
3726}
3727
3728/* ======================================================================
3729FUNCTION
3730 omx_vdec::GetConfig
3731
3732DESCRIPTION
3733 OMX Get Config Method implementation.
3734
3735PARAMETERS
3736 <TBD>.
3737
3738RETURN VALUE
3739 OMX Error None if successful.
3740
3741========================================================================== */
3742OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3743 OMX_IN OMX_INDEXTYPE configIndex,
3744 OMX_INOUT OMX_PTR configData)
3745{
3746 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3747
3748 if (m_state == OMX_StateInvalid)
3749 {
3750 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3751 return OMX_ErrorInvalidState;
3752 }
3753
Shalaj Jain286b0062013-02-21 20:35:48 -08003754 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003755 {
3756 case OMX_QcomIndexConfigInterlaced:
3757 {
3758 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3759 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3760 if (configFmt->nPortIndex == 1)
3761 {
3762 if (configFmt->nIndex == 0)
3763 {
3764 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3765 }
3766 else if (configFmt->nIndex == 1)
3767 {
3768 configFmt->eInterlaceType =
3769 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3770 }
3771 else if (configFmt->nIndex == 2)
3772 {
3773 configFmt->eInterlaceType =
3774 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3775 }
3776 else
3777 {
3778 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3779 " NoMore Interlaced formats\n");
3780 eRet = OMX_ErrorNoMore;
3781 }
3782
3783 }
3784 else
3785 {
3786 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3787 (int)configFmt->nPortIndex);
3788 eRet = OMX_ErrorBadPortIndex;
3789 }
3790 break;
3791 }
3792 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3793 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003794 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3795 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003796 decoderinstances->nNumOfInstances = 16;
3797 /*TODO: How to handle this case */
3798 break;
3799 }
3800 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3801 {
3802 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3803 {
3804 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3805 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3806 h264_parser->get_frame_pack_data(configFmt);
3807 }
3808 else
3809 {
3810 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3811 }
3812 break;
3813 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003814 case OMX_IndexConfigCommonOutputCrop:
3815 {
3816 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3817 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3818 break;
3819 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003820 default:
3821 {
3822 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3823 eRet = OMX_ErrorBadParameter;
3824 }
3825
3826 }
3827
3828 return eRet;
3829}
3830
3831/* ======================================================================
3832FUNCTION
3833 omx_vdec::SetConfig
3834
3835DESCRIPTION
3836 OMX Set Config method implementation
3837
3838PARAMETERS
3839 <TBD>.
3840
3841RETURN VALUE
3842 OMX Error None if successful.
3843========================================================================== */
3844OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3845 OMX_IN OMX_INDEXTYPE configIndex,
3846 OMX_IN OMX_PTR configData)
3847{
3848 if(m_state == OMX_StateInvalid)
3849 {
3850 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3851 return OMX_ErrorInvalidState;
3852 }
3853
3854 OMX_ERRORTYPE ret = OMX_ErrorNone;
3855 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3856
3857 DEBUG_PRINT_LOW("\n Set Config Called");
3858
3859 if (m_state == OMX_StateExecuting)
3860 {
3861 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3862 return ret;
3863 }
3864
Shalaj Jain286b0062013-02-21 20:35:48 -08003865 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003866 {
3867 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3868 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3869 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3870 {
3871 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3872 OMX_U32 extra_size;
3873 // Parsing done here for the AVC atom is definitely not generic
3874 // Currently this piece of code is working, but certainly
3875 // not tested with all .mp4 files.
3876 // Incase of failure, we might need to revisit this
3877 // for a generic piece of code.
3878
3879 // Retrieve size of NAL length field
3880 // byte #4 contains the size of NAL lenght field
3881 nal_length = (config->pData[4] & 0x03) + 1;
3882
3883 extra_size = 0;
3884 if (nal_length > 2)
3885 {
3886 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3887 extra_size = (nal_length - 2) * 2;
3888 }
3889
3890 // SPS starts from byte #6
3891 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3892 OMX_U8 *pDestBuf;
3893 m_vendor_config.nPortIndex = config->nPortIndex;
3894
3895 // minus 6 --> SPS starts from byte #6
3896 // minus 1 --> picture param set byte to be ignored from avcatom
3897 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3898 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3899 OMX_U32 len;
3900 OMX_U8 index = 0;
3901 // case where SPS+PPS is sent as part of set_config
3902 pDestBuf = m_vendor_config.pData;
3903
Shalaj Jainaf08f302013-03-18 13:15:35 -07003904 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003905 m_vendor_config.nPortIndex,
3906 m_vendor_config.nDataSize,
3907 m_vendor_config.pData);
3908 while (index < 2)
3909 {
3910 uint8 *psize;
3911 len = *pSrcBuf;
3912 len = len << 8;
3913 len |= *(pSrcBuf + 1);
3914 psize = (uint8 *) & len;
3915 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003916 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003917 {
3918 pDestBuf[i] = psize[nal_length - 1 - i];
3919 }
3920 //memcpy(pDestBuf,pSrcBuf,(len+2));
3921 pDestBuf += len + nal_length;
3922 pSrcBuf += len + 2;
3923 index++;
3924 pSrcBuf++; // skip picture param set
3925 len = 0;
3926 }
3927 }
3928 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3929 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3930 {
3931 m_vendor_config.nPortIndex = config->nPortIndex;
3932 m_vendor_config.nDataSize = config->nDataSize;
3933 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3934 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3935 }
3936 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3937 {
3938 if(m_vendor_config.pData)
3939 {
3940 free(m_vendor_config.pData);
3941 m_vendor_config.pData = NULL;
3942 m_vendor_config.nDataSize = 0;
3943 }
3944
3945 if (((*((OMX_U32 *) config->pData)) &
3946 VC1_SP_MP_START_CODE_MASK) ==
3947 VC1_SP_MP_START_CODE)
3948 {
3949 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3950 m_vendor_config.nPortIndex = config->nPortIndex;
3951 m_vendor_config.nDataSize = config->nDataSize;
3952 m_vendor_config.pData =
3953 (OMX_U8 *) malloc(config->nDataSize);
3954 memcpy(m_vendor_config.pData, config->pData,
3955 config->nDataSize);
3956 m_vc1_profile = VC1_SP_MP_RCV;
3957 }
3958 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3959 {
3960 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3961 m_vendor_config.nPortIndex = config->nPortIndex;
3962 m_vendor_config.nDataSize = config->nDataSize;
3963 m_vendor_config.pData =
3964 (OMX_U8 *) malloc((config->nDataSize));
3965 memcpy(m_vendor_config.pData, config->pData,
3966 config->nDataSize);
3967 m_vc1_profile = VC1_AP;
3968 }
3969 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3970 {
3971 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3972 m_vendor_config.nPortIndex = config->nPortIndex;
3973 m_vendor_config.nDataSize = config->nDataSize;
3974 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3975 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3976 m_vc1_profile = VC1_SP_MP_RCV;
3977 }
3978 else
3979 {
3980 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3981 }
3982 }
3983 return ret;
3984 }
3985 else if (configIndex == OMX_IndexConfigVideoNalSize)
3986 {
3987
3988 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3989 nal_length = pNal->nNaluBytes;
3990 m_frame_parser.init_nal_length(nal_length);
3991 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3992 return ret;
3993 }
3994
3995 return OMX_ErrorNotImplemented;
3996}
3997
3998/* ======================================================================
3999FUNCTION
4000 omx_vdec::GetExtensionIndex
4001
4002DESCRIPTION
4003 OMX GetExtensionIndex method implementaion. <TBD>
4004
4005PARAMETERS
4006 <TBD>.
4007
4008RETURN VALUE
4009 OMX Error None if everything successful.
4010
4011========================================================================== */
4012OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4013 OMX_IN OMX_STRING paramName,
4014 OMX_OUT OMX_INDEXTYPE* indexType)
4015{
4016 if(m_state == OMX_StateInvalid)
4017 {
4018 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
4019 return OMX_ErrorInvalidState;
4020 }
4021 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
4022 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
4023 }
4024 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
4025 {
4026 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
4027 }
4028#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4029 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
4030 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
4031 }
4032 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
4033 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
4034 }
4035 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
4036 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
4037 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
4038 }
4039 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
4040 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4041 }
4042#endif
4043 else {
4044 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
4045 return OMX_ErrorNotImplemented;
4046 }
4047 return OMX_ErrorNone;
4048}
4049
4050/* ======================================================================
4051FUNCTION
4052 omx_vdec::GetState
4053
4054DESCRIPTION
4055 Returns the state information back to the caller.<TBD>
4056
4057PARAMETERS
4058 <TBD>.
4059
4060RETURN VALUE
4061 Error None if everything is successful.
4062========================================================================== */
4063OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4064 OMX_OUT OMX_STATETYPE* state)
4065{
4066 *state = m_state;
4067 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4068 return OMX_ErrorNone;
4069}
4070
4071/* ======================================================================
4072FUNCTION
4073 omx_vdec::ComponentTunnelRequest
4074
4075DESCRIPTION
4076 OMX Component Tunnel Request method implementation. <TBD>
4077
4078PARAMETERS
4079 None.
4080
4081RETURN VALUE
4082 OMX Error None if everything successful.
4083
4084========================================================================== */
4085OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4086 OMX_IN OMX_U32 port,
4087 OMX_IN OMX_HANDLETYPE peerComponent,
4088 OMX_IN OMX_U32 peerPort,
4089 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4090{
4091 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4092 return OMX_ErrorNotImplemented;
4093}
4094
4095/* ======================================================================
4096FUNCTION
4097 omx_vdec::UseOutputBuffer
4098
4099DESCRIPTION
4100 Helper function for Use buffer in the input pin
4101
4102PARAMETERS
4103 None.
4104
4105RETURN VALUE
4106 true/false
4107
4108========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004109OMX_ERRORTYPE omx_vdec::allocate_extradata()
4110{
4111#ifdef USE_ION
4112 if (drv_ctx.extradata_info.buffer_size) {
4113 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4114 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4115 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4116 free_ion_memory(&drv_ctx.extradata_info.ion);
4117 }
4118 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4119 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4120 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4121 &drv_ctx.extradata_info.ion.ion_alloc_data,
4122 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4123 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4124 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4125 return OMX_ErrorInsufficientResources;
4126 }
4127 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4128 drv_ctx.extradata_info.size,
4129 PROT_READ|PROT_WRITE, MAP_SHARED,
4130 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4131 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4132 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4133 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4134 free_ion_memory(&drv_ctx.extradata_info.ion);
4135 return OMX_ErrorInsufficientResources;
4136 }
4137 }
4138#endif
4139 return OMX_ErrorNone;
4140}
4141
4142void omx_vdec::free_extradata() {
4143#ifdef USE_ION
4144 if (drv_ctx.extradata_info.uaddr) {
4145 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4146 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4147 free_ion_memory(&drv_ctx.extradata_info.ion);
4148 }
4149 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4150#endif
4151}
4152
Shalaj Jain273b3e02012-06-22 19:08:03 -07004153OMX_ERRORTYPE omx_vdec::use_output_buffer(
4154 OMX_IN OMX_HANDLETYPE hComp,
4155 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4156 OMX_IN OMX_U32 port,
4157 OMX_IN OMX_PTR appData,
4158 OMX_IN OMX_U32 bytes,
4159 OMX_IN OMX_U8* buffer)
4160{
4161 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4162 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4163 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004164 struct vdec_setbuffer_cmd setbuffers;
4165 OMX_PTR privateAppData = NULL;
4166 private_handle_t *handle = NULL;
4167 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004168 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004169 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4170 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004171
Shalaj Jain273b3e02012-06-22 19:08:03 -07004172 if (!m_out_mem_ptr) {
4173 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4174 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004175 if (eRet == OMX_ErrorNone)
4176 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004177 }
4178
4179 if (eRet == OMX_ErrorNone) {
4180 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4181 if(BITMASK_ABSENT(&m_out_bm_count,i))
4182 {
4183 break;
4184 }
4185 }
4186 }
4187
4188 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004189 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004190 eRet = OMX_ErrorInsufficientResources;
4191 }
4192
4193 if (eRet == OMX_ErrorNone) {
4194#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4195 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004196 if (m_use_android_native_buffers) {
4197 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4198 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4199 handle = (private_handle_t *)nBuf->handle;
4200 privateAppData = params->pAppPrivate;
4201 } else {
4202 handle = (private_handle_t *)buff;
4203 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004204 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004205
4206 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4207 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4208 " expected %u, got %lu",
4209 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4210 return OMX_ErrorBadParameter;
4211 }
4212
4213 if (!m_use_android_native_buffers) {
4214 if (!secure_mode) {
4215 buff = (OMX_U8*)mmap(0, handle->size,
4216 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4217 if (buff == MAP_FAILED) {
4218 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4219 return OMX_ErrorInsufficientResources;
4220 }
4221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004222 }
4223#if defined(_ANDROID_ICS_)
4224 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004225 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226#endif
4227 if(!handle) {
4228 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4229 return OMX_ErrorBadParameter;
4230 }
4231 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4232 drv_ctx.ptr_outputbuffer[i].offset = 0;
4233 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4234 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4235 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4236 } else
4237#endif
4238
4239 if (!ouput_egl_buffers && !m_use_output_pmem) {
4240#ifdef USE_ION
4241 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4242 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4243 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004244 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004245 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004246 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 -07004247 return OMX_ErrorInsufficientResources;
4248 }
4249 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4250 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4251#else
4252 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4253 open (MEM_DEVICE,O_RDWR);
4254
4255 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004256 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 -07004257 return OMX_ErrorInsufficientResources;
4258 }
4259
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004260 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004261 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4262 {
4263 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4264 open (MEM_DEVICE,O_RDWR);
4265 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004266 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 -07004267 return OMX_ErrorInsufficientResources;
4268 }
4269 }
4270
4271 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4272 drv_ctx.op_buf.buffer_size,
4273 drv_ctx.op_buf.alignment))
4274 {
4275 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4276 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4277 return OMX_ErrorInsufficientResources;
4278 }
4279#endif
4280 if(!secure_mode) {
4281 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4282 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4283 PROT_READ|PROT_WRITE, MAP_SHARED,
4284 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4285 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4286 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4287#ifdef USE_ION
4288 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4289#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004290 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291 return OMX_ErrorInsufficientResources;
4292 }
4293 }
4294 drv_ctx.ptr_outputbuffer[i].offset = 0;
4295 privateAppData = appData;
4296 }
4297 else {
4298
4299 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4300 if (!appData || !bytes ) {
4301 if(!secure_mode && !buffer) {
4302 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4303 return OMX_ErrorBadParameter;
4304 }
4305 }
4306
4307 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4308 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4309 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4310 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4311 !pmem_list->nEntries ||
4312 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4313 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4314 return OMX_ErrorBadParameter;
4315 }
4316 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4317 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004318 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004319 pmem_info->pmem_fd);
4320 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4321 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4322 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4323 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4324 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4325 privateAppData = appData;
4326 }
4327 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4328 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4329
4330 *bufferHdr = (m_out_mem_ptr + i );
4331 if(secure_mode)
4332 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4333 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4334 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4335 sizeof (vdec_bufferpayload));
4336
Shalaj Jain286b0062013-02-21 20:35:48 -08004337 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4338 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4339 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004340
4341 buf.index = i;
4342 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4343 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004344 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004345 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4346 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004347 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4348 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4349 plane[0].data_offset = 0;
4350 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4351 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4352 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4353 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4354#ifdef USE_ION
4355 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4356#endif
4357 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4358 plane[extra_idx].data_offset = 0;
4359 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4360 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4361 return OMX_ErrorBadParameter;
4362 }
4363 buf.m.planes = plane;
4364 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004365
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004366 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4367 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4368 /*TODO: How to handle this case */
4369 return OMX_ErrorInsufficientResources;
4370 }
4371
4372 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4373 enum v4l2_buf_type buf_type;
4374 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4375 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4376 return OMX_ErrorInsufficientResources;
4377 } else {
4378 streaming[CAPTURE_PORT] = true;
4379 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4380 }
4381 }
4382
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004384 if (m_enable_android_native_buffers) {
4385 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4386 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4387 } else {
4388 (*bufferHdr)->pBuffer = buff;
4389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004390 (*bufferHdr)->pAppPrivate = privateAppData;
4391 BITMASK_SET(&m_out_bm_count,i);
4392 }
4393 return eRet;
4394}
4395
4396/* ======================================================================
4397FUNCTION
4398 omx_vdec::use_input_heap_buffers
4399
4400DESCRIPTION
4401 OMX Use Buffer Heap allocation method implementation.
4402
4403PARAMETERS
4404 <TBD>.
4405
4406RETURN VALUE
4407 OMX Error None , if everything successful.
4408
4409========================================================================== */
4410OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4411 OMX_IN OMX_HANDLETYPE hComp,
4412 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4413 OMX_IN OMX_U32 port,
4414 OMX_IN OMX_PTR appData,
4415 OMX_IN OMX_U32 bytes,
4416 OMX_IN OMX_U8* buffer)
4417{
4418 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4419 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4420 if(!m_inp_heap_ptr)
4421 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4422 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4423 drv_ctx.ip_buf.actualcount);
4424 if(!m_phdr_pmem_ptr)
4425 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4426 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4427 drv_ctx.ip_buf.actualcount);
4428 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4429 {
4430 DEBUG_PRINT_ERROR("Insufficent memory");
4431 eRet = OMX_ErrorInsufficientResources;
4432 }
4433 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4434 {
4435 input_use_buffer = true;
4436 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4437 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4438 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4439 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4440 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4441 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4442 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4443 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4444 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 -08004445 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4446 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004447 {
4448 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4449 return OMX_ErrorInsufficientResources;
4450 }
4451 m_in_alloc_cnt++;
4452 }
4453 else
4454 {
4455 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4456 eRet = OMX_ErrorInsufficientResources;
4457 }
4458 return eRet;
4459}
4460
4461/* ======================================================================
4462FUNCTION
4463 omx_vdec::UseBuffer
4464
4465DESCRIPTION
4466 OMX Use Buffer method implementation.
4467
4468PARAMETERS
4469 <TBD>.
4470
4471RETURN VALUE
4472 OMX Error None , if everything successful.
4473
4474========================================================================== */
4475OMX_ERRORTYPE omx_vdec::use_buffer(
4476 OMX_IN OMX_HANDLETYPE hComp,
4477 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4478 OMX_IN OMX_U32 port,
4479 OMX_IN OMX_PTR appData,
4480 OMX_IN OMX_U32 bytes,
4481 OMX_IN OMX_U8* buffer)
4482{
4483 OMX_ERRORTYPE error = OMX_ErrorNone;
4484 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004485
4486 if (bufferHdr == NULL || bytes == 0)
4487 {
4488 if(!secure_mode && buffer == NULL) {
4489 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4490 return OMX_ErrorBadParameter;
4491 }
4492 }
4493 if(m_state == OMX_StateInvalid)
4494 {
4495 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4496 return OMX_ErrorInvalidState;
4497 }
4498 if(port == OMX_CORE_INPUT_PORT_INDEX)
4499 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4500 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4501 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4502 else
4503 {
4504 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4505 error = OMX_ErrorBadPortIndex;
4506 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004507 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004508 if(error == OMX_ErrorNone)
4509 {
4510 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4511 {
4512 // Send the callback now
4513 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4514 post_event(OMX_CommandStateSet,OMX_StateIdle,
4515 OMX_COMPONENT_GENERATE_EVENT);
4516 }
4517 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4518 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4519 {
4520 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4521 post_event(OMX_CommandPortEnable,
4522 OMX_CORE_INPUT_PORT_INDEX,
4523 OMX_COMPONENT_GENERATE_EVENT);
4524 }
4525 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4526 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4527 {
4528 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4529 post_event(OMX_CommandPortEnable,
4530 OMX_CORE_OUTPUT_PORT_INDEX,
4531 OMX_COMPONENT_GENERATE_EVENT);
4532 }
4533 }
4534 return error;
4535}
4536
4537OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4538 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4539{
4540 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4541 {
4542 if(m_inp_heap_ptr[bufferindex].pBuffer)
4543 free(m_inp_heap_ptr[bufferindex].pBuffer);
4544 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4545 }
4546 if (pmem_bufferHdr)
4547 free_input_buffer(pmem_bufferHdr);
4548 return OMX_ErrorNone;
4549}
4550
4551OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4552{
4553 unsigned int index = 0;
4554 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4555 {
4556 return OMX_ErrorBadParameter;
4557 }
4558
4559 index = bufferHdr - m_inp_mem_ptr;
4560 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4561
4562 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4563 {
4564 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4565 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4566 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004567 struct vdec_setbuffer_cmd setbuffers;
4568 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4569 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4570 sizeof (vdec_bufferpayload));
Praveen Chavan212671f2013-04-05 20:00:42 -07004571 if(!secure_mode) {
4572 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4573 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4574 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4575 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4576 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4577 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4578 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4579 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4581 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4582 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4583 {
4584 free(m_desc_buffer_ptr[index].buf_addr);
4585 m_desc_buffer_ptr[index].buf_addr = NULL;
4586 m_desc_buffer_ptr[index].desc_data_size = 0;
4587 }
4588#ifdef USE_ION
4589 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4590#endif
4591 }
4592 }
4593
4594 return OMX_ErrorNone;
4595}
4596
4597OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4598{
4599 unsigned int index = 0;
4600
4601 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4602 {
4603 return OMX_ErrorBadParameter;
4604 }
4605
4606 index = bufferHdr - m_out_mem_ptr;
4607 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4608
4609 if (index < drv_ctx.op_buf.actualcount
4610 && drv_ctx.ptr_outputbuffer)
4611 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004612 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004613 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4614
Shalaj Jain273b3e02012-06-22 19:08:03 -07004615 struct vdec_setbuffer_cmd setbuffers;
4616 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4617 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4618 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004619#ifdef _ANDROID_
4620 if(m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004621 if (!secure_mode) {
4622 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4623 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4624 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4625 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004626 }
4627 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4628 } else {
4629#endif
4630 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4631 {
Praveen Chavan212671f2013-04-05 20:00:42 -07004632 if (!secure_mode) {
4633 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4634 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4635 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4636 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4637 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4638 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4639 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4640 }
4641 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4642 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004643#ifdef USE_ION
Praveen Chavan212671f2013-04-05 20:00:42 -07004644 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645#endif
4646 }
4647#ifdef _ANDROID_
4648 }
4649#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004650 if (release_output_done()) {
4651 free_extradata();
4652 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004653 }
4654
4655 return OMX_ErrorNone;
4656
4657}
4658
4659OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4660 OMX_BUFFERHEADERTYPE **bufferHdr,
4661 OMX_U32 port,
4662 OMX_PTR appData,
4663 OMX_U32 bytes)
4664{
4665 OMX_BUFFERHEADERTYPE *input = NULL;
4666 unsigned char *buf_addr = NULL;
4667 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4668 unsigned i = 0;
4669
4670 /* Sanity Check*/
4671 if (bufferHdr == NULL)
4672 {
4673 return OMX_ErrorBadParameter;
4674 }
4675
4676 if (m_inp_heap_ptr == NULL)
4677 {
4678 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4679 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4680 drv_ctx.ip_buf.actualcount);
4681 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4682 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4683 drv_ctx.ip_buf.actualcount);
4684
4685 if (m_inp_heap_ptr == NULL)
4686 {
4687 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4688 return OMX_ErrorInsufficientResources;
4689 }
4690 }
4691
4692 /*Find a Free index*/
4693 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4694 {
4695 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4696 {
4697 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4698 break;
4699 }
4700 }
4701
4702 if (i < drv_ctx.ip_buf.actualcount)
4703 {
4704 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4705
4706 if (buf_addr == NULL)
4707 {
4708 return OMX_ErrorInsufficientResources;
4709 }
4710
4711 *bufferHdr = (m_inp_heap_ptr + i);
4712 input = *bufferHdr;
4713 BITMASK_SET(&m_heap_inp_bm_count,i);
4714
4715 input->pBuffer = (OMX_U8 *)buf_addr;
4716 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4717 input->nVersion.nVersion = OMX_SPEC_VERSION;
4718 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4719 input->pAppPrivate = appData;
4720 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4721 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4722 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004723 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004724 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004725 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4726 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004727 {
4728 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4729 return OMX_ErrorInsufficientResources;
4730 }
4731 }
4732 else
4733 {
4734 return OMX_ErrorBadParameter;
4735 }
4736
4737 return eRet;
4738
4739}
4740
4741
4742/* ======================================================================
4743FUNCTION
4744 omx_vdec::AllocateInputBuffer
4745
4746DESCRIPTION
4747 Helper function for allocate buffer in the input pin
4748
4749PARAMETERS
4750 None.
4751
4752RETURN VALUE
4753 true/false
4754
4755========================================================================== */
4756OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4757 OMX_IN OMX_HANDLETYPE hComp,
4758 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4759 OMX_IN OMX_U32 port,
4760 OMX_IN OMX_PTR appData,
4761 OMX_IN OMX_U32 bytes)
4762{
4763
4764 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4765 struct vdec_setbuffer_cmd setbuffers;
4766 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004767 unsigned i = 0;
4768 unsigned char *buf_addr = NULL;
4769 int pmem_fd = -1;
4770
4771 if(bytes != drv_ctx.ip_buf.buffer_size)
4772 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004773 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004774 bytes, drv_ctx.ip_buf.buffer_size);
4775 return OMX_ErrorBadParameter;
4776 }
4777
4778 if(!m_inp_mem_ptr)
4779 {
4780 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4781 drv_ctx.ip_buf.actualcount,
4782 drv_ctx.ip_buf.buffer_size);
4783
4784 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4785 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4786
4787 if (m_inp_mem_ptr == NULL)
4788 {
4789 return OMX_ErrorInsufficientResources;
4790 }
4791
4792 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4793 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4794
4795 if (drv_ctx.ptr_inputbuffer == NULL)
4796 {
4797 return OMX_ErrorInsufficientResources;
4798 }
4799#ifdef USE_ION
4800 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4801 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4802
4803 if (drv_ctx.ip_buf_ion_info == NULL)
4804 {
4805 return OMX_ErrorInsufficientResources;
4806 }
4807#endif
4808
4809 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4810 {
4811 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4812#ifdef USE_ION
4813 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4814#endif
4815 }
4816 }
4817
4818 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4819 {
4820 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4821 {
4822 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4823 break;
4824 }
4825 }
4826
4827 if(i < drv_ctx.ip_buf.actualcount)
4828 {
4829 struct v4l2_buffer buf;
4830 struct v4l2_plane plane;
4831 int rc;
4832 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4833#ifdef USE_ION
4834 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4835 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4836 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004837 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004838 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4839 return OMX_ErrorInsufficientResources;
4840 }
4841 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4842#else
4843 pmem_fd = open (MEM_DEVICE,O_RDWR);
4844
4845 if (pmem_fd < 0)
4846 {
4847 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4848 return OMX_ErrorInsufficientResources;
4849 }
4850
4851 if (pmem_fd == 0)
4852 {
4853 pmem_fd = open (MEM_DEVICE,O_RDWR);
4854
4855 if (pmem_fd < 0)
4856 {
4857 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4858 return OMX_ErrorInsufficientResources;
4859 }
4860 }
4861
4862 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4863 drv_ctx.ip_buf.alignment))
4864 {
4865 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4866 close(pmem_fd);
4867 return OMX_ErrorInsufficientResources;
4868 }
4869#endif
4870 if (!secure_mode) {
4871 buf_addr = (unsigned char *)mmap(NULL,
4872 drv_ctx.ip_buf.buffer_size,
4873 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4874
4875 if (buf_addr == MAP_FAILED)
4876 {
4877 close(pmem_fd);
4878#ifdef USE_ION
4879 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4880#endif
4881 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4882 return OMX_ErrorInsufficientResources;
4883 }
4884 }
4885 *bufferHdr = (m_inp_mem_ptr + i);
4886 if (secure_mode)
4887 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4888 else
4889 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4890 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4891 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4892 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4893 drv_ctx.ptr_inputbuffer [i].offset = 0;
4894
4895
4896 buf.index = i;
4897 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4898 buf.memory = V4L2_MEMORY_USERPTR;
4899 plane.bytesused = 0;
4900 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4901 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4902 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4903 plane.reserved[1] = 0;
4904 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4905 buf.m.planes = &plane;
4906 buf.length = 1;
4907
Shalaj Jainaf08f302013-03-18 13:15:35 -07004908 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4909 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910
4911 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4912
4913 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004914 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915 /*TODO: How to handle this case */
4916 return OMX_ErrorInsufficientResources;
4917 }
4918
4919 input = *bufferHdr;
4920 BITMASK_SET(&m_inp_bm_count,i);
4921 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4922 if (secure_mode)
4923 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4924 else
4925 input->pBuffer = (OMX_U8 *)buf_addr;
4926 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4927 input->nVersion.nVersion = OMX_SPEC_VERSION;
4928 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4929 input->pAppPrivate = appData;
4930 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4931 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4932
4933 if (drv_ctx.disable_dmx)
4934 {
4935 eRet = allocate_desc_buffer(i);
4936 }
4937 }
4938 else
4939 {
4940 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4941 eRet = OMX_ErrorInsufficientResources;
4942 }
4943 return eRet;
4944}
4945
4946
4947/* ======================================================================
4948FUNCTION
4949 omx_vdec::AllocateOutputBuffer
4950
4951DESCRIPTION
4952 Helper fn for AllocateBuffer in the output pin
4953
4954PARAMETERS
4955 <TBD>.
4956
4957RETURN VALUE
4958 OMX Error None if everything went well.
4959
4960========================================================================== */
4961OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4962 OMX_IN OMX_HANDLETYPE hComp,
4963 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4964 OMX_IN OMX_U32 port,
4965 OMX_IN OMX_PTR appData,
4966 OMX_IN OMX_U32 bytes)
4967{
4968 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4969 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4970 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004971 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004972 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004973#ifdef USE_ION
4974 int ion_device_fd =-1;
4975 struct ion_allocation_data ion_alloc_data;
4976 struct ion_fd_data fd_ion_data;
4977#endif
4978 if(!m_out_mem_ptr)
4979 {
4980 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4981 drv_ctx.op_buf.actualcount,
4982 drv_ctx.op_buf.buffer_size);
4983 int nBufHdrSize = 0;
4984 int nPlatformEntrySize = 0;
4985 int nPlatformListSize = 0;
4986 int nPMEMInfoSize = 0;
4987 int pmem_fd = -1;
4988 unsigned char *pmem_baseaddress = NULL;
4989
4990 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4991 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4992 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4993
4994 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4995 drv_ctx.op_buf.actualcount);
4996 nBufHdrSize = drv_ctx.op_buf.actualcount *
4997 sizeof(OMX_BUFFERHEADERTYPE);
4998
4999 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5000 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5001 nPlatformListSize = drv_ctx.op_buf.actualcount *
5002 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5003 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5004 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
5005
5006 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
5007 sizeof(OMX_BUFFERHEADERTYPE),
5008 nPMEMInfoSize,
5009 nPlatformListSize);
5010 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
5011 drv_ctx.op_buf.actualcount);
5012#ifdef USE_ION
5013 ion_device_fd = alloc_map_ion_memory(
5014 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5015 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07005016 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005017 if (ion_device_fd < 0) {
5018 return OMX_ErrorInsufficientResources;
5019 }
5020 pmem_fd = fd_ion_data.fd;
5021#else
5022 pmem_fd = open (MEM_DEVICE,O_RDWR);
5023
5024 if (pmem_fd < 0)
5025 {
5026 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5027 drv_ctx.op_buf.buffer_size);
5028 return OMX_ErrorInsufficientResources;
5029 }
5030
5031 if(pmem_fd == 0)
5032 {
5033 pmem_fd = open (MEM_DEVICE,O_RDWR);
5034
5035 if (pmem_fd < 0)
5036 {
5037 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5038 drv_ctx.op_buf.buffer_size);
5039 return OMX_ErrorInsufficientResources;
5040 }
5041 }
5042
5043 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5044 drv_ctx.op_buf.actualcount,
5045 drv_ctx.op_buf.alignment))
5046 {
5047 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5048 close(pmem_fd);
5049 return OMX_ErrorInsufficientResources;
5050 }
5051#endif
5052 if (!secure_mode) {
5053 pmem_baseaddress = (unsigned char *)mmap(NULL,
5054 (drv_ctx.op_buf.buffer_size *
5055 drv_ctx.op_buf.actualcount),
5056 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5057 if (pmem_baseaddress == MAP_FAILED)
5058 {
5059 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5060 drv_ctx.op_buf.buffer_size);
5061 close(pmem_fd);
5062#ifdef USE_ION
5063 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5064#endif
5065 return OMX_ErrorInsufficientResources;
5066 }
5067 }
5068 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5069 // Alloc mem for platform specific info
5070 char *pPtr=NULL;
5071 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5072 nPMEMInfoSize,1);
5073 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5074 calloc (sizeof(struct vdec_bufferpayload),
5075 drv_ctx.op_buf.actualcount);
5076 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5077 calloc (sizeof (struct vdec_output_frameinfo),
5078 drv_ctx.op_buf.actualcount);
5079#ifdef USE_ION
5080 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5081 calloc (sizeof(struct vdec_ion),
5082 drv_ctx.op_buf.actualcount);
5083#endif
5084
5085 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5086 && drv_ctx.ptr_respbuffer)
5087 {
5088 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5089 (drv_ctx.op_buf.buffer_size *
5090 drv_ctx.op_buf.actualcount);
5091 bufHdr = m_out_mem_ptr;
5092 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5093 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5094 (((char *) m_platform_list) + nPlatformListSize);
5095 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5096 (((char *) m_platform_entry) + nPlatformEntrySize);
5097 pPlatformList = m_platform_list;
5098 pPlatformEntry = m_platform_entry;
5099 pPMEMInfo = m_pmem_info;
5100
5101 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5102
5103 // Settting the entire storage nicely
5104 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5105 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5106 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5107 {
5108 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5109 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5110 // Set the values when we determine the right HxW param
5111 bufHdr->nAllocLen = bytes;
5112 bufHdr->nFilledLen = 0;
5113 bufHdr->pAppPrivate = appData;
5114 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5115 // Platform specific PMEM Information
5116 // Initialize the Platform Entry
5117 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5118 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5119 pPlatformEntry->entry = pPMEMInfo;
5120 // Initialize the Platform List
5121 pPlatformList->nEntries = 1;
5122 pPlatformList->entryList = pPlatformEntry;
5123 // Keep pBuffer NULL till vdec is opened
5124 bufHdr->pBuffer = NULL;
5125 bufHdr->nOffset = 0;
5126
5127 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5128 pPMEMInfo->pmem_fd = 0;
5129 bufHdr->pPlatformPrivate = pPlatformList;
5130
5131 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005132 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005133#ifdef USE_ION
5134 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5135 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5136 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5137#endif
5138
5139 /*Create a mapping between buffers*/
5140 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5141 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5142 &drv_ctx.ptr_outputbuffer[i];
5143 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5144 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5145 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5146
5147 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5148 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5149 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5150 // Move the buffer and buffer header pointers
5151 bufHdr++;
5152 pPMEMInfo++;
5153 pPlatformEntry++;
5154 pPlatformList++;
5155 }
5156 }
5157 else
5158 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005159 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005160 m_out_mem_ptr, pPtr);
5161 if(m_out_mem_ptr)
5162 {
5163 free(m_out_mem_ptr);
5164 m_out_mem_ptr = NULL;
5165 }
5166 if(pPtr)
5167 {
5168 free(pPtr);
5169 pPtr = NULL;
5170 }
5171 if(drv_ctx.ptr_outputbuffer)
5172 {
5173 free(drv_ctx.ptr_outputbuffer);
5174 drv_ctx.ptr_outputbuffer = NULL;
5175 }
5176 if(drv_ctx.ptr_respbuffer)
5177 {
5178 free(drv_ctx.ptr_respbuffer);
5179 drv_ctx.ptr_respbuffer = NULL;
5180 }
5181#ifdef USE_ION
5182 if (drv_ctx.op_buf_ion_info) {
5183 DEBUG_PRINT_LOW("\n Free o/p ion context");
5184 free(drv_ctx.op_buf_ion_info);
5185 drv_ctx.op_buf_ion_info = NULL;
5186 }
5187#endif
5188 eRet = OMX_ErrorInsufficientResources;
5189 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005190 if (eRet == OMX_ErrorNone)
5191 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192 }
5193
5194 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5195 {
5196 if(BITMASK_ABSENT(&m_out_bm_count,i))
5197 {
5198 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5199 break;
5200 }
5201 }
5202
5203 if (eRet == OMX_ErrorNone)
5204 {
5205 if(i < drv_ctx.op_buf.actualcount)
5206 {
5207 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005208 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005209 int rc;
5210 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5211
5212 drv_ctx.ptr_outputbuffer[i].buffer_len =
5213 drv_ctx.op_buf.buffer_size;
5214
5215 *bufferHdr = (m_out_mem_ptr + i );
5216 if (secure_mode) {
5217 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5218 }
5219 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5220
5221 buf.index = i;
5222 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5223 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005224 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005225 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5226 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005227#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005228 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005229#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005230 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5231 plane[0].data_offset = 0;
5232 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5233 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5234 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5235 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5236#ifdef USE_ION
5237 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5238#endif
5239 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5240 plane[extra_idx].data_offset = 0;
5241 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5242 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5243 return OMX_ErrorBadParameter;
5244 }
5245 buf.m.planes = plane;
5246 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005247 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 -07005248 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5249 if (rc) {
5250 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005251 return OMX_ErrorInsufficientResources;
5252 }
5253
5254 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5255 enum v4l2_buf_type buf_type;
5256 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5257 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5258 if (rc) {
5259 return OMX_ErrorInsufficientResources;
5260 } else {
5261 streaming[CAPTURE_PORT] = true;
5262 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5263 }
5264 }
5265
5266 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5267 (*bufferHdr)->pAppPrivate = appData;
5268 BITMASK_SET(&m_out_bm_count,i);
5269 }
5270 else
5271 {
5272 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5273 eRet = OMX_ErrorInsufficientResources;
5274 }
5275 }
5276
5277 return eRet;
5278}
5279
5280
5281// AllocateBuffer -- API Call
5282/* ======================================================================
5283FUNCTION
5284 omx_vdec::AllocateBuffer
5285
5286DESCRIPTION
5287 Returns zero if all the buffers released..
5288
5289PARAMETERS
5290 None.
5291
5292RETURN VALUE
5293 true/false
5294
5295========================================================================== */
5296OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5297 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5298 OMX_IN OMX_U32 port,
5299 OMX_IN OMX_PTR appData,
5300 OMX_IN OMX_U32 bytes)
5301{
5302 unsigned i = 0;
5303 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5304
5305 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5306 if(m_state == OMX_StateInvalid)
5307 {
5308 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5309 return OMX_ErrorInvalidState;
5310 }
5311
5312 if(port == OMX_CORE_INPUT_PORT_INDEX)
5313 {
5314 if (arbitrary_bytes)
5315 {
5316 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5317 }
5318 else
5319 {
5320 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5321 }
5322 }
5323 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5324 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005325 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5326 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327 }
5328 else
5329 {
5330 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5331 eRet = OMX_ErrorBadPortIndex;
5332 }
5333 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5334 if(eRet == OMX_ErrorNone)
5335 {
5336 if(allocate_done()){
5337 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5338 {
5339 // Send the callback now
5340 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5341 post_event(OMX_CommandStateSet,OMX_StateIdle,
5342 OMX_COMPONENT_GENERATE_EVENT);
5343 }
5344 }
5345 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5346 {
5347 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5348 {
5349 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5350 post_event(OMX_CommandPortEnable,
5351 OMX_CORE_INPUT_PORT_INDEX,
5352 OMX_COMPONENT_GENERATE_EVENT);
5353 }
5354 }
5355 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5356 {
5357 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5358 {
5359 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5360 post_event(OMX_CommandPortEnable,
5361 OMX_CORE_OUTPUT_PORT_INDEX,
5362 OMX_COMPONENT_GENERATE_EVENT);
5363 }
5364 }
5365 }
5366 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5367 return eRet;
5368}
5369
5370// Free Buffer - API call
5371/* ======================================================================
5372FUNCTION
5373 omx_vdec::FreeBuffer
5374
5375DESCRIPTION
5376
5377PARAMETERS
5378 None.
5379
5380RETURN VALUE
5381 true/false
5382
5383========================================================================== */
5384OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5385 OMX_IN OMX_U32 port,
5386 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5387{
5388 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5389 unsigned int nPortIndex;
5390 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5391
5392 if(m_state == OMX_StateIdle &&
5393 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5394 {
5395 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5396 }
5397 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5398 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5399 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005400 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401 }
5402 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5403 {
5404 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5405 post_event(OMX_EventError,
5406 OMX_ErrorPortUnpopulated,
5407 OMX_COMPONENT_GENERATE_EVENT);
5408
5409 return OMX_ErrorIncorrectStateOperation;
5410 }
5411 else if (m_state != OMX_StateInvalid)
5412 {
5413 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5414 post_event(OMX_EventError,
5415 OMX_ErrorPortUnpopulated,
5416 OMX_COMPONENT_GENERATE_EVENT);
5417 }
5418
5419 if(port == OMX_CORE_INPUT_PORT_INDEX)
5420 {
5421 /*Check if arbitrary bytes*/
5422 if(!arbitrary_bytes && !input_use_buffer)
5423 nPortIndex = buffer - m_inp_mem_ptr;
5424 else
5425 nPortIndex = buffer - m_inp_heap_ptr;
5426
5427 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5428 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5429 {
5430 // Clear the bit associated with it.
5431 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5432 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5433 if (input_use_buffer == true)
5434 {
5435
5436 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5437 if(m_phdr_pmem_ptr)
5438 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5439 }
5440 else
5441 {
5442 if (arbitrary_bytes)
5443 {
5444 if(m_phdr_pmem_ptr)
5445 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5446 else
5447 free_input_buffer(nPortIndex,NULL);
5448 }
5449 else
5450 free_input_buffer(buffer);
5451 }
5452 m_inp_bPopulated = OMX_FALSE;
5453 /*Free the Buffer Header*/
5454 if (release_input_done())
5455 {
5456 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5457 free_input_buffer_header();
5458 }
5459 }
5460 else
5461 {
5462 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5463 eRet = OMX_ErrorBadPortIndex;
5464 }
5465
5466 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5467 && release_input_done())
5468 {
5469 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5470 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5471 post_event(OMX_CommandPortDisable,
5472 OMX_CORE_INPUT_PORT_INDEX,
5473 OMX_COMPONENT_GENERATE_EVENT);
5474 }
5475 }
5476 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5477 {
5478 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005479 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005480 if(nPortIndex < drv_ctx.op_buf.actualcount)
5481 {
5482 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5483 // Clear the bit associated with it.
5484 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5485 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005486 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487
5488 if (release_output_done())
5489 {
5490 free_output_buffer_header();
5491 }
5492 }
5493 else
5494 {
5495 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5496 eRet = OMX_ErrorBadPortIndex;
5497 }
5498 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5499 && release_output_done())
5500 {
5501 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5502
5503 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5504 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5505#ifdef _ANDROID_ICS_
5506 if (m_enable_android_native_buffers)
5507 {
5508 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5509 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5510 }
5511#endif
5512
5513 post_event(OMX_CommandPortDisable,
5514 OMX_CORE_OUTPUT_PORT_INDEX,
5515 OMX_COMPONENT_GENERATE_EVENT);
5516 }
5517 }
5518 else
5519 {
5520 eRet = OMX_ErrorBadPortIndex;
5521 }
5522 if((eRet == OMX_ErrorNone) &&
5523 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5524 {
5525 if(release_done())
5526 {
5527 // Send the callback now
5528 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5529 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5530 OMX_COMPONENT_GENERATE_EVENT);
5531 }
5532 }
5533 return eRet;
5534}
5535
5536
5537/* ======================================================================
5538FUNCTION
5539 omx_vdec::EmptyThisBuffer
5540
5541DESCRIPTION
5542 This routine is used to push the encoded video frames to
5543 the video decoder.
5544
5545PARAMETERS
5546 None.
5547
5548RETURN VALUE
5549 OMX Error None if everything went successful.
5550
5551========================================================================== */
5552OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5553 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5554{
5555 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5556 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5557
5558 if(m_state == OMX_StateInvalid)
5559 {
5560 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5561 return OMX_ErrorInvalidState;
5562 }
5563
5564 if (buffer == NULL)
5565 {
5566 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5567 return OMX_ErrorBadParameter;
5568 }
5569
5570 if (!m_inp_bEnabled)
5571 {
5572 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5573 return OMX_ErrorIncorrectStateOperation;
5574 }
5575
5576 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5577 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005578 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579 return OMX_ErrorBadPortIndex;
5580 }
5581
5582#ifdef _ANDROID_
5583 if(iDivXDrmDecrypt)
5584 {
5585 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5586 if(drmErr != OMX_ErrorNone) {
5587 // this error can be ignored
5588 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5589 }
5590 }
5591#endif //_ANDROID_
5592 if (perf_flag)
5593 {
5594 if (!latency)
5595 {
5596 dec_time.stop();
5597 latency = dec_time.processing_time_us();
5598 dec_time.start();
5599 }
5600 }
5601
5602 if (arbitrary_bytes)
5603 {
5604 nBufferIndex = buffer - m_inp_heap_ptr;
5605 }
5606 else
5607 {
5608 if (input_use_buffer == true)
5609 {
5610 nBufferIndex = buffer - m_inp_heap_ptr;
5611 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5612 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5613 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5614 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005615 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 -07005616 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5617 }
5618 else{
5619 nBufferIndex = buffer - m_inp_mem_ptr;
5620 }
5621 }
5622
5623 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5624 {
5625 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5626 return OMX_ErrorBadParameter;
5627 }
5628
5629 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5630 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5631 if (arbitrary_bytes)
5632 {
5633 post_event ((unsigned)hComp,(unsigned)buffer,
5634 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5635 }
5636 else
5637 {
5638 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5639 set_frame_rate(buffer->nTimeStamp);
5640 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5641 }
5642 return OMX_ErrorNone;
5643}
5644
5645/* ======================================================================
5646FUNCTION
5647 omx_vdec::empty_this_buffer_proxy
5648
5649DESCRIPTION
5650 This routine is used to push the encoded video frames to
5651 the video decoder.
5652
5653PARAMETERS
5654 None.
5655
5656RETURN VALUE
5657 OMX Error None if everything went successful.
5658
5659========================================================================== */
5660OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5661 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5662{
5663 int push_cnt = 0,i=0;
5664 unsigned nPortIndex = 0;
5665 OMX_ERRORTYPE ret = OMX_ErrorNone;
5666 struct vdec_input_frameinfo frameinfo;
5667 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005668 struct vdec_seqheader seq_header;
5669 bool port_setting_changed = true;
5670 bool not_coded_vop = false;
5671
5672 /*Should we generate a Aync error event*/
5673 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5674 {
5675 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5676 return OMX_ErrorBadParameter;
5677 }
5678
5679 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5680
5681 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5682 {
5683 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5684 nPortIndex);
5685 return OMX_ErrorBadParameter;
5686 }
5687
5688 pending_input_buffers++;
5689
5690 /* return zero length and not an EOS buffer */
5691 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5692 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5693 {
5694 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5695 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5696 OMX_COMPONENT_GENERATE_EBD);
5697 return OMX_ErrorNone;
5698 }
5699
5700
5701 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5702 mp4StreamType psBits;
5703 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5704 psBits.numBytes = buffer->nFilledLen;
5705 mp4_headerparser.parseHeader(&psBits);
5706 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5707 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5708 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005709 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005710 buffer->nFilledLen,frame_count);
5711 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5712 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5713 not_coded_vop = false;
5714 buffer->nFilledLen = 0;
5715 }
5716 }
5717 }
5718
5719 if(input_flush_progress == true
5720
5721 || not_coded_vop
5722
5723 )
5724 {
5725 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5726 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5727 OMX_COMPONENT_GENERATE_EBD);
5728 return OMX_ErrorNone;
5729 }
5730
5731 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5732
5733 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5734 {
5735 return OMX_ErrorBadParameter;
5736 }
5737
5738 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5739 /*for use buffer we need to memcpy the data*/
5740 temp_buffer->buffer_len = buffer->nFilledLen;
5741
5742 if (input_use_buffer)
5743 {
5744 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5745 {
5746 if(arbitrary_bytes)
5747 {
5748 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5749 }
5750 else
5751 {
5752 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5753 buffer->nFilledLen);
5754 }
5755 }
5756 else
5757 {
5758 return OMX_ErrorBadParameter;
5759 }
5760
5761 }
5762
5763 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5764 frameinfo.client_data = (void *) buffer;
5765 frameinfo.datalen = temp_buffer->buffer_len;
5766 frameinfo.flags = 0;
5767 frameinfo.offset = buffer->nOffset;
5768 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5769 frameinfo.pmem_offset = temp_buffer->offset;
5770 frameinfo.timestamp = buffer->nTimeStamp;
5771 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5772 {
5773 DEBUG_PRINT_LOW("ETB: dmx enabled");
5774 if (m_demux_entries == 0)
5775 {
5776 extract_demux_addr_offsets(buffer);
5777 }
5778
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005779 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005780 handle_demux_data(buffer);
5781 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5782 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5783 }
5784 else
5785 {
5786 frameinfo.desc_addr = NULL;
5787 frameinfo.desc_size = 0;
5788 }
5789 if(!arbitrary_bytes)
5790 {
5791 frameinfo.flags |= buffer->nFlags;
5792 }
5793
5794#ifdef _ANDROID_
5795 if (m_debug_timestamp)
5796 {
5797 if(arbitrary_bytes)
5798 {
5799 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5800 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5801 }
5802 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5803 {
5804 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5805 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5806 }
5807 }
5808#endif
5809
5810#ifdef INPUT_BUFFER_LOG
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07005811 if (output_capability == V4L2_PIX_FMT_VP8) {
5812 struct vp8_ivf_frame_header{
5813 OMX_U32 framesize;
5814 OMX_U32 timestamp_lo;
5815 OMX_U32 timestamp_hi;
5816 } vp8_frame_header;
5817 vp8_frame_header.framesize = temp_buffer->buffer_len;
5818 /* Currently FW doesn't use timestamp values */
5819 vp8_frame_header.timestamp_lo = 0;
5820 vp8_frame_header.timestamp_hi = 0;
5821 if (inputBufferFile1)
5822 {
5823 fwrite((const char *)&vp8_frame_header,
5824 sizeof(vp8_frame_header),1,inputBufferFile1);
5825 fwrite((const char *)temp_buffer->bufferaddr,
5826 temp_buffer->buffer_len,1,inputBufferFile1);
5827 }
5828 } else {
5829 if (inputBufferFile1)
5830 {
5831 fwrite((const char *)temp_buffer->bufferaddr,
5832 temp_buffer->buffer_len,1,inputBufferFile1);
5833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834 }
5835#endif
5836
5837 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5838 {
5839 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5840 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5841 }
5842
5843 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5844 {
5845 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5846 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5847 h264_scratch.nFilledLen = 0;
5848 nal_count = 0;
5849 look_ahead_nal = false;
5850 frame_count = 0;
5851 if (m_frame_parser.mutils)
5852 m_frame_parser.mutils->initialize_frame_checking_environment();
5853 m_frame_parser.flush();
5854 h264_last_au_ts = LLONG_MAX;
5855 h264_last_au_flags = 0;
5856 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5857 m_demux_entries = 0;
5858 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005859 struct v4l2_buffer buf;
5860 struct v4l2_plane plane;
5861 memset( (void *)&buf, 0, sizeof(buf));
5862 memset( (void *)&plane, 0, sizeof(plane));
5863 int rc;
5864 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005865 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5866 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005867 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005868 }
5869 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5870 buf.index = nPortIndex;
5871 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5872 buf.memory = V4L2_MEMORY_USERPTR;
5873 plane.bytesused = temp_buffer->buffer_len;
5874 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005875 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5876 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005877 plane.reserved[0] = temp_buffer->pmem_fd;
5878 plane.reserved[1] = temp_buffer->offset;
5879 plane.data_offset = 0;
5880 buf.m.planes = &plane;
5881 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005882 if (frameinfo.timestamp >= LLONG_MAX) {
5883 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5884 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005885 //assumption is that timestamp is in milliseconds
5886 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5887 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005888 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5889
Shalaj Jain273b3e02012-06-22 19:08:03 -07005890 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005891 if(rc)
5892 {
5893 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5894 return OMX_ErrorHardware;
5895 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005896 if(!streaming[OUTPUT_PORT])
5897 {
5898 enum v4l2_buf_type buf_type;
5899 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005900
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5902 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5903 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5904 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005905 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005907 } else{
5908 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005909 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005910 }
5911}
5912 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5913 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5914 time_stamp_dts.insert_timestamp(buffer);
5915
5916 return ret;
5917}
5918
5919/* ======================================================================
5920FUNCTION
5921 omx_vdec::FillThisBuffer
5922
5923DESCRIPTION
5924 IL client uses this method to release the frame buffer
5925 after displaying them.
5926
5927PARAMETERS
5928 None.
5929
5930RETURN VALUE
5931 true/false
5932
5933========================================================================== */
5934OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5935 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5936{
5937
5938 if(m_state == OMX_StateInvalid)
5939 {
5940 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5941 return OMX_ErrorInvalidState;
5942 }
5943
5944 if (!m_out_bEnabled)
5945 {
5946 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5947 return OMX_ErrorIncorrectStateOperation;
5948 }
5949
Vinay Kaliada4f4422013-01-09 10:45:03 -08005950 if (buffer == NULL ||
5951 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952 {
5953 return OMX_ErrorBadParameter;
5954 }
5955
5956 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5957 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005958 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005959 return OMX_ErrorBadPortIndex;
5960 }
5961
5962 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005963 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005964 return OMX_ErrorNone;
5965}
5966/* ======================================================================
5967FUNCTION
5968 omx_vdec::fill_this_buffer_proxy
5969
5970DESCRIPTION
5971 IL client uses this method to release the frame buffer
5972 after displaying them.
5973
5974PARAMETERS
5975 None.
5976
5977RETURN VALUE
5978 true/false
5979
5980========================================================================== */
5981OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5982 OMX_IN OMX_HANDLETYPE hComp,
5983 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5984{
5985 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005986 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5987 unsigned nPortIndex = 0;
5988 struct vdec_fillbuffer_cmd fillbuffer;
5989 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5990 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5991
Vinay Kaliada4f4422013-01-09 10:45:03 -08005992 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005993
Vinay Kaliada4f4422013-01-09 10:45:03 -08005994 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005995 return OMX_ErrorBadParameter;
5996
5997 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5998 bufferAdd, bufferAdd->pBuffer);
5999 /*Return back the output buffer to client*/
6000 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
6001 {
6002 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
6003 buffer->nFilledLen = 0;
6004 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6005 return OMX_ErrorNone;
6006 }
6007 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006008 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006009 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6010 if (ptr_respbuffer)
6011 {
6012 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6013 }
6014
6015 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
6016 {
6017 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6018 buffer->nFilledLen = 0;
6019 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6020 pending_output_buffers--;
6021 return OMX_ErrorBadParameter;
6022 }
6023
Shalaj Jain286b0062013-02-21 20:35:48 -08006024 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08006026 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027
6028#ifdef _ANDROID_ICS_
6029 if (m_enable_android_native_buffers)
6030 {
6031 // Acquire a write lock on this buffer.
6032 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
6033 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
6034 DEBUG_PRINT_ERROR("Failed to acquire genlock");
6035 buffer->nFilledLen = 0;
6036 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6037 pending_output_buffers--;
6038 return OMX_ErrorInsufficientResources;
6039 } else {
6040 native_buffer[buffer - m_out_mem_ptr].inuse = true;
6041 }
6042 }
6043#endif
6044 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08006045 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006046 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08006047 memset( (void *)&buf, 0, sizeof(buf));
6048 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006049 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006050
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006051 buf.index = nPortIndex;
6052 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6053 buf.memory = V4L2_MEMORY_USERPTR;
6054 plane[0].bytesused = buffer->nFilledLen;
6055 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08006056 plane[0].m.userptr =
6057 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6058 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006059 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6060 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6061 plane[0].data_offset = 0;
6062 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6063 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6064 plane[extra_idx].bytesused = 0;
6065 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6066 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
6067#ifdef USE_ION
6068 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
6069#endif
6070 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6071 plane[extra_idx].data_offset = 0;
6072 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6073 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6074 return OMX_ErrorBadParameter;
6075 }
6076 buf.m.planes = plane;
6077 buf.length = drv_ctx.num_planes;
6078 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6079 if (rc) {
6080 /*TODO: How to handle this case */
6081 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6082 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083//#ifdef _ANDROID_ICS_
6084 // if (m_enable_android_native_buffers)
6085 // {
6086 // Unlock the buffer
6087 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6088 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6089 // return OMX_ErrorInsufficientResources;
6090 /// } else {
6091 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6092 // }
6093 // }
6094//#endif
6095 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6096 // pending_output_buffers--;
6097 // return OMX_ErrorBadParameter;
6098 //}
6099 return OMX_ErrorNone;
6100}
6101
6102/* ======================================================================
6103FUNCTION
6104 omx_vdec::SetCallbacks
6105
6106DESCRIPTION
6107 Set the callbacks.
6108
6109PARAMETERS
6110 None.
6111
6112RETURN VALUE
6113 OMX Error None if everything successful.
6114
6115========================================================================== */
6116OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6117 OMX_IN OMX_CALLBACKTYPE* callbacks,
6118 OMX_IN OMX_PTR appData)
6119{
6120
6121 m_cb = *callbacks;
6122 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6123 m_cb.EventHandler,m_cb.FillBufferDone);
6124 m_app_data = appData;
6125 return OMX_ErrorNotImplemented;
6126}
6127
6128/* ======================================================================
6129FUNCTION
6130 omx_vdec::ComponentDeInit
6131
6132DESCRIPTION
6133 Destroys the component and release memory allocated to the heap.
6134
6135PARAMETERS
6136 <TBD>.
6137
6138RETURN VALUE
6139 OMX Error None if everything successful.
6140
6141========================================================================== */
6142OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6143{
6144#ifdef _ANDROID_
6145 if(iDivXDrmDecrypt)
6146 {
6147 delete iDivXDrmDecrypt;
6148 iDivXDrmDecrypt=NULL;
6149 }
6150#endif //_ANDROID_
6151
Shalaj Jain286b0062013-02-21 20:35:48 -08006152 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006153 if (OMX_StateLoaded != m_state)
6154 {
6155 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6156 m_state);
6157 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6158 }
6159 else
6160 {
6161 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6162 }
6163
6164 /*Check if the output buffers have to be cleaned up*/
6165 if(m_out_mem_ptr)
6166 {
6167 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006168 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006169 {
6170 free_output_buffer (&m_out_mem_ptr[i]);
6171#ifdef _ANDROID_ICS_
6172 if (m_enable_android_native_buffers)
6173 {
6174 if (native_buffer[i].inuse)
6175 {
6176 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6177 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6178 }
6179 native_buffer[i].inuse = false;
6180 }
6181 }
6182#endif
6183 }
6184#ifdef _ANDROID_ICS_
6185 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6186#endif
6187 }
6188
6189 /*Check if the input buffers have to be cleaned up*/
6190 if(m_inp_mem_ptr || m_inp_heap_ptr)
6191 {
6192 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006193 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006194 {
6195 if (m_inp_mem_ptr)
6196 free_input_buffer (i,&m_inp_mem_ptr[i]);
6197 else
6198 free_input_buffer (i,NULL);
6199 }
6200 }
6201 free_input_buffer_header();
6202 free_output_buffer_header();
6203 if(h264_scratch.pBuffer)
6204 {
6205 free(h264_scratch.pBuffer);
6206 h264_scratch.pBuffer = NULL;
6207 }
6208
6209 if (h264_parser)
6210 {
6211 delete h264_parser;
6212 h264_parser = NULL;
6213 }
6214
6215 if(m_platform_list)
6216 {
6217 free(m_platform_list);
6218 m_platform_list = NULL;
6219 }
6220 if(m_vendor_config.pData)
6221 {
6222 free(m_vendor_config.pData);
6223 m_vendor_config.pData = NULL;
6224 }
6225
6226 // Reset counters in mesg queues
6227 m_ftb_q.m_size=0;
6228 m_cmd_q.m_size=0;
6229 m_etb_q.m_size=0;
6230 m_ftb_q.m_read = m_ftb_q.m_write =0;
6231 m_cmd_q.m_read = m_cmd_q.m_write =0;
6232 m_etb_q.m_read = m_etb_q.m_write =0;
6233#ifdef _ANDROID_
6234 if (m_debug_timestamp)
6235 {
6236 m_timestamp_list.reset_ts_list();
6237 }
6238#endif
6239
6240 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6241 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6242 // NULL);
6243 DEBUG_PRINT_HIGH("\n Close the driver instance");
6244
6245#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006246 if (inputBufferFile1)
6247 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006248#endif
6249#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006250 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006251 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006252#endif
6253#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006254 if (outputExtradataFile)
6255 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006256#endif
6257 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6258 return OMX_ErrorNone;
6259}
6260
6261/* ======================================================================
6262FUNCTION
6263 omx_vdec::UseEGLImage
6264
6265DESCRIPTION
6266 OMX Use EGL Image method implementation <TBD>.
6267
6268PARAMETERS
6269 <TBD>.
6270
6271RETURN VALUE
6272 Not Implemented error.
6273
6274========================================================================== */
6275OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6276 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6277 OMX_IN OMX_U32 port,
6278 OMX_IN OMX_PTR appData,
6279 OMX_IN void* eglImage)
6280{
6281 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6282 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6283 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6284
6285#ifdef USE_EGL_IMAGE_GPU
6286 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6287 EGLint fd = -1, offset = 0,pmemPtr = 0;
6288#else
6289 int fd = -1, offset = 0;
6290#endif
6291 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6292 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6293 DEBUG_PRINT_ERROR("\n ");
6294 }
6295#ifdef USE_EGL_IMAGE_GPU
6296 if(m_display_id == NULL) {
6297 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6298 return OMX_ErrorInsufficientResources;
6299 }
6300 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6301 eglGetProcAddress("eglQueryImageKHR");
6302 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6303 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6304 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6305#else //with OMX test app
6306 struct temp_egl {
6307 int pmem_fd;
6308 int offset;
6309 };
6310 struct temp_egl *temp_egl_id = NULL;
6311 void * pmemPtr = (void *) eglImage;
6312 temp_egl_id = (struct temp_egl *)eglImage;
6313 if (temp_egl_id != NULL)
6314 {
6315 fd = temp_egl_id->pmem_fd;
6316 offset = temp_egl_id->offset;
6317 }
6318#endif
6319 if (fd < 0) {
6320 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6321 return OMX_ErrorInsufficientResources;
6322 }
6323 pmem_info.pmem_fd = (OMX_U32) fd;
6324 pmem_info.offset = (OMX_U32) offset;
6325 pmem_entry.entry = (void *) &pmem_info;
6326 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6327 pmem_list.entryList = &pmem_entry;
6328 pmem_list.nEntries = 1;
6329 ouput_egl_buffers = true;
6330 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6331 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6332 (OMX_U8 *)pmemPtr)) {
6333 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6334 return OMX_ErrorInsufficientResources;
6335 }
6336 return OMX_ErrorNone;
6337}
6338
6339/* ======================================================================
6340FUNCTION
6341 omx_vdec::ComponentRoleEnum
6342
6343DESCRIPTION
6344 OMX Component Role Enum method implementation.
6345
6346PARAMETERS
6347 <TBD>.
6348
6349RETURN VALUE
6350 OMX Error None if everything is successful.
6351========================================================================== */
6352OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6353 OMX_OUT OMX_U8* role,
6354 OMX_IN OMX_U32 index)
6355{
6356 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6357
6358 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6359 {
6360 if((0 == index) && role)
6361 {
6362 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6363 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6364 }
6365 else
6366 {
6367 eRet = OMX_ErrorNoMore;
6368 }
6369 }
6370 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6371 {
6372 if((0 == index) && role)
6373 {
6374 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6375 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6376 }
6377 else
6378 {
6379 eRet = OMX_ErrorNoMore;
6380 }
6381 }
6382 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6383 {
6384 if((0 == index) && role)
6385 {
6386 strlcpy((char *)role, "video_decoder.h263",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 }
6395
6396 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6397 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6398 )
6399
6400 {
6401 if((0 == index) && role)
6402 {
6403 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6404 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6405 }
6406 else
6407 {
6408 DEBUG_PRINT_LOW("\n No more roles \n");
6409 eRet = OMX_ErrorNoMore;
6410 }
6411 }
6412 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6413 {
6414 if((0 == index) && role)
6415 {
6416 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6417 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6418 }
6419 else
6420 {
6421 DEBUG_PRINT_LOW("\n No more roles \n");
6422 eRet = OMX_ErrorNoMore;
6423 }
6424 }
6425 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6426 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6427 )
6428 {
6429 if((0 == index) && role)
6430 {
6431 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6432 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6433 }
6434 else
6435 {
6436 DEBUG_PRINT_LOW("\n No more roles \n");
6437 eRet = OMX_ErrorNoMore;
6438 }
6439 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006440 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6441 {
6442 if((0 == index) && role)
6443 {
6444 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6445 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6446 }
6447 else
6448 {
6449 DEBUG_PRINT_LOW("\n No more roles \n");
6450 eRet = OMX_ErrorNoMore;
6451 }
6452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006453 else
6454 {
6455 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6456 eRet = OMX_ErrorInvalidComponentName;
6457 }
6458 return eRet;
6459}
6460
6461
6462
6463
6464/* ======================================================================
6465FUNCTION
6466 omx_vdec::AllocateDone
6467
6468DESCRIPTION
6469 Checks if entire buffer pool is allocated by IL Client or not.
6470 Need this to move to IDLE state.
6471
6472PARAMETERS
6473 None.
6474
6475RETURN VALUE
6476 true/false.
6477
6478========================================================================== */
6479bool omx_vdec::allocate_done(void)
6480{
6481 bool bRet = false;
6482 bool bRet_In = false;
6483 bool bRet_Out = false;
6484
6485 bRet_In = allocate_input_done();
6486 bRet_Out = allocate_output_done();
6487
6488 if(bRet_In && bRet_Out)
6489 {
6490 bRet = true;
6491 }
6492
6493 return bRet;
6494}
6495/* ======================================================================
6496FUNCTION
6497 omx_vdec::AllocateInputDone
6498
6499DESCRIPTION
6500 Checks if I/P buffer pool is allocated by IL Client or not.
6501
6502PARAMETERS
6503 None.
6504
6505RETURN VALUE
6506 true/false.
6507
6508========================================================================== */
6509bool omx_vdec::allocate_input_done(void)
6510{
6511 bool bRet = false;
6512 unsigned i=0;
6513
6514 if (m_inp_mem_ptr == NULL)
6515 {
6516 return bRet;
6517 }
6518 if(m_inp_mem_ptr )
6519 {
6520 for(;i<drv_ctx.ip_buf.actualcount;i++)
6521 {
6522 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6523 {
6524 break;
6525 }
6526 }
6527 }
6528 if(i == drv_ctx.ip_buf.actualcount)
6529 {
6530 bRet = true;
6531 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6532 }
6533 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6534 {
6535 m_inp_bPopulated = OMX_TRUE;
6536 }
6537 return bRet;
6538}
6539/* ======================================================================
6540FUNCTION
6541 omx_vdec::AllocateOutputDone
6542
6543DESCRIPTION
6544 Checks if entire O/P buffer pool is allocated by IL Client or not.
6545
6546PARAMETERS
6547 None.
6548
6549RETURN VALUE
6550 true/false.
6551
6552========================================================================== */
6553bool omx_vdec::allocate_output_done(void)
6554{
6555 bool bRet = false;
6556 unsigned j=0;
6557
6558 if (m_out_mem_ptr == NULL)
6559 {
6560 return bRet;
6561 }
6562
6563 if (m_out_mem_ptr)
6564 {
6565 for(;j < drv_ctx.op_buf.actualcount;j++)
6566 {
6567 if(BITMASK_ABSENT(&m_out_bm_count,j))
6568 {
6569 break;
6570 }
6571 }
6572 }
6573
6574 if(j == drv_ctx.op_buf.actualcount)
6575 {
6576 bRet = true;
6577 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6578 if(m_out_bEnabled)
6579 m_out_bPopulated = OMX_TRUE;
6580 }
6581
6582 return bRet;
6583}
6584
6585/* ======================================================================
6586FUNCTION
6587 omx_vdec::ReleaseDone
6588
6589DESCRIPTION
6590 Checks if IL client has released all the buffers.
6591
6592PARAMETERS
6593 None.
6594
6595RETURN VALUE
6596 true/false
6597
6598========================================================================== */
6599bool omx_vdec::release_done(void)
6600{
6601 bool bRet = false;
6602
6603 if(release_input_done())
6604 {
6605 if(release_output_done())
6606 {
6607 bRet = true;
6608 }
6609 }
6610 return bRet;
6611}
6612
6613
6614/* ======================================================================
6615FUNCTION
6616 omx_vdec::ReleaseOutputDone
6617
6618DESCRIPTION
6619 Checks if IL client has released all the buffers.
6620
6621PARAMETERS
6622 None.
6623
6624RETURN VALUE
6625 true/false
6626
6627========================================================================== */
6628bool omx_vdec::release_output_done(void)
6629{
6630 bool bRet = false;
6631 unsigned i=0,j=0;
6632
6633 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6634 if(m_out_mem_ptr)
6635 {
6636 for(;j < drv_ctx.op_buf.actualcount ; j++)
6637 {
6638 if(BITMASK_PRESENT(&m_out_bm_count,j))
6639 {
6640 break;
6641 }
6642 }
6643 if(j == drv_ctx.op_buf.actualcount)
6644 {
6645 m_out_bm_count = 0;
6646 bRet = true;
6647 }
6648 }
6649 else
6650 {
6651 m_out_bm_count = 0;
6652 bRet = true;
6653 }
6654 return bRet;
6655}
6656/* ======================================================================
6657FUNCTION
6658 omx_vdec::ReleaseInputDone
6659
6660DESCRIPTION
6661 Checks if IL client has released all the buffers.
6662
6663PARAMETERS
6664 None.
6665
6666RETURN VALUE
6667 true/false
6668
6669========================================================================== */
6670bool omx_vdec::release_input_done(void)
6671{
6672 bool bRet = false;
6673 unsigned i=0,j=0;
6674
6675 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6676 if(m_inp_mem_ptr)
6677 {
6678 for(;j<drv_ctx.ip_buf.actualcount;j++)
6679 {
6680 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6681 {
6682 break;
6683 }
6684 }
6685 if(j==drv_ctx.ip_buf.actualcount)
6686 {
6687 bRet = true;
6688 }
6689 }
6690 else
6691 {
6692 bRet = true;
6693 }
6694 return bRet;
6695}
6696
6697OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6698 OMX_BUFFERHEADERTYPE * buffer)
6699{
6700 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6701 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6702 {
6703 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6704 return OMX_ErrorBadParameter;
6705 }
6706 else if (output_flush_progress)
6707 {
6708 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6709 buffer->nFilledLen = 0;
6710 buffer->nTimeStamp = 0;
6711 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6712 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6713 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6714 }
6715
6716 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6717 buffer, buffer->pBuffer);
6718 pending_output_buffers --;
6719
6720 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6721 {
6722 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6723 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006724 post_event((unsigned)NULL, (unsigned)NULL,
6725 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006726
6727 if (psource_frame)
6728 {
6729 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6730 psource_frame = NULL;
6731 }
6732 if (pdest_frame)
6733 {
6734 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006735 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6736 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006737 pdest_frame = NULL;
6738 }
6739 }
6740
6741 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6742#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006743 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006744 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006745 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006746 int stride = drv_ctx.video_resolution.stride;
6747 int scanlines = drv_ctx.video_resolution.scan_lines;
6748 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006749 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006750 int bytes_written = 0;
6751 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6752 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6753 temp += stride;
6754 }
6755 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006756 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006757 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6758 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6759 temp += stride_c;
6760 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761 }
6762#endif
6763
6764 /* For use buffer we need to copy the data */
6765 if (!output_flush_progress)
6766 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006767 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006768 bool is_duplicate_ts_valid = true;
6769 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6770 output_capability == V4L2_PIX_FMT_DIVX ||
6771 output_capability == V4L2_PIX_FMT_DIVX_311)
6772 is_duplicate_ts_valid = false;
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006773 if (buffer->nFilledLen > 0)
6774 time_stamp_dts.get_next_timestamp(buffer,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006775 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6776 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006777 else {
6778 m_inp_err_count++;
6779 time_stamp_dts.remove_time_stamp(
6780 buffer->nTimeStamp,
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006781 ((drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6782 ?true:false) && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006783 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006784 if (m_debug_timestamp)
6785 {
6786 {
6787 OMX_TICKS expected_ts = 0;
6788 m_timestamp_list.pop_min_ts(expected_ts);
6789 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6790 buffer->nTimeStamp, expected_ts);
6791
6792 if (buffer->nTimeStamp != expected_ts)
6793 {
6794 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6795 }
6796 }
6797 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006798 }
6799 if (m_cb.FillBufferDone)
6800 {
6801 if (buffer->nFilledLen > 0)
6802 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006803 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006804 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6805 // Keep min timestamp interval to handle corrupted bit stream scenario
6806 set_frame_rate(buffer->nTimeStamp);
6807 else if (arbitrary_bytes)
6808 adjust_timestamp(buffer->nTimeStamp);
6809 if (perf_flag)
6810 {
6811 if (!proc_frms)
6812 {
6813 dec_time.stop();
6814 latency = dec_time.processing_time_us() - latency;
6815 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6816 dec_time.start();
6817 fps_metrics.start();
6818 }
6819 proc_frms++;
6820 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6821 {
6822 OMX_U64 proc_time = 0;
6823 fps_metrics.stop();
6824 proc_time = fps_metrics.processing_time_us();
6825 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6826 proc_frms, (float)proc_time / 1e6,
6827 (float)(1e6 * proc_frms) / proc_time);
6828 proc_frms = 0;
6829 }
6830 }
6831
6832#ifdef OUTPUT_EXTRADATA_LOG
6833 if (outputExtradataFile)
6834 {
6835
6836 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6837 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6838 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6839 buffer->nFilledLen + 3)&(~3));
6840 while(p_extra &&
6841 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6842 {
6843 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6844 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6845 if (p_extra->eType == OMX_ExtraDataNone)
6846 {
6847 break;
6848 }
6849 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6850 }
6851 }
6852#endif
6853 }
6854 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6855 prev_ts = LLONG_MAX;
6856 rst_prev_ts = true;
6857 }
6858
6859 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6860 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6861 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006862 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006863#ifdef _ANDROID_ICS_
6864 if (m_enable_android_native_buffers)
6865 {
6866 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6867 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6868 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6869 return OMX_ErrorInsufficientResources;
6870 }
6871 else {
6872 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6873 }
6874 }
6875 }
6876#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006877 OMX_BUFFERHEADERTYPE *il_buffer;
6878 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6879 if (il_buffer)
6880 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6881 else {
6882 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6883 return OMX_ErrorBadParameter;
6884 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006885 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006886 }
6887 else
6888 {
6889 return OMX_ErrorBadParameter;
6890 }
6891
6892 return OMX_ErrorNone;
6893}
6894
6895OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6896 OMX_BUFFERHEADERTYPE* buffer)
6897{
6898
6899 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6900 {
6901 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6902 return OMX_ErrorBadParameter;
6903 }
6904
6905 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6906 buffer, buffer->pBuffer);
6907 pending_input_buffers--;
6908
6909 if (arbitrary_bytes)
6910 {
6911 if (pdest_frame == NULL && input_flush_progress == false)
6912 {
6913 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6914 pdest_frame = buffer;
6915 buffer->nFilledLen = 0;
6916 buffer->nTimeStamp = LLONG_MAX;
6917 push_input_buffer (hComp);
6918 }
6919 else
6920 {
6921 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6922 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006923 if (!m_input_free_q.insert_entry((unsigned)buffer,
6924 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006925 {
6926 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6927 }
6928 }
6929 }
6930 else if(m_cb.EmptyBufferDone)
6931 {
6932 buffer->nFilledLen = 0;
6933 if (input_use_buffer == true){
6934 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6935 }
6936 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6937 }
6938 return OMX_ErrorNone;
6939}
6940
Shalaj Jain273b3e02012-06-22 19:08:03 -07006941int omx_vdec::async_message_process (void *context, void* message)
6942{
6943 omx_vdec* omx = NULL;
6944 struct vdec_msginfo *vdec_msg = NULL;
6945 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006946 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006947 struct vdec_output_frameinfo *output_respbuf = NULL;
6948 int rc=1;
6949 if (context == NULL || message == NULL)
6950 {
6951 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6952 return -1;
6953 }
6954 vdec_msg = (struct vdec_msginfo *)message;
6955
6956 omx = reinterpret_cast<omx_vdec*>(context);
6957
Shalaj Jain273b3e02012-06-22 19:08:03 -07006958 switch (vdec_msg->msgcode)
6959 {
6960
6961 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006962 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006963 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6964 break;
6965
6966 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006967 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006968 OMX_COMPONENT_GENERATE_START_DONE);
6969 break;
6970
6971 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006972 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006973 OMX_COMPONENT_GENERATE_STOP_DONE);
6974 break;
6975
6976 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006977 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006978 OMX_COMPONENT_GENERATE_RESUME_DONE);
6979 break;
6980
6981 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006982 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006983 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6984 break;
6985
6986 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006987 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006988 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6989 break;
6990 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006991 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006992 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6993 break;
6994 case VDEC_MSG_RESP_INPUT_FLUSHED:
6995 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6996
Shalaj Jain286b0062013-02-21 20:35:48 -08006997 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6998 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006999
7000 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7001 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7002 if (omxhdr == NULL ||
7003 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
7004 {
7005 omxhdr = NULL;
7006 vdec_msg->status_code = VDEC_S_EFATAL;
7007 }
7008
7009 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7010 OMX_COMPONENT_GENERATE_EBD);
7011 break;
7012 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7013 int64_t *timestamp;
7014 timestamp = (int64_t *) malloc(sizeof(int64_t));
7015 if (timestamp) {
7016 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7017 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7018 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
7019 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
7020 vdec_msg->msgdata.output_frame.time_stamp);
7021 }
7022 break;
7023 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7024 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7025
7026 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7027 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
7028 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
7029 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
7030 vdec_msg->msgdata.output_frame.pic_type);
7031
7032 if (omxhdr && omxhdr->pOutputPortPrivate &&
7033 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
7034 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
7035 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
7036 {
7037 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
7038 {
7039 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7040 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007041 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007042 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
7043
7044 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
7045 {
7046 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7047 //rc = -1;
7048 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08007049 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
7050 {
7051 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7052 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007053 vdec_msg->msgdata.output_frame.bufferaddr =
7054 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007055 int format_notably_changed = 0;
7056 if (omxhdr->nFilledLen &&
7057 (omxhdr->nFilledLen != omx->prev_n_filled_len))
7058 {
7059 struct v4l2_format fmt;
7060 int ret;
7061 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7062 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7063 if (ret) {
7064 DEBUG_PRINT_HIGH("Failed to get format from driver\n");
7065 } else {
7066 if(omx->update_resolution(fmt.fmt.pix_mp.width,
7067 fmt.fmt.pix_mp.height,
7068 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7069 fmt.fmt.pix_mp.plane_fmt[0].reserved[0])) {
7070 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7071 format_notably_changed = 1;
7072 }
7073 }
7074 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007075 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7076 vdec_msg->msgdata.output_frame.framesize.left)
7077 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08007078 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7079 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
Vinay Kaliafa7cc352013-04-03 17:02:37 -07007080 struct v4l2_format fmt;
7081 int ret;
7082 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7083 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7084 if (ret) {
7085 DEBUG_PRINT_HIGH("Failed to get format from driver\n");
7086 } else {
7087 if(omx->update_resolution(fmt.fmt.pix_mp.width,
7088 fmt.fmt.pix_mp.height,
7089 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7090 fmt.fmt.pix_mp.plane_fmt[0].reserved[0])) {
7091 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7092 }
7093 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08007094 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7095 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7096 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7097 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
7098 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
Vinay Kaliab9e98102013-04-02 19:31:43 -07007099 format_notably_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08007100 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007101 if (format_notably_changed) {
7102 if(omx->is_video_session_supported()) {
7103 omx->post_event (NULL, vdec_msg->status_code,
7104 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7105 } else {
7106 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7107 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7108 }
7109 }
7110 if (omxhdr->nFilledLen)
7111 omx->prev_n_filled_len = omxhdr->nFilledLen;
7112
Shalaj Jain273b3e02012-06-22 19:08:03 -07007113 output_respbuf = (struct vdec_output_frameinfo *)\
7114 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007115 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7116 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08007117 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7118 {
7119 output_respbuf->pic_type = PICTURE_TYPE_I;
7120 }
7121 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7122 {
7123 output_respbuf->pic_type = PICTURE_TYPE_P;
7124 }
7125 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7126 output_respbuf->pic_type = PICTURE_TYPE_B;
7127 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007128
7129 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007130 memcpy ( omxhdr->pBuffer, (void *)
7131 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7132 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7133 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007134 }
7135 else
7136 omxhdr->nFilledLen = 0;
7137 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7138 OMX_COMPONENT_GENERATE_FBD);
7139 }
7140 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007141 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007142 OMX_COMPONENT_GENERATE_EOS_DONE);
7143 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007144 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007145 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7146 break;
7147 case VDEC_MSG_EVT_CONFIG_CHANGED:
7148 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007149 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7150 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007151 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007152 default:
7153 break;
7154 }
7155 return rc;
7156}
7157
7158OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7159 OMX_HANDLETYPE hComp,
7160 OMX_BUFFERHEADERTYPE *buffer
7161 )
7162{
7163 unsigned address,p2,id;
7164 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7165
7166 if (buffer == NULL)
7167 {
7168 return OMX_ErrorBadParameter;
7169 }
7170 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007171 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7172 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007173
7174 /* return zero length and not an EOS buffer */
7175 /* return buffer if input flush in progress */
7176 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7177 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7178 {
7179 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7180 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7181 return OMX_ErrorNone;
7182 }
7183
7184 if (psource_frame == NULL)
7185 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007186 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007187 psource_frame = buffer;
7188 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7189 push_input_buffer (hComp);
7190 }
7191 else
7192 {
7193 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007194 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7195 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007196 {
7197 return OMX_ErrorBadParameter;
7198 }
7199 }
7200
7201
7202 return OMX_ErrorNone;
7203}
7204
7205OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7206{
7207 unsigned address,p2,id;
7208 OMX_ERRORTYPE ret = OMX_ErrorNone;
7209
7210 if (pdest_frame == NULL || psource_frame == NULL)
7211 {
7212 /*Check if we have a destination buffer*/
7213 if (pdest_frame == NULL)
7214 {
7215 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7216 if (m_input_free_q.m_size)
7217 {
7218 m_input_free_q.pop_entry(&address,&p2,&id);
7219 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7220 pdest_frame->nFilledLen = 0;
7221 pdest_frame->nTimeStamp = LLONG_MAX;
7222 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7223 }
7224 }
7225
7226 /*Check if we have a destination buffer*/
7227 if (psource_frame == NULL)
7228 {
7229 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7230 if (m_input_pending_q.m_size)
7231 {
7232 m_input_pending_q.pop_entry(&address,&p2,&id);
7233 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007234 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007235 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007236 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007237 psource_frame->nFlags,psource_frame->nFilledLen);
7238
7239 }
7240 }
7241
7242 }
7243
7244 while ((pdest_frame != NULL) && (psource_frame != NULL))
7245 {
7246 switch (codec_type_parse)
7247 {
7248 case CODEC_TYPE_MPEG4:
7249 case CODEC_TYPE_H263:
7250 case CODEC_TYPE_MPEG2:
7251 ret = push_input_sc_codec(hComp);
7252 break;
7253 case CODEC_TYPE_H264:
7254 ret = push_input_h264(hComp);
7255 break;
7256 case CODEC_TYPE_VC1:
7257 ret = push_input_vc1(hComp);
7258 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007259 default:
7260 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007261 }
7262 if (ret != OMX_ErrorNone)
7263 {
7264 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7265 omx_report_error ();
7266 break;
7267 }
7268 }
7269
7270 return ret;
7271}
7272
7273OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7274{
7275 OMX_U32 partial_frame = 1;
7276 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007277 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007278
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007279 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007280 psource_frame,psource_frame->nTimeStamp);
7281 if (m_frame_parser.parse_sc_frame(psource_frame,
7282 pdest_frame,&partial_frame) == -1)
7283 {
7284 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7285 return OMX_ErrorBadParameter;
7286 }
7287
7288 if (partial_frame == 0)
7289 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007290 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007291 pdest_frame->nFilledLen,psource_frame,frame_count);
7292
7293
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007294 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007295 /*First Parsed buffer will have only header Hence skip*/
7296 if (frame_count == 0)
7297 {
7298 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7299
7300 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7301 codec_type_parse == CODEC_TYPE_DIVX) {
7302 mp4StreamType psBits;
7303 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7304 psBits.numBytes = pdest_frame->nFilledLen;
7305 mp4_headerparser.parseHeader(&psBits);
7306 }
7307
7308 frame_count++;
7309 }
7310 else
7311 {
7312 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7313 if(pdest_frame->nFilledLen)
7314 {
7315 /*Push the frame to the Decoder*/
7316 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7317 {
7318 return OMX_ErrorBadParameter;
7319 }
7320 frame_count++;
7321 pdest_frame = NULL;
7322
7323 if (m_input_free_q.m_size)
7324 {
7325 m_input_free_q.pop_entry(&address,&p2,&id);
7326 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7327 pdest_frame->nFilledLen = 0;
7328 }
7329 }
7330 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7331 {
7332 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007333 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7334 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007335 pdest_frame = NULL;
7336 }
7337 }
7338 }
7339 else
7340 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007341 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007342 /*Check if Destination Buffer is full*/
7343 if (pdest_frame->nAllocLen ==
7344 pdest_frame->nFilledLen + pdest_frame->nOffset)
7345 {
7346 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7347 return OMX_ErrorStreamCorrupt;
7348 }
7349 }
7350
7351 if (psource_frame->nFilledLen == 0)
7352 {
7353 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7354 {
7355 if (pdest_frame)
7356 {
7357 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007358 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007359 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007360 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007361 pdest_frame->nFilledLen,frame_count++);
7362 /*Push the frame to the Decoder*/
7363 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7364 {
7365 return OMX_ErrorBadParameter;
7366 }
7367 frame_count++;
7368 pdest_frame = NULL;
7369 }
7370 else
7371 {
7372 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7373 generate_ebd = OMX_FALSE;
7374 }
7375 }
7376 if(generate_ebd)
7377 {
7378 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7379 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7380 psource_frame = NULL;
7381
7382 if (m_input_pending_q.m_size)
7383 {
7384 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7385 m_input_pending_q.pop_entry(&address,&p2,&id);
7386 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007387 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007388 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007389 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 psource_frame->nFlags,psource_frame->nFilledLen);
7391 }
7392 }
7393 }
7394 return OMX_ErrorNone;
7395}
7396
7397OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7398{
7399 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007400 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007401 OMX_BOOL isNewFrame = OMX_FALSE;
7402 OMX_BOOL generate_ebd = OMX_TRUE;
7403
7404 if (h264_scratch.pBuffer == NULL)
7405 {
7406 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7407 return OMX_ErrorBadParameter;
7408 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007409 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007410 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007411 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007412 if (h264_scratch.nFilledLen && look_ahead_nal)
7413 {
7414 look_ahead_nal = false;
7415 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7416 h264_scratch.nFilledLen)
7417 {
7418 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7419 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7420 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7421 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7422 h264_scratch.nFilledLen = 0;
7423 }
7424 else
7425 {
7426 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7427 return OMX_ErrorBadParameter;
7428 }
7429 }
7430 if (nal_length == 0)
7431 {
7432 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7433 if (m_frame_parser.parse_sc_frame(psource_frame,
7434 &h264_scratch,&partial_frame) == -1)
7435 {
7436 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7437 return OMX_ErrorBadParameter;
7438 }
7439 }
7440 else
7441 {
7442 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7443 if (m_frame_parser.parse_h264_nallength(psource_frame,
7444 &h264_scratch,&partial_frame) == -1)
7445 {
7446 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7447 return OMX_ErrorBadParameter;
7448 }
7449 }
7450
7451 if (partial_frame == 0)
7452 {
7453 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7454 {
7455 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7456 nal_count++;
7457 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7458 h264_scratch.nFlags = psource_frame->nFlags;
7459 }
7460 else
7461 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007462 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007463 if(h264_scratch.nFilledLen)
7464 {
7465 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7466 NALU_TYPE_SPS);
7467#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7468 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7469 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7470 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7471 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7472 // If timeinfo is present frame info from SEI is already processed
7473 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7474 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7475#endif
7476 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7477 nal_count++;
7478 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7479 pdest_frame->nTimeStamp = h264_last_au_ts;
7480 pdest_frame->nFlags = h264_last_au_flags;
7481#ifdef PANSCAN_HDLR
7482 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7483 h264_parser->update_panscan_data(h264_last_au_ts);
7484#endif
7485 }
7486 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7487 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7488 h264_last_au_ts = h264_scratch.nTimeStamp;
7489 h264_last_au_flags = h264_scratch.nFlags;
7490#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7491 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7492 {
7493 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7494 if (!VALID_TS(h264_last_au_ts))
7495 h264_last_au_ts = ts_in_sei;
7496 }
7497#endif
7498 } else
7499 h264_last_au_ts = LLONG_MAX;
7500 }
7501
7502 if (!isNewFrame)
7503 {
7504 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7505 h264_scratch.nFilledLen)
7506 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007507 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007508 h264_scratch.nFilledLen);
7509 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7510 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7511 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7512 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7513 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7514 h264_scratch.nFilledLen = 0;
7515 }
7516 else
7517 {
7518 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7519 return OMX_ErrorBadParameter;
7520 }
7521 }
7522 else
7523 {
7524 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007525 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007526 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007527 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007528 pdest_frame->nFilledLen,frame_count++);
7529
7530 if (pdest_frame->nFilledLen == 0)
7531 {
7532 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7533 look_ahead_nal = false;
7534 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7535 h264_scratch.nFilledLen)
7536 {
7537 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7538 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7539 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7540 h264_scratch.nFilledLen = 0;
7541 }
7542 else
7543 {
7544 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7545 return OMX_ErrorBadParameter;
7546 }
7547 }
7548 else
7549 {
7550 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7551 {
7552 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7553 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7554 }
7555 /*Push the frame to the Decoder*/
7556 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7557 {
7558 return OMX_ErrorBadParameter;
7559 }
7560 //frame_count++;
7561 pdest_frame = NULL;
7562 if (m_input_free_q.m_size)
7563 {
7564 m_input_free_q.pop_entry(&address,&p2,&id);
7565 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7566 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7567 pdest_frame->nFilledLen = 0;
7568 pdest_frame->nFlags = 0;
7569 pdest_frame->nTimeStamp = LLONG_MAX;
7570 }
7571 }
7572 }
7573 }
7574 }
7575 else
7576 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007577 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007578 /*Check if Destination Buffer is full*/
7579 if (h264_scratch.nAllocLen ==
7580 h264_scratch.nFilledLen + h264_scratch.nOffset)
7581 {
7582 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7583 return OMX_ErrorStreamCorrupt;
7584 }
7585 }
7586
7587 if (!psource_frame->nFilledLen)
7588 {
7589 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7590
7591 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7592 {
7593 if (pdest_frame)
7594 {
7595 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7596 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7597 h264_scratch.nFilledLen)
7598 {
7599 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7600 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7601 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7602 h264_scratch.nFilledLen = 0;
7603 }
7604 else
7605 {
7606 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7607 return OMX_ErrorBadParameter;
7608 }
7609 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7610 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7611
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007612 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007613 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7614 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7615#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7616 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7617 {
7618 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7619 if (!VALID_TS(pdest_frame->nTimeStamp))
7620 pdest_frame->nTimeStamp = ts_in_sei;
7621 }
7622#endif
7623 /*Push the frame to the Decoder*/
7624 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7625 {
7626 return OMX_ErrorBadParameter;
7627 }
7628 frame_count++;
7629 pdest_frame = NULL;
7630 }
7631 else
7632 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007633 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007634 pdest_frame,h264_scratch.nFilledLen);
7635 generate_ebd = OMX_FALSE;
7636 }
7637 }
7638 }
7639 if(generate_ebd && !psource_frame->nFilledLen)
7640 {
7641 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7642 psource_frame = NULL;
7643 if (m_input_pending_q.m_size)
7644 {
7645 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7646 m_input_pending_q.pop_entry(&address,&p2,&id);
7647 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007648 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649 psource_frame->nFlags,psource_frame->nFilledLen);
7650 }
7651 }
7652 return OMX_ErrorNone;
7653}
7654
7655OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7656{
7657 OMX_U8 *buf, *pdest;
7658 OMX_U32 partial_frame = 1;
7659 OMX_U32 buf_len, dest_len;
7660
7661 if(first_frame == 0)
7662 {
7663 first_frame = 1;
7664 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7665 if(!m_vendor_config.pData)
7666 {
7667 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7668 buf = psource_frame->pBuffer;
7669 buf_len = psource_frame->nFilledLen;
7670
7671 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7672 VC1_SP_MP_START_CODE)
7673 {
7674 m_vc1_profile = VC1_SP_MP_RCV;
7675 }
7676 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7677 {
7678 m_vc1_profile = VC1_AP;
7679 }
7680 else
7681 {
7682 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7683 return OMX_ErrorStreamCorrupt;
7684 }
7685 }
7686 else
7687 {
7688 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7689 pdest_frame->nOffset;
7690 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7691 pdest_frame->nOffset);
7692
7693 if(dest_len < m_vendor_config.nDataSize)
7694 {
7695 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7696 return OMX_ErrorBadParameter;
7697 }
7698 else
7699 {
7700 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7701 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7702 }
7703 }
7704 }
7705
7706 switch(m_vc1_profile)
7707 {
7708 case VC1_AP:
7709 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7710 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7711 {
7712 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7713 return OMX_ErrorBadParameter;
7714 }
7715 break;
7716
7717 case VC1_SP_MP_RCV:
7718 default:
7719 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7720 return OMX_ErrorBadParameter;
7721 }
7722 return OMX_ErrorNone;
7723}
7724
David Ng38e2d232013-03-15 20:05:58 -07007725#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007726bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7727 OMX_U32 alignment)
7728{
7729 struct pmem_allocation allocation;
7730 allocation.size = buffer_size;
7731 allocation.align = clip2(alignment);
7732 if (allocation.align < 4096)
7733 {
7734 allocation.align = 4096;
7735 }
7736 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7737 {
7738 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7739 allocation.align, allocation.size);
7740 return false;
7741 }
7742 return true;
7743}
David Ng38e2d232013-03-15 20:05:58 -07007744#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007745#ifdef USE_ION
7746int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7747 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7748 struct ion_fd_data *fd_data, int flag)
7749{
7750 int fd = -EINVAL;
7751 int rc = -EINVAL;
7752 int ion_dev_flag;
7753 struct vdec_ion ion_buf_info;
7754 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7755 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7756 return -EINVAL;
7757 }
Arun Menon737de532012-09-14 14:48:18 -07007758 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007759 fd = open (MEM_DEVICE, ion_dev_flag);
7760 if (fd < 0) {
7761 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7762 return fd;
7763 }
Arun Menon737de532012-09-14 14:48:18 -07007764 alloc_data->flags = 0;
7765 if(!secure_mode && (flag & ION_FLAG_CACHED))
7766 {
7767 alloc_data->flags |= ION_FLAG_CACHED;
7768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007769 alloc_data->len = buffer_size;
7770 alloc_data->align = clip2(alignment);
7771 if (alloc_data->align < 4096)
7772 {
7773 alloc_data->align = 4096;
7774 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007775 if ((secure_mode) && (flag & ION_SECURE))
7776 alloc_data->flags |= ION_SECURE;
7777
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007778 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7779 if (secure_mode)
7780 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007781 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7782 if (rc || !alloc_data->handle) {
7783 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7784 alloc_data->handle = NULL;
7785 close(fd);
7786 fd = -ENOMEM;
7787 return fd;
7788 }
7789 fd_data->handle = alloc_data->handle;
7790 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7791 if (rc) {
7792 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7793 ion_buf_info.ion_alloc_data = *alloc_data;
7794 ion_buf_info.ion_device_fd = fd;
7795 ion_buf_info.fd_ion_data = *fd_data;
7796 free_ion_memory(&ion_buf_info);
7797 fd_data->fd =-1;
7798 close(fd);
7799 fd = -ENOMEM;
7800 }
7801
7802 return fd;
7803}
7804
7805void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7806
7807 if(!buf_ion_info) {
7808 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7809 return;
7810 }
7811 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7812 &buf_ion_info->ion_alloc_data.handle)) {
7813 DEBUG_PRINT_ERROR("\n ION: free failed" );
7814 }
7815 close(buf_ion_info->ion_device_fd);
7816 buf_ion_info->ion_device_fd = -1;
7817 buf_ion_info->ion_alloc_data.handle = NULL;
7818 buf_ion_info->fd_ion_data.fd = -1;
7819}
7820#endif
7821void omx_vdec::free_output_buffer_header()
7822{
7823 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7824 output_use_buffer = false;
7825 ouput_egl_buffers = false;
7826
7827 if (m_out_mem_ptr)
7828 {
7829 free (m_out_mem_ptr);
7830 m_out_mem_ptr = NULL;
7831 }
7832
7833 if(m_platform_list)
7834 {
7835 free(m_platform_list);
7836 m_platform_list = NULL;
7837 }
7838
7839 if (drv_ctx.ptr_respbuffer)
7840 {
7841 free (drv_ctx.ptr_respbuffer);
7842 drv_ctx.ptr_respbuffer = NULL;
7843 }
7844 if (drv_ctx.ptr_outputbuffer)
7845 {
7846 free (drv_ctx.ptr_outputbuffer);
7847 drv_ctx.ptr_outputbuffer = NULL;
7848 }
7849#ifdef USE_ION
7850 if (drv_ctx.op_buf_ion_info) {
7851 DEBUG_PRINT_LOW("\n Free o/p ion context");
7852 free(drv_ctx.op_buf_ion_info);
7853 drv_ctx.op_buf_ion_info = NULL;
7854 }
7855#endif
7856}
7857
7858void omx_vdec::free_input_buffer_header()
7859{
7860 input_use_buffer = false;
7861 if (arbitrary_bytes)
7862 {
7863 if (m_frame_parser.mutils)
7864 {
7865 DEBUG_PRINT_LOW("\n Free utils parser");
7866 delete (m_frame_parser.mutils);
7867 m_frame_parser.mutils = NULL;
7868 }
7869
7870 if (m_inp_heap_ptr)
7871 {
7872 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7873 free (m_inp_heap_ptr);
7874 m_inp_heap_ptr = NULL;
7875 }
7876
7877 if (m_phdr_pmem_ptr)
7878 {
7879 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7880 free (m_phdr_pmem_ptr);
7881 m_phdr_pmem_ptr = NULL;
7882 }
7883 }
7884 if (m_inp_mem_ptr)
7885 {
7886 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7887 free (m_inp_mem_ptr);
7888 m_inp_mem_ptr = NULL;
7889 }
7890 if (drv_ctx.ptr_inputbuffer)
7891 {
7892 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7893 free (drv_ctx.ptr_inputbuffer);
7894 drv_ctx.ptr_inputbuffer = NULL;
7895 }
7896#ifdef USE_ION
7897 if (drv_ctx.ip_buf_ion_info) {
7898 DEBUG_PRINT_LOW("\n Free ion context");
7899 free(drv_ctx.ip_buf_ion_info);
7900 drv_ctx.ip_buf_ion_info = NULL;
7901 }
7902#endif
7903}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007904
7905int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007906{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007907 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007908 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007909 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007910
7911 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7912 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7913 v4l2_port = OUTPUT_PORT;
7914 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7915 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7916 v4l2_port = CAPTURE_PORT;
7917 } else if (port == OMX_ALL) {
7918 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7919 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7920
7921 if (!rc_input)
7922 return rc_input;
7923 else
7924 return rc_output;
7925 }
7926
7927 if (!streaming[v4l2_port]) {
7928 // already streamed off, warn and move on
7929 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7930 " which is already streamed off", v4l2_port);
7931 return 0;
7932 }
7933
7934 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7935
Shalaj Jain273b3e02012-06-22 19:08:03 -07007936 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7937 if (rc) {
7938 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007939 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007941 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007942 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007943
7944 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007945}
7946
7947OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7948{
7949 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7950 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007951 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007952 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007953 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007954 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7955 buffer_prop->actualcount, buffer_prop->buffer_size);
7956 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007957 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007958 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7959 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7960 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7961 fmt.fmt.pix_mp.pixelformat = output_capability;
7962 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7963 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7964 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7965 fmt.fmt.pix_mp.pixelformat = capture_capability;
7966 }else {eRet = OMX_ErrorBadParameter;}
7967 if(eRet==OMX_ErrorNone){
7968 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7969 }
7970 if(ret)
7971 {
7972 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7973 /*TODO: How to handle this case */
7974 eRet = OMX_ErrorInsufficientResources;
7975 return eRet;
7976 }
7977 else
7978 {
7979 buffer_prop->actualcount = bufreq.count;
7980 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007981 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007982 }
7983 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7984 buffer_prop->actualcount, buffer_prop->buffer_size);
7985
7986 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7987 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7988
7989 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7990
Vinay Kalia21649b32013-03-18 17:28:07 -07007991 update_resolution(fmt.fmt.pix_mp.width,
7992 fmt.fmt.pix_mp.height,
7993 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7994 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007995 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7996 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007997 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998
7999 if(ret)
8000 {
8001 /*TODO: How to handle this case */
8002 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8003 eRet = OMX_ErrorInsufficientResources;
8004 }
8005 else
8006 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008007 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08008008
8009 eRet = is_video_session_supported();
8010 if (eRet)
8011 return eRet;
8012
Shalaj Jain273b3e02012-06-22 19:08:03 -07008013 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8014 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008015 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8016 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8017 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8018 } else if (extra_idx >= VIDEO_MAX_PLANES) {
8019 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
8020 return OMX_ErrorBadParameter;
8021 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008022 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8023 {
8024 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008025 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008026 }
8027 if (client_extradata & OMX_INTERLACE_EXTRADATA)
8028 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008029 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008030 }
8031 if (client_extradata & OMX_PORTDEF_EXTRADATA)
8032 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008033 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
8034 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
8035 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008036 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008037 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008038 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008039 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07008040 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
8041 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008042 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
8043 drv_ctx.extradata_info.count = buffer_prop->actualcount;
8044 drv_ctx.extradata_info.buffer_size = extra_data_size;
8045 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008046 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8047 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008048 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008049 if (in_reconfig) // BufReq will be set to driver when port is disabled
8050 buffer_prop->buffer_size = buf_size;
8051 else if (buf_size != buffer_prop->buffer_size)
8052 {
8053 buffer_prop->buffer_size = buf_size;
8054 eRet = set_buffer_req(buffer_prop);
8055 }
8056 }
8057 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8058 buffer_prop->actualcount, buffer_prop->buffer_size);
8059 return eRet;
8060}
8061
8062OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8063{
8064 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8065 unsigned buf_size = 0;
8066 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008067 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008068 int ret;
8069 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8070 buffer_prop->actualcount, buffer_prop->buffer_size);
8071 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8072 if (buf_size != buffer_prop->buffer_size)
8073 {
8074 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8075 buffer_prop->buffer_size, buf_size);
8076 eRet = OMX_ErrorBadParameter;
8077 }
8078 else
8079 {
8080 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8081 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008082
8083 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8084 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8085 fmt.fmt.pix_mp.pixelformat = output_capability;
8086 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8087 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8088 fmt.fmt.pix_mp.pixelformat = capture_capability;
8089 } else {eRet = OMX_ErrorBadParameter;}
8090
8091 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8092 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008093 {
8094 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008095 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008096 eRet = OMX_ErrorInsufficientResources;
8097 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008098
8099 bufreq.memory = V4L2_MEMORY_USERPTR;
8100 bufreq.count = buffer_prop->actualcount;
8101 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8102 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8103 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8104 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8105 } else {eRet = OMX_ErrorBadParameter;}
8106
8107 if (eRet==OMX_ErrorNone) {
8108 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8109 }
8110
8111 if (ret)
8112 {
8113 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8114 /*TODO: How to handle this case */
8115 eRet = OMX_ErrorInsufficientResources;
8116 } else if (bufreq.count < buffer_prop->actualcount) {
8117 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8118 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8119 buffer_prop->actualcount, bufreq.count);
8120 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008121 } else {
8122 if (!client_buffers.update_buffer_req()) {
8123 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8124 eRet = OMX_ErrorInsufficientResources;
8125 }
8126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008127 }
8128 return eRet;
8129}
8130
Shalaj Jain273b3e02012-06-22 19:08:03 -07008131OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8132{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008133 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008134 return eRet;
8135}
8136
8137OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8138{
8139 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8140 if (!portDefn)
8141 {
8142 return OMX_ErrorBadParameter;
8143 }
8144 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8145 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8146 portDefn->nSize = sizeof(portDefn);
8147 portDefn->eDomain = OMX_PortDomainVideo;
8148 if (drv_ctx.frame_rate.fps_denominator > 0)
8149 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8150 drv_ctx.frame_rate.fps_denominator;
8151 else {
8152 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8153 return OMX_ErrorBadParameter;
8154 }
8155 if (0 == portDefn->nPortIndex)
8156 {
8157 portDefn->eDir = OMX_DirInput;
8158 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8159 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8160 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8161 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8162 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8163 portDefn->bEnabled = m_inp_bEnabled;
8164 portDefn->bPopulated = m_inp_bPopulated;
8165 }
8166 else if (1 == portDefn->nPortIndex)
8167 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008168 unsigned int buf_size = 0;
8169 if (!client_buffers.update_buffer_req()) {
8170 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8171 return OMX_ErrorHardware;
8172 }
8173 if (!client_buffers.get_buffer_req(buf_size)) {
8174 DEBUG_PRINT_ERROR("\n update buffer requirements");
8175 return OMX_ErrorHardware;
8176 }
8177 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008178 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008179 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8180 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008181 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8182 portDefn->bEnabled = m_out_bEnabled;
8183 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008184 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8185 DEBUG_PRINT_ERROR("\n Error in getting color format");
8186 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008187 }
8188 }
8189 else
8190 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008191 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008192 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8193 (int)portDefn->nPortIndex);
8194 eRet = OMX_ErrorBadPortIndex;
8195 }
8196 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8197 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8198 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8199 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008200 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8201 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008202 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008203 portDefn->format.video.nStride,
8204 portDefn->format.video.nSliceHeight);
8205 return eRet;
8206
8207}
8208
8209OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8210{
8211 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8212 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8213 unsigned i= 0;
8214
8215 if(!m_out_mem_ptr) {
8216 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8217 int nBufHdrSize = 0;
8218 int nPlatformEntrySize = 0;
8219 int nPlatformListSize = 0;
8220 int nPMEMInfoSize = 0;
8221 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8222 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8223 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8224
8225 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8226 drv_ctx.op_buf.actualcount);
8227 nBufHdrSize = drv_ctx.op_buf.actualcount *
8228 sizeof(OMX_BUFFERHEADERTYPE);
8229
8230 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8231 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8232 nPlatformListSize = drv_ctx.op_buf.actualcount *
8233 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8234 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8235 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8236
8237 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8238 sizeof(OMX_BUFFERHEADERTYPE),
8239 nPMEMInfoSize,
8240 nPlatformListSize);
8241 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8242 m_out_bm_count);
8243 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8244 // Alloc mem for platform specific info
8245 char *pPtr=NULL;
8246 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8247 nPMEMInfoSize,1);
8248 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8249 calloc (sizeof(struct vdec_bufferpayload),
8250 drv_ctx.op_buf.actualcount);
8251 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8252 calloc (sizeof (struct vdec_output_frameinfo),
8253 drv_ctx.op_buf.actualcount);
8254#ifdef USE_ION
8255 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8256 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8257#endif
8258
8259 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8260 && drv_ctx.ptr_respbuffer)
8261 {
8262 bufHdr = m_out_mem_ptr;
8263 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8264 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8265 (((char *) m_platform_list) + nPlatformListSize);
8266 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8267 (((char *) m_platform_entry) + nPlatformEntrySize);
8268 pPlatformList = m_platform_list;
8269 pPlatformEntry = m_platform_entry;
8270 pPMEMInfo = m_pmem_info;
8271
8272 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8273
8274 // Settting the entire storage nicely
8275 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8276 m_out_mem_ptr,pPlatformEntry);
8277 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8278 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8279 {
8280 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8281 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8282 // Set the values when we determine the right HxW param
8283 bufHdr->nAllocLen = 0;
8284 bufHdr->nFilledLen = 0;
8285 bufHdr->pAppPrivate = NULL;
8286 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8287 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8288 pPlatformEntry->entry = pPMEMInfo;
8289 // Initialize the Platform List
8290 pPlatformList->nEntries = 1;
8291 pPlatformList->entryList = pPlatformEntry;
8292 // Keep pBuffer NULL till vdec is opened
8293 bufHdr->pBuffer = NULL;
8294 pPMEMInfo->offset = 0;
8295 pPMEMInfo->pmem_fd = 0;
8296 bufHdr->pPlatformPrivate = pPlatformList;
8297 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8298#ifdef USE_ION
8299 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8300#endif
8301 /*Create a mapping between buffers*/
8302 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8303 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8304 &drv_ctx.ptr_outputbuffer[i];
8305 // Move the buffer and buffer header pointers
8306 bufHdr++;
8307 pPMEMInfo++;
8308 pPlatformEntry++;
8309 pPlatformList++;
8310 }
8311 }
8312 else
8313 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008314 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008315 m_out_mem_ptr, pPtr);
8316 if(m_out_mem_ptr)
8317 {
8318 free(m_out_mem_ptr);
8319 m_out_mem_ptr = NULL;
8320 }
8321 if(pPtr)
8322 {
8323 free(pPtr);
8324 pPtr = NULL;
8325 }
8326 if(drv_ctx.ptr_outputbuffer)
8327 {
8328 free(drv_ctx.ptr_outputbuffer);
8329 drv_ctx.ptr_outputbuffer = NULL;
8330 }
8331 if(drv_ctx.ptr_respbuffer)
8332 {
8333 free(drv_ctx.ptr_respbuffer);
8334 drv_ctx.ptr_respbuffer = NULL;
8335 }
8336#ifdef USE_ION
8337 if (drv_ctx.op_buf_ion_info) {
8338 DEBUG_PRINT_LOW("\n Free o/p ion context");
8339 free(drv_ctx.op_buf_ion_info);
8340 drv_ctx.op_buf_ion_info = NULL;
8341 }
8342#endif
8343 eRet = OMX_ErrorInsufficientResources;
8344 }
8345 } else {
8346 eRet = OMX_ErrorInsufficientResources;
8347 }
8348 return eRet;
8349}
8350
8351void omx_vdec::complete_pending_buffer_done_cbs()
8352{
8353 unsigned p1;
8354 unsigned p2;
8355 unsigned ident;
8356 omx_cmd_queue tmp_q, pending_bd_q;
8357 pthread_mutex_lock(&m_lock);
8358 // pop all pending GENERATE FDB from ftb queue
8359 while (m_ftb_q.m_size)
8360 {
8361 m_ftb_q.pop_entry(&p1,&p2,&ident);
8362 if(ident == OMX_COMPONENT_GENERATE_FBD)
8363 {
8364 pending_bd_q.insert_entry(p1,p2,ident);
8365 }
8366 else
8367 {
8368 tmp_q.insert_entry(p1,p2,ident);
8369 }
8370 }
8371 //return all non GENERATE FDB to ftb queue
8372 while(tmp_q.m_size)
8373 {
8374 tmp_q.pop_entry(&p1,&p2,&ident);
8375 m_ftb_q.insert_entry(p1,p2,ident);
8376 }
8377 // pop all pending GENERATE EDB from etb queue
8378 while (m_etb_q.m_size)
8379 {
8380 m_etb_q.pop_entry(&p1,&p2,&ident);
8381 if(ident == OMX_COMPONENT_GENERATE_EBD)
8382 {
8383 pending_bd_q.insert_entry(p1,p2,ident);
8384 }
8385 else
8386 {
8387 tmp_q.insert_entry(p1,p2,ident);
8388 }
8389 }
8390 //return all non GENERATE FDB to etb queue
8391 while(tmp_q.m_size)
8392 {
8393 tmp_q.pop_entry(&p1,&p2,&ident);
8394 m_etb_q.insert_entry(p1,p2,ident);
8395 }
8396 pthread_mutex_unlock(&m_lock);
8397 // process all pending buffer dones
8398 while(pending_bd_q.m_size)
8399 {
8400 pending_bd_q.pop_entry(&p1,&p2,&ident);
8401 switch(ident)
8402 {
8403 case OMX_COMPONENT_GENERATE_EBD:
8404 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8405 {
8406 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8407 omx_report_error ();
8408 }
8409 break;
8410
8411 case OMX_COMPONENT_GENERATE_FBD:
8412 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8413 {
8414 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8415 omx_report_error ();
8416 }
8417 break;
8418 }
8419 }
8420}
8421
8422void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8423{
8424 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008425 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8426 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8427 {
8428 new_frame_interval = (act_timestamp > prev_ts)?
8429 act_timestamp - prev_ts :
8430 prev_ts - act_timestamp;
8431 if (new_frame_interval < frm_int || frm_int == 0)
8432 {
8433 frm_int = new_frame_interval;
8434 if(frm_int)
8435 {
8436 drv_ctx.frame_rate.fps_numerator = 1e6;
8437 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008438 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008439 frm_int, drv_ctx.frame_rate.fps_numerator /
8440 (float)drv_ctx.frame_rate.fps_denominator);
Praneeth Paladugu53478562013-03-12 14:49:46 -07008441 enableAdditionalCores(frm_int);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008442 }
8443 }
8444 }
8445 prev_ts = act_timestamp;
8446}
8447
8448void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8449{
8450 if (rst_prev_ts && VALID_TS(act_timestamp))
8451 {
8452 prev_ts = act_timestamp;
8453 rst_prev_ts = false;
8454 }
8455 else if (VALID_TS(prev_ts))
8456 {
8457 bool codec_cond = (drv_ctx.timestamp_adjust)?
8458 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8459 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8460 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8461 if(frm_int > 0 && codec_cond)
8462 {
8463 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8464 act_timestamp = prev_ts + frm_int;
8465 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8466 prev_ts = act_timestamp;
8467 }
8468 else
8469 set_frame_rate(act_timestamp);
8470 }
8471 else if (frm_int > 0) // In this case the frame rate was set along
8472 { // with the port definition, start ts with 0
8473 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8474 rst_prev_ts = true;
8475 }
8476}
8477
8478void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8479{
8480 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8481 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008482 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008483 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008484 OMX_U32 num_MB_in_frame;
8485 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008486 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008487 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008488 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8489 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008490 if (!drv_ctx.extradata_info.uaddr) {
8491 return;
8492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008493 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008494 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8495 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8496 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008497 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008498 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008499 if (data) {
8500 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008501 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008502 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008503 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008504 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008505 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008506 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008507 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008508 struct msm_vidc_interlace_payload *payload;
8509 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008510 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8511 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008512 OMX_U32 mbaff = 0;
8513 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8514 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8515 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8516 else
8517 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8518 if(m_enable_android_native_buffers)
8519 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008520 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008521 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008522 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8523 append_interlace_extradata(p_extra, payload->format);
8524 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8525 }
8526 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008527 case EXTRADATA_FRAME_RATE:
8528 struct msm_vidc_framerate_payload *frame_rate_payload;
8529 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8530 frame_rate = frame_rate_payload->frame_rate;
8531 break;
8532 case EXTRADATA_TIMESTAMP:
8533 struct msm_vidc_ts_payload *time_stamp_payload;
8534 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008535 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008536 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008537 break;
8538 case EXTRADATA_NUM_CONCEALED_MB:
8539 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8540 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8541 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8542 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8543 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8544 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008545 case EXTRADATA_ASPECT_RATIO:
8546 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8547 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8548 ((struct vdec_output_frameinfo *)
8549 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8550 ((struct vdec_output_frameinfo *)
8551 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8552 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008553 case EXTRADATA_RECOVERY_POINT_SEI:
8554 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8555 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8556 recovery_sei_flags = recovery_sei_payload->flags;
8557 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8558 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008559 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008560 }
8561 break;
8562 case EXTRADATA_PANSCAN_WINDOW:
8563 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8564 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008565 default:
8566 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008567 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008568 consumed_len += data->nSize;
8569 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008570 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008571 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008572 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008573 append_frame_info_extradata(p_extra,
8574 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008575 panscan_payload,&((struct vdec_output_frameinfo *)
8576 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008577 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008578unrecognized_extradata:
8579 if(!secure_mode && client_extradata)
8580 append_terminator_extradata(p_extra);
8581 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008582}
8583
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008584OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8585 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586{
8587 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008588 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008589 if(m_state != OMX_StateLoaded)
8590 {
8591 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8592 return OMX_ErrorIncorrectStateOperation;
8593 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008594 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008595 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008596
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008597 if (!is_internal) {
8598 if (enable)
8599 client_extradata |= requested_extradata;
8600 else
8601 client_extradata = client_extradata & ~requested_extradata;
8602 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008603
8604 if (enable) {
8605 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8606 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8607 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8608 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8609 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8610 " Quality of interlaced clips might be impacted.\n");
8611 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008612 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8613 {
8614 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8615 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8616 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8617 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8618 }
8619 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8620 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8621 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8622 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8623 }
8624 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8625 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8626 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8627 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8628 }
8629 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8630 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8631 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8632 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8633 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008634 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8635 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8636 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8637 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8638 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008639 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8640 {
8641 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8642 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8643 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8644 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8645 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008646 }
8647 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008648 return ret;
8649}
8650
8651OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8652{
8653 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8654 OMX_U8 *data_ptr = extra->data, data = 0;
8655 while (byte_count < extra->nDataSize)
8656 {
8657 data = *data_ptr;
8658 while (data)
8659 {
8660 num_MB += (data&0x01);
8661 data >>= 1;
8662 }
8663 data_ptr++;
8664 byte_count++;
8665 }
8666 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8667 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8668 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8669}
8670
8671void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8672{
8673 if (!m_debug_extradata)
8674 return;
8675
8676 DEBUG_PRINT_HIGH(
8677 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008678 " Size: %lu \n"
8679 " Version: %lu \n"
8680 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008681 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008682 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008683 extra->nSize, extra->nVersion.nVersion,
8684 extra->nPortIndex, extra->eType, extra->nDataSize);
8685
Shalaj Jain286b0062013-02-21 20:35:48 -08008686 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008687 {
8688 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8689 DEBUG_PRINT_HIGH(
8690 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008691 " Size: %lu \n"
8692 " Version: %lu \n"
8693 " PortIndex: %lu \n"
8694 " Is Interlace Format: %d \n"
8695 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008696 "=========== End of Interlace ===========\n",
8697 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8698 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8699 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008700 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008701 {
8702 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8703
8704 DEBUG_PRINT_HIGH(
8705 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008706 " Picture Type: %d \n"
8707 " Interlace Type: %d \n"
8708 " Pan Scan Total Frame Num: %lu \n"
8709 " Concealed Macro Blocks: %lu \n"
8710 " frame rate: %lu \n"
8711 " Aspect Ratio X: %lu \n"
8712 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008713 fminfo->ePicType,
8714 fminfo->interlaceType,
8715 fminfo->panScan.numWindows,
8716 fminfo->nConcealedMacroblocks,
8717 fminfo->nFrameRate,
8718 fminfo->aspectRatio.aspectRatioX,
8719 fminfo->aspectRatio.aspectRatioY);
8720
Praneeth Paladugu32284302013-02-14 22:53:06 -08008721 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008722 {
8723 DEBUG_PRINT_HIGH(
8724 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008725 " Pan Scan Frame Num: %lu \n"
8726 " Rectangle x: %ld \n"
8727 " Rectangle y: %ld \n"
8728 " Rectangle dx: %ld \n"
8729 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008730 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8731 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8732 }
8733
8734 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8735 }
8736 else if (extra->eType == OMX_ExtraDataNone)
8737 {
8738 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8739 }
8740 else
8741 {
8742 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8743 }
8744}
8745
8746void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8747 OMX_U32 interlaced_format_type)
8748{
8749 OMX_STREAMINTERLACEFORMAT *interlace_format;
8750 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008751 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8752 return;
8753 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008754 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8755 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8756 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8757 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8758 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8759 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8760 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8761 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8762 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8763 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008764 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008765 {
8766 interlace_format->bInterlaceFormat = OMX_FALSE;
8767 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8768 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8769 }
8770 else
8771 {
8772 interlace_format->bInterlaceFormat = OMX_TRUE;
8773 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8774 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8775 }
8776 print_debug_extradata(extra);
8777}
8778
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008779void omx_vdec::fill_aspect_ratio_info(
8780 struct vdec_aspectratioinfo *aspect_ratio_info,
8781 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8782{
8783 m_extradata = frame_info;
8784 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8785 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008786 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008787 m_extradata->aspectRatio.aspectRatioY);
8788}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008789
8790void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008791 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008792 struct msm_vidc_panscan_window_payload *panscan_payload,
8793 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008794{
8795 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008796 struct msm_vidc_panscan_window *panscan_window;
8797 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8798 return;
8799 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008800 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8801 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8802 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8803 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8804 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8805 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8806 switch (picture_type)
8807 {
8808 case PICTURE_TYPE_I:
8809 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8810 break;
8811 case PICTURE_TYPE_P:
8812 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8813 break;
8814 case PICTURE_TYPE_B:
8815 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8816 break;
8817 default:
8818 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8819 }
8820 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8821 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8822 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8823 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8824 else
8825 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008826 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008827 frame_info->nConcealedMacroblocks = num_conceal_mb;
8828 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008829 frame_info->panScan.numWindows = 0;
8830 if(panscan_payload) {
8831 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8832 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008833 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008834 {
8835 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8836 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8837 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8838 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8839 panscan_window++;
8840 }
8841 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008842 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008843 print_debug_extradata(extra);
8844}
8845
8846void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8847{
8848 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8849 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8850 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8851 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8852 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8853 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8854 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8855 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008856 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8857 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008858 portDefn->format.video.nFrameWidth,
8859 portDefn->format.video.nStride,
8860 portDefn->format.video.nSliceHeight);
8861}
8862
8863void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8864{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008865 if (!client_extradata) {
8866 return;
8867 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008868 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8869 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8870 extra->eType = OMX_ExtraDataNone;
8871 extra->nDataSize = 0;
8872 extra->data[0] = 0;
8873
8874 print_debug_extradata(extra);
8875}
8876
8877OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8878{
8879 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8880 if (index >= drv_ctx.ip_buf.actualcount)
8881 {
8882 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8883 return OMX_ErrorInsufficientResources;
8884 }
8885 if (m_desc_buffer_ptr == NULL)
8886 {
8887 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8888 calloc( (sizeof(desc_buffer_hdr)),
8889 drv_ctx.ip_buf.actualcount);
8890 if (m_desc_buffer_ptr == NULL)
8891 {
8892 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8893 return OMX_ErrorInsufficientResources;
8894 }
8895 }
8896
8897 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8898 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8899 {
8900 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8901 return OMX_ErrorInsufficientResources;
8902 }
8903
8904 return eRet;
8905}
8906
8907void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8908{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008909 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008910 if (m_demux_entries < 8192)
8911 {
8912 m_demux_offsets[m_demux_entries++] = address_offset;
8913 }
8914 return;
8915}
8916
8917void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8918{
8919 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8920 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8921 OMX_U32 index = 0;
8922
8923 m_demux_entries = 0;
8924
8925 while (index < bytes_to_parse)
8926 {
8927 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8928 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8929 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8930 (buf[index+2] == 0x01)) )
8931 {
8932 //Found start code, insert address offset
8933 insert_demux_addr_offset(index);
8934 if (buf[index+2] == 0x01) // 3 byte start code
8935 index += 3;
8936 else //4 byte start code
8937 index += 4;
8938 }
8939 else
8940 index++;
8941 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008942 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008943 return;
8944}
8945
8946OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8947{
8948 //fix this, handle 3 byte start code, vc1 terminator entry
8949 OMX_U8 *p_demux_data = NULL;
8950 OMX_U32 desc_data = 0;
8951 OMX_U32 start_addr = 0;
8952 OMX_U32 nal_size = 0;
8953 OMX_U32 suffix_byte = 0;
8954 OMX_U32 demux_index = 0;
8955 OMX_U32 buffer_index = 0;
8956
8957 if (m_desc_buffer_ptr == NULL)
8958 {
8959 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8960 return OMX_ErrorBadParameter;
8961 }
8962
8963 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8964 if (buffer_index > drv_ctx.ip_buf.actualcount)
8965 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008966 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008967 return OMX_ErrorBadParameter;
8968 }
8969
8970 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8971
8972 if ( ((OMX_U8*)p_demux_data == NULL) ||
8973 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8974 {
8975 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8976 return OMX_ErrorBadParameter;
8977 }
8978 else
8979 {
8980 for (; demux_index < m_demux_entries; demux_index++)
8981 {
8982 desc_data = 0;
8983 start_addr = m_demux_offsets[demux_index];
8984 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8985 {
8986 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8987 }
8988 else
8989 {
8990 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8991 }
8992 if (demux_index < (m_demux_entries - 1))
8993 {
8994 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8995 }
8996 else
8997 {
8998 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8999 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009000 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9001 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07009002 suffix_byte,
9003 nal_size,
9004 demux_index);
9005 desc_data = (start_addr >> 3) << 1;
9006 desc_data |= (start_addr & 7) << 21;
9007 desc_data |= suffix_byte << 24;
9008
9009 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9010 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9011 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9012 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9013
9014 p_demux_data += 16;
9015 }
9016 if (codec_type_parse == CODEC_TYPE_VC1)
9017 {
9018 DEBUG_PRINT_LOW("VC1 terminator entry");
9019 desc_data = 0;
9020 desc_data = 0x82 << 24;
9021 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9022 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9023 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9024 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9025 p_demux_data += 16;
9026 m_demux_entries++;
9027 }
9028 //Add zero word to indicate end of descriptors
9029 memset(p_demux_data, 0, sizeof(OMX_U32));
9030
9031 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009032 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009033 }
9034 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9035 m_demux_entries = 0;
9036 DEBUG_PRINT_LOW("Demux table complete!");
9037 return OMX_ErrorNone;
9038}
9039
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009040OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009041{
9042 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009043 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07009044 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07009045 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9046 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009047 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009048 delete iDivXDrmDecrypt;
9049 iDivXDrmDecrypt = NULL;
9050 }
9051 }
9052 else {
9053 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009054 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009055 }
9056 return err;
9057}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009058
Vinay Kaliada4f4422013-01-09 10:45:03 -08009059omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9060{
9061 enabled = false;
9062 omx = NULL;
9063 init_members();
9064 ColorFormat = OMX_COLOR_FormatMax;
9065}
9066
9067void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9068{
9069 omx = reinterpret_cast<omx_vdec*>(client);
9070}
9071
9072void omx_vdec::allocate_color_convert_buf::init_members() {
9073 allocated_count = 0;
9074 buffer_size_req = 0;
9075 buffer_alignment_req = 0;
9076 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9077 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9078 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9079 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9080#ifdef USE_ION
9081 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9082#endif
9083 for (int i = 0; i < MAX_COUNT;i++)
9084 pmem_fd[i] = -1;
9085}
9086
9087omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
9088 c2d.destroy();
9089}
9090
9091bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9092{
9093 bool status = true;
9094 unsigned int src_size = 0, destination_size = 0;
9095 OMX_COLOR_FORMATTYPE drv_color_format;
9096 if (!omx){
9097 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9098 return false;
9099 }
9100 if (!enabled){
9101 DEBUG_PRINT_ERROR("\n No color conversion required");
9102 return status;
9103 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009104 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009105 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9106 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9107 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009108 status = false;
9109 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009110 }
9111 c2d.close();
9112 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9113 omx->drv_ctx.video_resolution.frame_width,
9114 NV12_128m,YCbCr420P);
9115 if (status) {
9116 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9117 if (status)
9118 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9119 }
9120 if (status) {
9121 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9122 !destination_size) {
9123 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9124 "driver size %d destination size %d",
9125 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9126 status = false;
9127 c2d.close();
9128 buffer_size_req = 0;
9129 } else {
9130 buffer_size_req = destination_size;
9131 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9132 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9133 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9134 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9135 }
9136 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009137fail_update_buf_req:
9138 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009139 return status;
9140}
9141
9142bool omx_vdec::allocate_color_convert_buf::set_color_format(
9143 OMX_COLOR_FORMATTYPE dest_color_format)
9144{
9145 bool status = true;
9146 OMX_COLOR_FORMATTYPE drv_color_format;
9147 if (!omx){
9148 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9149 return false;
9150 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009151 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009152 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9153 drv_color_format = (OMX_COLOR_FORMATTYPE)
9154 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9155 else {
9156 DEBUG_PRINT_ERROR("\n Incorrect color format");
9157 status = false;
9158 }
9159 if (status && (drv_color_format != dest_color_format)) {
9160 DEBUG_PRINT_LOW("Enabling C2D\n");
9161 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9162 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9163 status = false;
9164 } else {
9165 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9166 if (enabled)
9167 c2d.destroy();
9168 enabled = false;
9169 if (!c2d.init()) {
9170 DEBUG_PRINT_ERROR("\n open failed for c2d");
9171 status = false;
9172 } else
9173 enabled = true;
9174 }
9175 } else {
9176 if (enabled)
9177 c2d.destroy();
9178 enabled = false;
9179 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009180 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009181 return status;
9182}
9183
9184OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9185{
9186 if (!omx){
9187 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9188 return NULL;
9189 }
9190 if (!enabled)
9191 return omx->m_out_mem_ptr;
9192 return m_out_mem_ptr_client;
9193}
9194
9195OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9196 (OMX_BUFFERHEADERTYPE *bufadd)
9197{
9198 if (!omx){
9199 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9200 return NULL;
9201 }
9202 if (!enabled)
9203 return bufadd;
9204
9205 unsigned index = 0;
9206 index = bufadd - omx->m_out_mem_ptr;
9207 if (index < omx->drv_ctx.op_buf.actualcount) {
9208 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9209 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9210 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009211 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009212 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009213 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9214 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009215 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009216 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9217 if (!status){
9218 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009219 m_out_mem_ptr_client[index].nFilledLen = 0;
9220 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009221 }
9222 } else
9223 m_out_mem_ptr_client[index].nFilledLen = 0;
9224 return &m_out_mem_ptr_client[index];
9225 }
9226 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9227 return NULL;
9228}
9229
9230OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9231 (OMX_BUFFERHEADERTYPE *bufadd)
9232{
9233 if (!omx){
9234 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9235 return NULL;
9236 }
9237 if (!enabled)
9238 return bufadd;
9239 unsigned index = 0;
9240 index = bufadd - m_out_mem_ptr_client;
9241 if (index < omx->drv_ctx.op_buf.actualcount) {
9242 return &omx->m_out_mem_ptr[index];
9243 }
9244 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9245 return NULL;
9246}
9247bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9248 (unsigned int &buffer_size)
9249{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009250 bool status = true;
9251 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009252 if (!enabled)
9253 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009254 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009255 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9256 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009257 status = false;
9258 goto fail_get_buffer_size;
9259 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009260 }
9261 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9262 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9263 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9264 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009265fail_get_buffer_size:
9266 pthread_mutex_unlock(&omx->c_lock);
9267 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009268}
9269OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9270 OMX_BUFFERHEADERTYPE *bufhdr) {
9271 unsigned int index = 0;
9272
9273 if (!enabled)
9274 return omx->free_output_buffer(bufhdr);
9275 if (enabled && omx->is_component_secure())
9276 return OMX_ErrorNone;
9277 if (!allocated_count || !bufhdr) {
9278 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9279 return OMX_ErrorBadParameter;
9280 }
9281 index = bufhdr - m_out_mem_ptr_client;
9282 if (index >= omx->drv_ctx.op_buf.actualcount){
9283 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9284 return OMX_ErrorBadParameter;
9285 }
9286 if (pmem_fd[index] > 0) {
9287 munmap(pmem_baseaddress[index], buffer_size_req);
9288 close(pmem_fd[index]);
9289 }
9290 pmem_fd[index] = -1;
9291#ifdef USE_ION
9292 omx->free_ion_memory(&op_buf_ion_info[index]);
9293#endif
9294 m_heap_ptr[index].video_heap_ptr = NULL;
9295 if (allocated_count > 0)
9296 allocated_count--;
9297 else
9298 allocated_count = 0;
9299 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009300 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009301 c2d.close();
9302 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009303 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009304 }
9305 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9306}
9307
9308OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9309 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9310{
9311 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9312 if (!enabled){
9313 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9314 return eRet;
9315 }
9316 if (enabled && omx->is_component_secure()) {
9317 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9318 omx->is_component_secure());
9319 return OMX_ErrorUnsupportedSetting;
9320 }
9321 if (!bufferHdr || bytes > buffer_size_req) {
9322 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009323 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009324 buffer_size_req,bytes);
9325 return OMX_ErrorBadParameter;
9326 }
9327 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9328 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9329 return OMX_ErrorInsufficientResources;
9330 }
9331 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9332 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9333 port,appData,omx->drv_ctx.op_buf.buffer_size);
9334 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9335 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9336 return eRet;
9337 }
9338 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9339 omx->drv_ctx.op_buf.actualcount) {
9340 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9341 (temp_bufferHdr - omx->m_out_mem_ptr));
9342 return OMX_ErrorUndefined;
9343 }
9344 unsigned int i = allocated_count;
9345#ifdef USE_ION
9346 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9347 buffer_size_req,buffer_alignment_req,
9348 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009349 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009350 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9351 if (op_buf_ion_info[i].ion_device_fd < 0) {
9352 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9353 return OMX_ErrorInsufficientResources;
9354 }
9355 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9356 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9357
9358 if (pmem_baseaddress[i] == MAP_FAILED) {
9359 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9360 close(pmem_fd[i]);
9361 omx->free_ion_memory(&op_buf_ion_info[i]);
9362 return OMX_ErrorInsufficientResources;
9363 }
9364 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9365 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9366 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9367#endif
9368 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9369 m_pmem_info_client[i].offset = 0;
9370 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9371 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9372 m_platform_list_client[i].nEntries = 1;
9373 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9374 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9375 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9376 m_out_mem_ptr_client[i].nFilledLen = 0;
9377 m_out_mem_ptr_client[i].nFlags = 0;
9378 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9379 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9380 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9381 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9382 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9383 m_out_mem_ptr_client[i].pAppPrivate = appData;
9384 *bufferHdr = &m_out_mem_ptr_client[i];
9385 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9386 allocated_count++;
9387 return eRet;
9388}
9389
9390bool omx_vdec::is_component_secure()
9391{
9392 return secure_mode;
9393}
9394
9395bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9396{
9397 bool status = true;
9398 if (!enabled) {
9399 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9400 dest_color_format = (OMX_COLOR_FORMATTYPE)
9401 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9402 else
9403 status = false;
9404 } else {
9405 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9406 status = false;
9407 } else
9408 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9409 }
9410 return status;
9411}
Praneeth Paladugu53478562013-03-12 14:49:46 -07009412
9413void omx_vdec::enableAdditionalCores(int frame_interval)
9414{
9415 DEBUG_PRINT_LOW("Setting frame rate to 1/(%dusec)", frame_interval);
9416 if (frame_interval < 33000)
9417 {
9418 DEBUG_PRINT_HIGH("Turning on additional CPU cores");
9419 if (NULL == opt_handle) {
9420 char opt_lib_path[PATH_MAX] = {0};
9421
9422 if (property_get("ro.vendor.extension_library", opt_lib_path, NULL) != 0) {
9423 if ((opt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
9424 DEBUG_PRINT_ERROR("Unable to open %s: %s\n", opt_lib_path, dlerror());
9425 } else {
9426 perf_lock_acq = (int(*)(int, int, int*,int))dlsym(opt_handle, "perf_lock_acq");
9427 if (perf_lock_acq == NULL) {
9428 DEBUG_PRINT_ERROR("failed to get lock_acq sym");
9429 }
9430
9431 perf_lock_rel = (int(*)(int))dlsym(opt_handle, "perf_lock_rel");
9432 if (perf_lock_rel == NULL) {
9433 DEBUG_PRINT_ERROR("failed to get lock_rel sym");
9434 }
9435 }
9436 } else {
9437 DEBUG_PRINT_ERROR("Property ro.vendor.extension_library does not exist.");
9438 }
9439 }
9440
9441 int decode_opts[1] = {0x704}; //value of last nibble == # of cores
9442 if (perf_lock_acq && perf_lock_handle < 0) {
9443 DEBUG_PRINT_LOW("Lock acquired");
9444 perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, decode_opts, 1);
9445 }
9446 }
9447}