blob: 799fa3fc0569151cd9d380488a452ae054e61c5e [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>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080052#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070053
54#ifndef _ANDROID_
55#include <sys/ioctl.h>
56#include <sys/mman.h>
57#endif //_ANDROID_
58
59#ifdef _ANDROID_
60#include <cutils/properties.h>
61#undef USE_EGL_IMAGE_GPU
62#endif
63
64#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
65#include <gralloc_priv.h>
66#endif
67
68#if defined (_ANDROID_ICS_)
69#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070070#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070071#endif
72
73#ifdef _ANDROID_
74#include "DivXDrmDecrypt.h"
75#endif //_ANDROID_
76
77#ifdef USE_EGL_IMAGE_GPU
78#include <EGL/egl.h>
79#include <EGL/eglQCOM.h>
80#define EGL_BUFFER_HANDLE_QCOM 0x4F00
81#define EGL_BUFFER_OFFSET_QCOM 0x4F01
82#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -070083#ifdef INPUT_BUFFER_LOG
84#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
85#define INPUT_BUFFER_FILE_NAME_LEN 30
86FILE *inputBufferFile1;
87char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
88#endif
89#ifdef OUTPUT_BUFFER_LOG
90FILE *outputBufferFile1;
91char outputfilename [] = "/data/output.yuv";
Vinay Kalia21649b32013-03-18 17:28:07 -070092
Shalaj Jain273b3e02012-06-22 19:08:03 -070093#endif
94#ifdef OUTPUT_EXTRADATA_LOG
95FILE *outputExtradataFile;
96char ouputextradatafilename [] = "/data/extradata";
97#endif
98
99#define DEFAULT_FPS 30
100#define MAX_INPUT_ERROR DEFAULT_FPS
101#define MAX_SUPPORTED_FPS 120
102
103#define VC1_SP_MP_START_CODE 0xC5000000
104#define VC1_SP_MP_START_CODE_MASK 0xFF000000
105#define VC1_AP_SEQ_START_CODE 0x0F010000
106#define VC1_STRUCT_C_PROFILE_MASK 0xF0
107#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
108#define VC1_SIMPLE_PROFILE 0
109#define VC1_MAIN_PROFILE 1
110#define VC1_ADVANCE_PROFILE 3
111#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
112#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
113#define VC1_STRUCT_C_LEN 4
114#define VC1_STRUCT_C_POS 8
115#define VC1_STRUCT_A_POS 12
116#define VC1_STRUCT_B_POS 24
117#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700118#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119
120#define MEM_DEVICE "/dev/ion"
121#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
122
123#ifdef _ANDROID_
124 extern "C"{
125 #include<utils/Log.h>
126 }
127#endif//_ANDROID_
128
Vinay Kalia53fa6832012-10-11 17:55:30 -0700129#define SZ_4K 0x1000
130#define SZ_1M 0x100000
131
Shalaj Jain273b3e02012-06-22 19:08:03 -0700132#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
133#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 -0700134#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
135
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800136#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700137void* async_message_thread (void *input)
138{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700139 OMX_BUFFERHEADERTYPE *buffer;
140 struct v4l2_plane plane[VIDEO_MAX_PLANES];
141 struct pollfd pfd;
Praneeth Paladugu32284302013-02-14 22:53:06 -0800142 struct v4l2_buffer v4l2_buf;
143 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700144 struct v4l2_event dqevent;
145 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
146 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
147 pfd.fd = omx->drv_ctx.video_driver_fd;
148 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
149 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
150 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
151 while (1)
152 {
153 rc = poll(&pfd, 1, POLL_TIMEOUT);
154 if (!rc) {
155 DEBUG_PRINT_ERROR("Poll timedout\n");
156 break;
157 } else if (rc < 0) {
158 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
159 break;
160 }
161 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
162 struct vdec_msginfo vdec_msg;
163 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
164 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
165 v4l2_buf.length = omx->drv_ctx.num_planes;
166 v4l2_buf.m.planes = plane;
167 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
168 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
169 vdec_msg.status_code=VDEC_S_SUCCESS;
170 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
171 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
172 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
Eric (Quicee1674a2012-12-21 15:29:08 -0800173 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
174 (uint64_t)v4l2_buf.timestamp.tv_usec;
Vinay Kalia592e4b42012-12-19 15:55:47 -0800175 if (vdec_msg.msgdata.output_frame.len) {
176 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
177 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
178 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
179 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
180 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700181 if (omx->async_message_process(input,&vdec_msg) < 0) {
182 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
183 break;
184 }
185 }
186 }
187 if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
188 struct vdec_msginfo vdec_msg;
189 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
190 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
191 v4l2_buf.length = 1;
192 v4l2_buf.m.planes = plane;
193 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
194 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
195 vdec_msg.status_code=VDEC_S_SUCCESS;
196 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
197 if (omx->async_message_process(input,&vdec_msg) < 0) {
198 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
199 break;
200 }
201 }
202 }
203 if (pfd.revents & POLLPRI){
204 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700205 if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700206 struct vdec_msginfo vdec_msg;
207 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
208 vdec_msg.status_code=VDEC_S_SUCCESS;
Vinay Kaliab9e98102013-04-02 19:31:43 -0700209 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700210 if (omx->async_message_process(input,&vdec_msg) < 0) {
211 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
212 break;
213 }
214 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
215 struct vdec_msginfo vdec_msg;
216 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
217 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -0700218 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700219 if (omx->async_message_process(input,&vdec_msg) < 0) {
220 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
221 break;
222 }
223 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
224 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -0700225 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700226 if (omx->async_message_process(input,&vdec_msg) < 0) {
227 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
228 break;
229 }
230 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
231 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
232 break;
233 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
234 struct vdec_msginfo vdec_msg;
235 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
236 vdec_msg.status_code=VDEC_S_SUCCESS;
237 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
238 if (omx->async_message_process(input,&vdec_msg) < 0) {
239 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
240 break;
241 }
242 } else {
243 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
244 continue;
245 }
246 }
247 }
248 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
249 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700250}
251
252void* message_thread(void *input)
253{
254 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
255 unsigned char id;
256 int n;
257
258 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
259 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
260 while (1)
261 {
262
263 n = read(omx->m_pipe_in, &id, 1);
264
265 if(0 == n)
266 {
267 break;
268 }
269
270 if (1 == n)
271 {
272 omx->process_event_cb(omx, id);
273 }
274 if ((n < 0) && (errno != EINTR))
275 {
276 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
277 break;
278 }
279 }
280 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
281 return 0;
282}
283
284void post_message(omx_vdec *omx, unsigned char id)
285{
286 int ret_value;
287 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
288 ret_value = write(omx->m_pipe_out, &id, 1);
289 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
290}
291
292// omx_cmd_queue destructor
293omx_vdec::omx_cmd_queue::~omx_cmd_queue()
294{
295 // Nothing to do
296}
297
298// omx cmd queue constructor
299omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
300{
301 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
302}
303
304// omx cmd queue insert
305bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
306{
307 bool ret = true;
308 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
309 {
310 m_q[m_write].id = id;
311 m_q[m_write].param1 = p1;
312 m_q[m_write].param2 = p2;
313 m_write++;
314 m_size ++;
315 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
316 {
317 m_write = 0;
318 }
319 }
320 else
321 {
322 ret = false;
323 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
324 }
325 return ret;
326}
327
328// omx cmd queue pop
329bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
330{
331 bool ret = true;
332 if (m_size > 0)
333 {
334 *id = m_q[m_read].id;
335 *p1 = m_q[m_read].param1;
336 *p2 = m_q[m_read].param2;
337 // Move the read pointer ahead
338 ++m_read;
339 --m_size;
340 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
341 {
342 m_read = 0;
343 }
344 }
345 else
346 {
347 ret = false;
348 }
349 return ret;
350}
351
352// Retrieve the first mesg type in the queue
353unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
354{
355 return m_q[m_read].id;
356}
357
358#ifdef _ANDROID_
359omx_vdec::ts_arr_list::ts_arr_list()
360{
361 //initialize timestamps array
362 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
363}
364omx_vdec::ts_arr_list::~ts_arr_list()
365{
366 //free m_ts_arr_list?
367}
368
369bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
370{
371 bool ret = true;
372 bool duplicate_ts = false;
373 int idx = 0;
374
375 //insert at the first available empty location
376 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
377 {
378 if (!m_ts_arr_list[idx].valid)
379 {
380 //found invalid or empty entry, save timestamp
381 m_ts_arr_list[idx].valid = true;
382 m_ts_arr_list[idx].timestamp = ts;
383 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
384 ts, idx);
385 break;
386 }
387 }
388
389 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
390 {
391 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
392 ret = false;
393 }
394 return ret;
395}
396
397bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
398{
399 bool ret = true;
400 int min_idx = -1;
401 OMX_TICKS min_ts = 0;
402 int idx = 0;
403
404 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
405 {
406
407 if (m_ts_arr_list[idx].valid)
408 {
409 //found valid entry, save index
410 if (min_idx < 0)
411 {
412 //first valid entry
413 min_ts = m_ts_arr_list[idx].timestamp;
414 min_idx = idx;
415 }
416 else if (m_ts_arr_list[idx].timestamp < min_ts)
417 {
418 min_ts = m_ts_arr_list[idx].timestamp;
419 min_idx = idx;
420 }
421 }
422
423 }
424
425 if (min_idx < 0)
426 {
427 //no valid entries found
428 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
429 ts = 0;
430 ret = false;
431 }
432 else
433 {
434 ts = m_ts_arr_list[min_idx].timestamp;
435 m_ts_arr_list[min_idx].valid = false;
436 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
437 ts, min_idx);
438 }
439
440 return ret;
441
442}
443
444
445bool omx_vdec::ts_arr_list::reset_ts_list()
446{
447 bool ret = true;
448 int idx = 0;
449
450 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
451 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
452 {
453 m_ts_arr_list[idx].valid = false;
454 }
455 return ret;
456}
457#endif
458
459// factory function executed by the core to create instances
460void *get_omx_component_factory_fn(void)
461{
462 return (new omx_vdec);
463}
464
465#ifdef _ANDROID_
466#ifdef USE_ION
467VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
468 struct ion_handle *handle, int ionMapfd)
469{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700470// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471}
472#else
473VideoHeap::VideoHeap(int fd, size_t size, void* base)
474{
475 // dup file descriptor, map once, use pmem
476 init(dup(fd), base, size, 0 , MEM_DEVICE);
477}
478#endif
479#endif // _ANDROID_
480/* ======================================================================
481FUNCTION
482 omx_vdec::omx_vdec
483
484DESCRIPTION
485 Constructor
486
487PARAMETERS
488 None
489
490RETURN VALUE
491 None.
492========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800493omx_vdec::omx_vdec(): m_error_propogated(false),
494 m_state(OMX_StateInvalid),
495 m_app_data(NULL),
496 m_inp_mem_ptr(NULL),
497 m_out_mem_ptr(NULL),
498 m_inp_err_count(0),
499 input_flush_progress (false),
500 output_flush_progress (false),
501 input_use_buffer (false),
502 output_use_buffer (false),
503 ouput_egl_buffers(false),
504 m_use_output_pmem(OMX_FALSE),
505 m_out_mem_region_smi(OMX_FALSE),
506 m_out_pvt_entry_pmem(OMX_FALSE),
507 pending_input_buffers(0),
508 pending_output_buffers(0),
509 m_out_bm_count(0),
510 m_inp_bm_count(0),
511 m_inp_bPopulated(OMX_FALSE),
512 m_out_bPopulated(OMX_FALSE),
513 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700514#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800515 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800517 m_inp_bEnabled(OMX_TRUE),
518 m_out_bEnabled(OMX_TRUE),
519 m_in_alloc_cnt(0),
520 m_platform_list(NULL),
521 m_platform_entry(NULL),
522 m_pmem_info(NULL),
523 arbitrary_bytes (true),
524 psource_frame (NULL),
525 pdest_frame (NULL),
526 m_inp_heap_ptr (NULL),
527 m_phdr_pmem_ptr(NULL),
528 m_heap_inp_bm_count (0),
529 codec_type_parse ((codec_type)0),
530 first_frame_meta (true),
531 frame_count (0),
532 nal_count (0),
533 nal_length(0),
534 look_ahead_nal (false),
535 first_frame(0),
536 first_buffer(NULL),
537 first_frame_size (0),
538 m_device_file_ptr(NULL),
539 m_vc1_profile((vc1_profile_type)0),
540 h264_last_au_ts(LLONG_MAX),
541 h264_last_au_flags(0),
542 prev_ts(LLONG_MAX),
543 rst_prev_ts(true),
544 frm_int(0),
Praneeth Paladugud0881ef2013-04-23 23:02:55 -0700545 m_disp_hor_size(0),
546 m_disp_vert_size(0),
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800547 in_reconfig(false),
548 m_display_id(NULL),
549 h264_parser(NULL),
550 client_extradata(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700551#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800552 m_enable_android_native_buffers(OMX_FALSE),
553 m_use_android_native_buffers(OMX_FALSE),
554 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700555#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800556 m_desc_buffer_ptr(NULL),
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -0700557 secure_mode(false),
558 client_set_fps(false)
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;
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700596 msg_thread_id = 0;
597 async_thread_id = 0;
598 msg_thread_created = false;
599 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700600#ifdef _ANDROID_ICS_
601 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
602#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700603 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700604 drv_ctx.timestamp_adjust = false;
605 drv_ctx.video_driver_fd = -1;
606 m_vendor_config.pData = NULL;
607 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800608 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700609 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800610 streaming[CAPTURE_PORT] =
611 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700612#ifdef _ANDROID_
613 char extradata_value[PROPERTY_VALUE_MAX] = {0};
614 property_get("vidc.dec.debug.extradata", extradata_value, "0");
615 m_debug_extradata = atoi(extradata_value);
616 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
617#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800618 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
619 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700620}
621
Vinay Kalia85793762012-06-14 19:12:34 -0700622static const int event_type[] = {
623 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
624 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
625 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700626 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
627 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700628};
629
630static OMX_ERRORTYPE subscribe_to_events(int fd)
631{
632 OMX_ERRORTYPE eRet = OMX_ErrorNone;
633 struct v4l2_event_subscription sub;
634 int array_sz = sizeof(event_type)/sizeof(int);
635 int i,rc;
636 if (fd < 0) {
637 printf("Invalid input: %d\n", fd);
638 return OMX_ErrorBadParameter;
639 }
640
641 for (i = 0; i < array_sz; ++i) {
642 memset(&sub, 0, sizeof(sub));
643 sub.type = event_type[i];
644 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
645 if (rc) {
646 printf("Failed to subscribe event: 0x%x\n", sub.type);
647 break;
648 }
649 }
650 if (i < array_sz) {
651 for (--i; i >=0 ; i--) {
652 memset(&sub, 0, sizeof(sub));
653 sub.type = event_type[i];
654 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
655 if (rc)
656 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
657 }
658 eRet = OMX_ErrorNotImplemented;
659 }
660 return eRet;
661}
662
663
664static OMX_ERRORTYPE unsubscribe_to_events(int fd)
665{
666 OMX_ERRORTYPE eRet = OMX_ErrorNone;
667 struct v4l2_event_subscription sub;
668 int array_sz = sizeof(event_type)/sizeof(int);
669 int i,rc;
670 if (fd < 0) {
671 printf("Invalid input: %d\n", fd);
672 return OMX_ErrorBadParameter;
673 }
674
675 for (i = 0; i < array_sz; ++i) {
676 memset(&sub, 0, sizeof(sub));
677 sub.type = event_type[i];
678 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
679 if (rc) {
680 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
681 break;
682 }
683 }
684 return eRet;
685}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700686
687/* ======================================================================
688FUNCTION
689 omx_vdec::~omx_vdec
690
691DESCRIPTION
692 Destructor
693
694PARAMETERS
695 None
696
697RETURN VALUE
698 None.
699========================================================================== */
700omx_vdec::~omx_vdec()
701{
702 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700703 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700704 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
705 if(m_pipe_in) close(m_pipe_in);
706 if(m_pipe_out) close(m_pipe_out);
707 m_pipe_in = -1;
708 m_pipe_out = -1;
709 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700710 if (msg_thread_created)
711 pthread_join(msg_thread_id,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700712 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700713 dec.cmd = V4L2_DEC_CMD_STOP;
Vinay Kaliadae8ad62013-04-26 20:42:10 -0700714 if (drv_ctx.video_driver_fd >=0 ) {
715 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
716 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700717 }
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700718 if (async_thread_created)
719 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700720 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700721 close(drv_ctx.video_driver_fd);
722 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800723 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700724 sem_destroy(&m_cmd_lock);
725 if (perf_flag)
726 {
727 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
728 dec_time.end();
729 }
730 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
731}
732
Vinay Kaliafeef7032012-09-25 19:23:33 -0700733int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
734 struct v4l2_requestbuffers bufreq;
735 int rc = 0;
736 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
737 bufreq.memory = V4L2_MEMORY_USERPTR;
738 bufreq.count = 0;
739 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
740 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
741 }
742 return rc;
743}
744
Shalaj Jain273b3e02012-06-22 19:08:03 -0700745/* ======================================================================
746FUNCTION
747 omx_vdec::OMXCntrlProcessMsgCb
748
749DESCRIPTION
750 IL Client callbacks are generated through this routine. The decoder
751 provides the thread context for this routine.
752
753PARAMETERS
754 ctxt -- Context information related to the self.
755 id -- Event identifier. This could be any of the following:
756 1. Command completion event
757 2. Buffer done callback event
758 3. Frame done callback event
759
760RETURN VALUE
761 None.
762
763========================================================================== */
764void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
765{
Shalaj Jain286b0062013-02-21 20:35:48 -0800766 signed p1; // Parameter - 1
767 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700768 unsigned ident;
769 unsigned qsize=0; // qsize
770 omx_vdec *pThis = (omx_vdec *) ctxt;
771
772 if(!pThis)
773 {
774 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
775 __func__);
776 return;
777 }
778
779 // Protect the shared queue data structure
780 do
781 {
782 /*Read the message id's from the queue*/
783 pthread_mutex_lock(&pThis->m_lock);
784 qsize = pThis->m_cmd_q.m_size;
785 if(qsize)
786 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800787 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700788 }
789
790 if (qsize == 0 && pThis->m_state != OMX_StatePause)
791 {
792 qsize = pThis->m_ftb_q.m_size;
793 if (qsize)
794 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800795 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700796 }
797 }
798
799 if (qsize == 0 && pThis->m_state != OMX_StatePause)
800 {
801 qsize = pThis->m_etb_q.m_size;
802 if (qsize)
803 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800804 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700805 }
806 }
807 pthread_mutex_unlock(&pThis->m_lock);
808
809 /*process message if we have one*/
810 if(qsize > 0)
811 {
812 id = ident;
813 switch (id)
814 {
815 case OMX_COMPONENT_GENERATE_EVENT:
816 if (pThis->m_cb.EventHandler)
817 {
818 switch (p1)
819 {
820 case OMX_CommandStateSet:
821 pThis->m_state = (OMX_STATETYPE) p2;
822 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
823 pThis->m_state);
824 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
825 OMX_EventCmdComplete, p1, p2, NULL);
826 break;
827
828 case OMX_EventError:
829 if(p2 == OMX_StateInvalid)
830 {
831 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
832 pThis->m_state = (OMX_STATETYPE) p2;
833 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
834 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
835 }
836 else if (p2 == OMX_ErrorHardware)
837 {
838 pThis->omx_report_error();
839 }
840 else
841 {
842 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800843 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700844 }
845 break;
846
847 case OMX_CommandPortDisable:
848 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
849 if (BITMASK_PRESENT(&pThis->m_flags,
850 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
851 {
852 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
853 break;
854 }
Deva Ramasubramanian37651692013-05-09 20:24:10 -0700855 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700856 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700857 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700858 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700859 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
860 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
861 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700862 pThis->in_reconfig = false;
863 if(eRet != OMX_ErrorNone)
864 {
865 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
866 pThis->omx_report_error();
867 break;
868 }
869 }
870 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
871 OMX_EventCmdComplete, p1, p2, NULL );
872 break;
873 case OMX_CommandPortEnable:
874 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
875 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
876 OMX_EventCmdComplete, p1, p2, NULL );
877 break;
878
879 default:
880 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
881 OMX_EventCmdComplete, p1, p2, NULL );
882 break;
883
884 }
885 }
886 else
887 {
888 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
889 }
890 break;
891 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
892 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
893 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
894 {
895 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
896 pThis->omx_report_error ();
897 }
898 break;
899 case OMX_COMPONENT_GENERATE_ETB:
900 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
901 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
902 {
903 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
904 pThis->omx_report_error ();
905 }
906 break;
907
908 case OMX_COMPONENT_GENERATE_FTB:
909 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
910 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
911 {
912 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
913 pThis->omx_report_error ();
914 }
915 break;
916
917 case OMX_COMPONENT_GENERATE_COMMAND:
918 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
919 (OMX_U32)p2,(OMX_PTR)NULL);
920 break;
921
922 case OMX_COMPONENT_GENERATE_EBD:
923
924 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
925 {
926 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
927 pThis->omx_report_error ();
928 }
929 else
930 {
931 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
932 {
933 pThis->m_inp_err_count++;
934 pThis->time_stamp_dts.remove_time_stamp(
935 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
936 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
937 ?true:false);
938 }
939 else
940 {
941 pThis->m_inp_err_count = 0;
942 }
943 if ( pThis->empty_buffer_done(&pThis->m_cmp,
944 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
945 {
946 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
947 pThis->omx_report_error ();
948 }
949 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
950 {
951 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
952 pThis->omx_report_error ();
953 }
954 }
955 break;
956 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
957 {
958 int64_t *timestamp = (int64_t *)p1;
959 if (p1)
960 {
961 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
962 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
963 ?true:false);
964 free(timestamp);
965 }
966 }
967 break;
968 case OMX_COMPONENT_GENERATE_FBD:
969 if (p2 != VDEC_S_SUCCESS)
970 {
971 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
972 pThis->omx_report_error ();
973 }
974 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
975 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
976 {
977 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
978 pThis->omx_report_error ();
979 }
980 break;
981
982 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
983 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
984 if (!pThis->input_flush_progress)
985 {
986 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
987 }
988 else
989 {
990 pThis->execute_input_flush();
991 if (pThis->m_cb.EventHandler)
992 {
993 if (p2 != VDEC_S_SUCCESS)
994 {
995 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
996 pThis->omx_report_error ();
997 }
998 else
999 {
1000 /*Check if we need generate event for Flush done*/
1001 if(BITMASK_PRESENT(&pThis->m_flags,
1002 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1003 {
1004 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1005 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1006 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1007 OMX_EventCmdComplete,OMX_CommandFlush,
1008 OMX_CORE_INPUT_PORT_INDEX,NULL );
1009 }
1010 if (BITMASK_PRESENT(&pThis->m_flags,
1011 OMX_COMPONENT_IDLE_PENDING))
1012 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001013 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001014 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1015 pThis->omx_report_error ();
1016 } else {
1017 pThis->streaming[OUTPUT_PORT] = false;
1018 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001019 if (!pThis->output_flush_progress)
1020 {
Vinay Kalia22046272012-09-28 20:16:05 -07001021 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001022 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001023 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001024 }
1025 }
1026 }
1027 }
1028 else
1029 {
1030 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1031 }
1032 }
1033 break;
1034
1035 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1036 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1037 if (!pThis->output_flush_progress)
1038 {
1039 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1040 }
1041 else
1042 {
1043 pThis->execute_output_flush();
1044 if (pThis->m_cb.EventHandler)
1045 {
1046 if (p2 != VDEC_S_SUCCESS)
1047 {
1048 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1049 pThis->omx_report_error ();
1050 }
1051 else
1052 {
1053 /*Check if we need generate event for Flush done*/
1054 if(BITMASK_PRESENT(&pThis->m_flags,
1055 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1056 {
1057 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1058 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1059 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1060 OMX_EventCmdComplete,OMX_CommandFlush,
1061 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1062 }
1063 if(BITMASK_PRESENT(&pThis->m_flags,
1064 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1065 {
1066 DEBUG_PRINT_LOW("\n Internal flush complete");
1067 BITMASK_CLEAR (&pThis->m_flags,
1068 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1069 if (BITMASK_PRESENT(&pThis->m_flags,
1070 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1071 {
1072 pThis->post_event(OMX_CommandPortDisable,
1073 OMX_CORE_OUTPUT_PORT_INDEX,
1074 OMX_COMPONENT_GENERATE_EVENT);
1075 BITMASK_CLEAR (&pThis->m_flags,
1076 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1077
1078 }
1079 }
1080
1081 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1082 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001083 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001084 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1085 pThis->omx_report_error ();
1086 break;
1087 }
1088 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001089 if (!pThis->input_flush_progress)
1090 {
Vinay Kalia22046272012-09-28 20:16:05 -07001091 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001092 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001093 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001094 }
1095 }
1096 }
1097 }
1098 else
1099 {
1100 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1101 }
1102 }
1103 break;
1104
1105 case OMX_COMPONENT_GENERATE_START_DONE:
1106 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1107
1108 if (pThis->m_cb.EventHandler)
1109 {
1110 if (p2 != VDEC_S_SUCCESS)
1111 {
1112 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1113 pThis->omx_report_error ();
1114 }
1115 else
1116 {
1117 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1118 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1119 {
1120 DEBUG_PRINT_LOW("\n Move to executing");
1121 // Send the callback now
1122 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1123 pThis->m_state = OMX_StateExecuting;
1124 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1125 OMX_EventCmdComplete,OMX_CommandStateSet,
1126 OMX_StateExecuting, NULL);
1127 }
1128 else if (BITMASK_PRESENT(&pThis->m_flags,
1129 OMX_COMPONENT_PAUSE_PENDING))
1130 {
1131 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1132 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1133 {
1134 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1135 pThis->omx_report_error ();
1136 }
1137 }
1138 }
1139 }
1140 else
1141 {
1142 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1143 }
1144 break;
1145
1146 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1147 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1148 if (pThis->m_cb.EventHandler)
1149 {
1150 if (p2 != VDEC_S_SUCCESS)
1151 {
1152 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1153 pThis->omx_report_error ();
1154 }
1155 else
1156 {
1157 pThis->complete_pending_buffer_done_cbs();
1158 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1159 {
1160 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1161 //Send the callback now
1162 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1163 pThis->m_state = OMX_StatePause;
1164 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1165 OMX_EventCmdComplete,OMX_CommandStateSet,
1166 OMX_StatePause, NULL);
1167 }
1168 }
1169 }
1170 else
1171 {
1172 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1173 }
1174
1175 break;
1176
1177 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1178 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1179 if (pThis->m_cb.EventHandler)
1180 {
1181 if (p2 != VDEC_S_SUCCESS)
1182 {
1183 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1184 pThis->omx_report_error ();
1185 }
1186 else
1187 {
1188 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1189 {
1190 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1191 // Send the callback now
1192 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1193 pThis->m_state = OMX_StateExecuting;
1194 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1195 OMX_EventCmdComplete,OMX_CommandStateSet,
1196 OMX_StateExecuting,NULL);
1197 }
1198 }
1199 }
1200 else
1201 {
1202 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1203 }
1204
1205 break;
1206
1207 case OMX_COMPONENT_GENERATE_STOP_DONE:
1208 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1209 if (pThis->m_cb.EventHandler)
1210 {
1211 if (p2 != VDEC_S_SUCCESS)
1212 {
1213 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1214 pThis->omx_report_error ();
1215 }
1216 else
1217 {
1218 pThis->complete_pending_buffer_done_cbs();
1219 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1220 {
1221 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1222 // Send the callback now
1223 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1224 pThis->m_state = OMX_StateIdle;
1225 DEBUG_PRINT_LOW("\n Move to Idle State");
1226 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1227 OMX_EventCmdComplete,OMX_CommandStateSet,
1228 OMX_StateIdle,NULL);
1229 }
1230 }
1231 }
1232 else
1233 {
1234 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1235 }
1236
1237 break;
1238
1239 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1240 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001241
Vinay Kalia592e4b42012-12-19 15:55:47 -08001242 if (p2 == OMX_IndexParamPortDefinition) {
1243 pThis->in_reconfig = true;
1244 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001245 if (pThis->m_cb.EventHandler) {
1246 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001247 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001248 } else {
1249 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1250 }
1251
1252 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001253 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001254 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1255 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1256 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1257 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1258 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1259 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1260 else //unsupported interlace format; raise a error
1261 event = OMX_EventError;
1262 if (pThis->m_cb.EventHandler) {
1263 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1264 event, format, 0, NULL );
1265 } else {
1266 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001267 }
1268 }
1269 break;
1270
1271 case OMX_COMPONENT_GENERATE_EOS_DONE:
1272 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1273 if (pThis->m_cb.EventHandler) {
1274 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1275 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1276 } else {
1277 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1278 }
1279 pThis->prev_ts = LLONG_MAX;
1280 pThis->rst_prev_ts = true;
1281 break;
1282
1283 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1284 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1285 pThis->omx_report_error ();
1286 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001287
1288 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1289 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1290 pThis->omx_report_unsupported_setting();
1291 break;
1292
Shalaj Jain273b3e02012-06-22 19:08:03 -07001293 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1294 {
1295 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1296 if (pThis->m_cb.EventHandler) {
1297 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1298 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1299 } else {
1300 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1301 }
1302 }
1303 default:
1304 break;
1305 }
1306 }
1307 pthread_mutex_lock(&pThis->m_lock);
1308 qsize = pThis->m_cmd_q.m_size;
1309 if (pThis->m_state != OMX_StatePause)
1310 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1311 pthread_mutex_unlock(&pThis->m_lock);
1312 }
1313 while(qsize>0);
1314
1315}
1316
Vinay Kaliab9e98102013-04-02 19:31:43 -07001317int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001318{
Vinay Kaliab9e98102013-04-02 19:31:43 -07001319 int format_changed = 0;
1320 if ((height != drv_ctx.video_resolution.frame_height) ||
Vinay Kalia0321dc12013-04-08 20:45:54 -07001321 (width != drv_ctx.video_resolution.frame_width)) {
1322 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1323 width, drv_ctx.video_resolution.frame_width,
1324 height,drv_ctx.video_resolution.frame_height);
Vinay Kaliab9e98102013-04-02 19:31:43 -07001325 format_changed = 1;
Vinay Kalia0321dc12013-04-08 20:45:54 -07001326 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001327 drv_ctx.video_resolution.frame_height = height;
1328 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001329 drv_ctx.video_resolution.scan_lines = scan_lines;
1330 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001331 rectangle.nLeft = 0;
1332 rectangle.nTop = 0;
1333 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1334 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Vinay Kaliab9e98102013-04-02 19:31:43 -07001335 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001336}
1337
Arun Menon6836ba02013-02-19 20:37:40 -08001338OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1339{
Arun Menonc10115b2013-04-26 17:56:34 -07001340 if ((drv_ctx.video_resolution.frame_width *
1341 drv_ctx.video_resolution.frame_height >
1342 m_decoder_capability.max_width *
1343 m_decoder_capability.max_height) ||
1344 (drv_ctx.video_resolution.frame_width*
1345 drv_ctx.video_resolution.frame_height <
1346 m_decoder_capability.min_width *
1347 m_decoder_capability.min_height))
1348 {
1349 DEBUG_PRINT_ERROR(
1350 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1351 drv_ctx.video_resolution.frame_width,
1352 drv_ctx.video_resolution.frame_height,
1353 m_decoder_capability.min_width,
1354 m_decoder_capability.min_height,
1355 m_decoder_capability.max_width,
1356 m_decoder_capability.max_height);
Arun Menon6836ba02013-02-19 20:37:40 -08001357 return OMX_ErrorUnsupportedSetting;
1358 }
1359 DEBUG_PRINT_HIGH("\n video session supported\n");
1360 return OMX_ErrorNone;
1361}
1362
Shalaj Jain273b3e02012-06-22 19:08:03 -07001363/* ======================================================================
1364FUNCTION
1365 omx_vdec::ComponentInit
1366
1367DESCRIPTION
1368 Initialize the component.
1369
1370PARAMETERS
1371 ctxt -- Context information related to the self.
1372 id -- Event identifier. This could be any of the following:
1373 1. Command completion event
1374 2. Buffer done callback event
1375 3. Frame done callback event
1376
1377RETURN VALUE
1378 None.
1379
1380========================================================================== */
1381OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1382{
1383
1384 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001385 struct v4l2_fmtdesc fdesc;
1386 struct v4l2_format fmt;
1387 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001388 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001389 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001390 unsigned int alignment = 0,buffer_size = 0;
1391 int fds[2];
1392 int r,ret=0;
1393 bool codec_ambiguous = false;
Sachin Shahc82a18f2013-03-29 14:45:38 -07001394 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
1395
1396#ifdef _ANDROID_
1397 char platform_name[64];
1398 property_get("ro.board.platform", platform_name, "0");
1399 if (!strncmp(platform_name, "msm8610", 7)) {
1400 device_name = (OMX_STRING)"/dev/video/q6_dec";
1401 }
1402#endif
1403
Vinay Kalia53fa6832012-10-11 17:55:30 -07001404 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1405 struct v4l2_control control;
1406 secure_mode = true;
1407 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001408 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001409 }
1410
Sachin Shahc82a18f2013-03-29 14:45:38 -07001411 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001412
1413 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1414 drv_ctx.video_driver_fd, errno);
1415
1416 if(drv_ctx.video_driver_fd == 0){
Vinay Kalia4d17ce32013-05-22 17:10:35 -07001417 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1418 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1419 close(0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001420 }
1421
1422 if(drv_ctx.video_driver_fd < 0)
1423 {
1424 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1425 return OMX_ErrorInsufficientResources;
1426 }
1427 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1428 drv_ctx.frame_rate.fps_denominator = 1;
1429
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001430 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001431 if (!ret) {
1432 async_thread_created = true;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001433 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001434 }
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001435 if(ret) {
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001436 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001437 async_thread_created = false;
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001438 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001440
1441#ifdef INPUT_BUFFER_LOG
1442 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1443#endif
1444#ifdef OUTPUT_BUFFER_LOG
1445 outputBufferFile1 = fopen (outputfilename, "ab");
1446#endif
1447#ifdef OUTPUT_EXTRADATA_LOG
1448 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1449#endif
1450
1451 // Copy the role information which provides the decoder kind
1452 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001453
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1455 OMX_MAX_STRINGNAME_SIZE))
1456 {
1457 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1458 OMX_MAX_STRINGNAME_SIZE);
1459 drv_ctx.timestamp_adjust = true;
1460 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1461 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001462 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001463 /*Initialize Start Code for MPEG4*/
1464 codec_type_parse = CODEC_TYPE_MPEG4;
1465 m_frame_parser.init_start_codes (codec_type_parse);
1466#ifdef INPUT_BUFFER_LOG
1467 strcat(inputfilename, "m4v");
1468#endif
1469 }
1470 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1471 OMX_MAX_STRINGNAME_SIZE))
1472 {
1473 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1474 OMX_MAX_STRINGNAME_SIZE);
1475 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001476 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001477 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1478 /*Initialize Start Code for MPEG2*/
1479 codec_type_parse = CODEC_TYPE_MPEG2;
1480 m_frame_parser.init_start_codes (codec_type_parse);
1481#ifdef INPUT_BUFFER_LOG
1482 strcat(inputfilename, "mpg");
1483#endif
1484 }
1485 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1486 OMX_MAX_STRINGNAME_SIZE))
1487 {
1488 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1489 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1490 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1491 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001492 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001493 codec_type_parse = CODEC_TYPE_H263;
1494 m_frame_parser.init_start_codes (codec_type_parse);
1495#ifdef INPUT_BUFFER_LOG
1496 strcat(inputfilename, "263");
1497#endif
1498 }
1499 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1500 OMX_MAX_STRINGNAME_SIZE))
1501 {
1502 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1503 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1504 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1505 output_capability = V4L2_PIX_FMT_DIVX_311;
1506 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1507 codec_type_parse = CODEC_TYPE_DIVX;
1508 m_frame_parser.init_start_codes (codec_type_parse);
1509
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001510 eRet = createDivxDrmContext();
1511 if (eRet != OMX_ErrorNone) {
1512 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1513 return eRet;
1514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001515 }
1516 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1517 OMX_MAX_STRINGNAME_SIZE))
1518 {
1519 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1520 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1521 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1522 output_capability = V4L2_PIX_FMT_DIVX;
1523 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1524 codec_type_parse = CODEC_TYPE_DIVX;
1525 codec_ambiguous = true;
1526 m_frame_parser.init_start_codes (codec_type_parse);
1527
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001528 eRet = createDivxDrmContext();
1529 if (eRet != OMX_ErrorNone) {
1530 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1531 return eRet;
1532 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001533 }
1534 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1535 OMX_MAX_STRINGNAME_SIZE))
1536 {
1537 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1538 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1539 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1540 output_capability = V4L2_PIX_FMT_DIVX;
1541 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1542 codec_type_parse = CODEC_TYPE_DIVX;
1543 codec_ambiguous = true;
1544 m_frame_parser.init_start_codes (codec_type_parse);
1545
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001546 eRet = createDivxDrmContext();
1547 if (eRet != OMX_ErrorNone) {
1548 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1549 return eRet;
1550 }
1551
Shalaj Jain273b3e02012-06-22 19:08:03 -07001552 }
1553 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1554 OMX_MAX_STRINGNAME_SIZE))
1555 {
1556 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1557 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1558 output_capability=V4L2_PIX_FMT_H264;
1559 eCompressionFormat = OMX_VIDEO_CodingAVC;
1560 codec_type_parse = CODEC_TYPE_H264;
1561 m_frame_parser.init_start_codes (codec_type_parse);
1562 m_frame_parser.init_nal_length(nal_length);
1563#ifdef INPUT_BUFFER_LOG
1564 strcat(inputfilename, "264");
1565#endif
1566 }
1567 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1568 OMX_MAX_STRINGNAME_SIZE))
1569 {
1570 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1571 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1572 eCompressionFormat = OMX_VIDEO_CodingWMV;
1573 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001574 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001575 m_frame_parser.init_start_codes (codec_type_parse);
1576#ifdef INPUT_BUFFER_LOG
1577 strcat(inputfilename, "vc1");
1578#endif
1579 }
1580 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1581 OMX_MAX_STRINGNAME_SIZE))
1582 {
1583 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1584 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1585 eCompressionFormat = OMX_VIDEO_CodingWMV;
1586 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001587 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001588 m_frame_parser.init_start_codes (codec_type_parse);
1589#ifdef INPUT_BUFFER_LOG
1590 strcat(inputfilename, "vc1");
1591#endif
1592 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001593 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1594 OMX_MAX_STRINGNAME_SIZE))
1595 {
1596 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1597 output_capability=V4L2_PIX_FMT_VP8;
1598 eCompressionFormat = OMX_VIDEO_CodingVPX;
1599 codec_type_parse = CODEC_TYPE_VP8;
1600 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001601#ifdef INPUT_BUFFER_LOG
1602 strcat(inputfilename, "ivf");
1603#endif
1604
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001605 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001606 else
1607 {
1608 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1609 eRet = OMX_ErrorInvalidComponentName;
1610 }
1611#ifdef INPUT_BUFFER_LOG
1612 inputBufferFile1 = fopen (inputfilename, "ab");
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001613 if (output_capability == V4L2_PIX_FMT_VP8) {
1614 struct ivf_file_header
1615 {
1616 OMX_U8 signature[4]; //='DKIF';
1617 OMX_U8 version ; //= 0;
1618 OMX_U8 headersize ; //= 32;
1619 OMX_U32 FourCC;
1620 OMX_U8 width;
1621 OMX_U8 height;
1622 OMX_U32 rate;
1623 OMX_U32 scale;
1624 OMX_U32 length;
1625 OMX_U8 unused[4];
1626 } file_header;
1627 memset((void *)&file_header,0,sizeof(file_header));
1628 file_header.signature[0] = 'D';
1629 file_header.signature[1] = 'K';
1630 file_header.signature[2] = 'I';
1631 file_header.signature[3] = 'F';
1632 file_header.version = 0;
1633 file_header.headersize = 32;
1634 file_header.FourCC = 0x30385056;
1635 if (inputBufferFile1)
1636 {
1637 fwrite((const char *)&file_header,
1638 sizeof(file_header),1,inputBufferFile1);
1639 }
1640 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001641#endif
1642 if (eRet == OMX_ErrorNone)
1643 {
1644
Vinay Kaliada4f4422013-01-09 10:45:03 -08001645 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1646 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1647 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1648 if (!client_buffers.set_color_format(dest_color_format)) {
1649 DEBUG_PRINT_ERROR("\n Setting color format failed");
1650 eRet = OMX_ErrorInsufficientResources;
1651 }
1652
Shalaj Jain273b3e02012-06-22 19:08:03 -07001653 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001654
1655 struct v4l2_capability cap;
1656 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1657 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001658 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jainaa459962013-05-23 19:12:00 -07001659 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001660 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001661 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001662 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1663 cap.bus_info, cap.version, cap.capabilities);
1664 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001665 ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001666 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1667 fdesc.index=0;
1668 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001669 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001670 fdesc.pixelformat, fdesc.flags);
1671 fdesc.index++;
1672 }
1673 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1674 fdesc.index=0;
1675 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1676
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001677 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001678 fdesc.pixelformat, fdesc.flags);
1679 fdesc.index++;
1680 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001681 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001682 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1683 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1684 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1685 fmt.fmt.pix_mp.pixelformat = output_capability;
1686 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1687 if (ret) {
1688 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001689 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Praneeth Paladugub227af72013-05-08 01:33:06 -07001690 return OMX_ErrorInsufficientResources;
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001691 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001692 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693 if (codec_ambiguous) {
1694 if (output_capability == V4L2_PIX_FMT_DIVX) {
1695 struct v4l2_control divx_ctrl;
1696
1697 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001698 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001699 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001700 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001701 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001702 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001703 }
1704
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001705 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001706 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001707 if (ret) {
1708 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1709 }
1710 } else {
1711 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1712 }
1713 }
1714
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001715 //Get the hardware capabilities
1716 memset((void *)&frmsize,0,sizeof(frmsize));
1717 frmsize.index = 0;
1718 frmsize.pixel_format = output_capability;
1719 ret = ioctl(drv_ctx.video_driver_fd,
1720 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1721 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1722 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1723 return OMX_ErrorHardware;
1724 }
1725
1726 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1727 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1728 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1729 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1730 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1731 }
1732
Shalaj Jain273b3e02012-06-22 19:08:03 -07001733 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1734 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1735 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001736 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001737 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1738 if (ret) {
1739 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001740 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001741 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001742 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001743 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001744 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1745 control.value = 1;
1746 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1747 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1748 if (ret) {
1749 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001750 return OMX_ErrorInsufficientResources;
1751 }
1752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001753
1754 /*Get the Buffer requirements for input and output ports*/
1755 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1756 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001757 if (secure_mode) {
1758 drv_ctx.op_buf.alignment=SZ_1M;
1759 drv_ctx.ip_buf.alignment=SZ_1M;
1760 } else {
1761 drv_ctx.op_buf.alignment=SZ_4K;
1762 drv_ctx.ip_buf.alignment=SZ_4K;
1763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1765 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001766 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1768 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1769 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001770 drv_ctx.idr_only_decoding = 0;
1771
Vinay Kalia5713bb32013-01-16 18:39:59 -08001772 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001773#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001774 if (eRet == OMX_ErrorNone && !secure_mode)
1775 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001776#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001777 eRet=get_buffer_req(&drv_ctx.ip_buf);
1778 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1779 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001780 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1781 {
1782 if (m_frame_parser.mutils == NULL)
1783 {
1784 m_frame_parser.mutils = new H264_Utils();
1785
1786 if (m_frame_parser.mutils == NULL)
1787 {
1788 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1789 eRet = OMX_ErrorInsufficientResources;
1790 }
1791 else
1792 {
1793 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1794 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1795 h264_scratch.nFilledLen = 0;
1796 h264_scratch.nOffset = 0;
1797
1798 if (h264_scratch.pBuffer == NULL)
1799 {
1800 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1801 return OMX_ErrorInsufficientResources;
1802 }
1803 m_frame_parser.mutils->initialize_frame_checking_environment();
1804 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1805 }
1806 }
1807
1808 h264_parser = new h264_stream_parser();
1809 if (!h264_parser)
1810 {
1811 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1812 eRet = OMX_ErrorInsufficientResources;
1813 }
1814 }
1815
1816 if(pipe(fds))
1817 {
1818 DEBUG_PRINT_ERROR("pipe creation failed\n");
1819 eRet = OMX_ErrorInsufficientResources;
1820 }
1821 else
1822 {
1823 int temp1[2];
1824 if(fds[0] == 0 || fds[1] == 0)
1825 {
1826 if (pipe (temp1))
1827 {
1828 DEBUG_PRINT_ERROR("pipe creation failed\n");
1829 return OMX_ErrorInsufficientResources;
1830 }
1831 //close (fds[0]);
1832 //close (fds[1]);
1833 fds[0] = temp1 [0];
1834 fds[1] = temp1 [1];
1835 }
1836 m_pipe_in = fds[0];
1837 m_pipe_out = fds[1];
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001838 msg_thread_created = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001839 r = pthread_create(&msg_thread_id,0,message_thread,this);
1840
1841 if(r < 0)
1842 {
1843 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001844 msg_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001845 eRet = OMX_ErrorInsufficientResources;
1846 }
1847 }
1848 }
1849
1850 if (eRet != OMX_ErrorNone)
1851 {
1852 DEBUG_PRINT_ERROR("\n Component Init Failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001853 }
1854 else
1855 {
1856 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1857 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001858 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1859 return eRet;
1860}
1861
1862/* ======================================================================
1863FUNCTION
1864 omx_vdec::GetComponentVersion
1865
1866DESCRIPTION
1867 Returns the component version.
1868
1869PARAMETERS
1870 TBD.
1871
1872RETURN VALUE
1873 OMX_ErrorNone.
1874
1875========================================================================== */
1876OMX_ERRORTYPE omx_vdec::get_component_version
1877 (
1878 OMX_IN OMX_HANDLETYPE hComp,
1879 OMX_OUT OMX_STRING componentName,
1880 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1881 OMX_OUT OMX_VERSIONTYPE* specVersion,
1882 OMX_OUT OMX_UUIDTYPE* componentUUID
1883 )
1884{
1885 if(m_state == OMX_StateInvalid)
1886 {
1887 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1888 return OMX_ErrorInvalidState;
1889 }
1890 /* TBD -- Return the proper version */
1891 if (specVersion)
1892 {
1893 specVersion->nVersion = OMX_SPEC_VERSION;
1894 }
1895 return OMX_ErrorNone;
1896}
1897/* ======================================================================
1898FUNCTION
1899 omx_vdec::SendCommand
1900
1901DESCRIPTION
1902 Returns zero if all the buffers released..
1903
1904PARAMETERS
1905 None.
1906
1907RETURN VALUE
1908 true/false
1909
1910========================================================================== */
1911OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1912 OMX_IN OMX_COMMANDTYPE cmd,
1913 OMX_IN OMX_U32 param1,
1914 OMX_IN OMX_PTR cmdData
1915 )
1916{
1917 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1918 if(m_state == OMX_StateInvalid)
1919 {
1920 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1921 return OMX_ErrorInvalidState;
1922 }
1923 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1924 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1925 {
1926 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001927 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001928 return OMX_ErrorBadPortIndex;
1929 }
1930 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1931 sem_wait(&m_cmd_lock);
1932 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1933 return OMX_ErrorNone;
1934}
1935
1936/* ======================================================================
1937FUNCTION
1938 omx_vdec::SendCommand
1939
1940DESCRIPTION
1941 Returns zero if all the buffers released..
1942
1943PARAMETERS
1944 None.
1945
1946RETURN VALUE
1947 true/false
1948
1949========================================================================== */
1950OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1951 OMX_IN OMX_COMMANDTYPE cmd,
1952 OMX_IN OMX_U32 param1,
1953 OMX_IN OMX_PTR cmdData
1954 )
1955{
1956 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1957 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1958 int bFlag = 1,sem_posted = 0,ret=0;
1959
1960 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1961 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1962 m_state, eState);
1963
1964 if(cmd == OMX_CommandStateSet)
1965 {
1966 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1967 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1968 /***************************/
1969 /* Current State is Loaded */
1970 /***************************/
1971 if(m_state == OMX_StateLoaded)
1972 {
1973 if(eState == OMX_StateIdle)
1974 {
1975 //if all buffers are allocated or all ports disabled
1976 if(allocate_done() ||
1977 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1978 {
1979 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1980 }
1981 else
1982 {
1983 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1984 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1985 // Skip the event notification
1986 bFlag = 0;
1987 }
1988 }
1989 /* Requesting transition from Loaded to Loaded */
1990 else if(eState == OMX_StateLoaded)
1991 {
1992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1993 post_event(OMX_EventError,OMX_ErrorSameState,\
1994 OMX_COMPONENT_GENERATE_EVENT);
1995 eRet = OMX_ErrorSameState;
1996 }
1997 /* Requesting transition from Loaded to WaitForResources */
1998 else if(eState == OMX_StateWaitForResources)
1999 {
2000 /* Since error is None , we will post an event
2001 at the end of this function definition */
2002 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
2003 }
2004 /* Requesting transition from Loaded to Executing */
2005 else if(eState == OMX_StateExecuting)
2006 {
2007 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
2008 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2009 OMX_COMPONENT_GENERATE_EVENT);
2010 eRet = OMX_ErrorIncorrectStateTransition;
2011 }
2012 /* Requesting transition from Loaded to Pause */
2013 else if(eState == OMX_StatePause)
2014 {
2015 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
2016 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2017 OMX_COMPONENT_GENERATE_EVENT);
2018 eRet = OMX_ErrorIncorrectStateTransition;
2019 }
2020 /* Requesting transition from Loaded to Invalid */
2021 else if(eState == OMX_StateInvalid)
2022 {
2023 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
2024 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2025 eRet = OMX_ErrorInvalidState;
2026 }
2027 else
2028 {
2029 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
2030 eState);
2031 eRet = OMX_ErrorBadParameter;
2032 }
2033 }
2034
2035 /***************************/
2036 /* Current State is IDLE */
2037 /***************************/
2038 else if(m_state == OMX_StateIdle)
2039 {
2040 if(eState == OMX_StateLoaded)
2041 {
2042 if(release_done())
2043 {
2044 /*
2045 Since error is None , we will post an event at the end
2046 of this function definition
2047 */
2048 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2049 }
2050 else
2051 {
2052 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2053 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2054 // Skip the event notification
2055 bFlag = 0;
2056 }
2057 }
2058 /* Requesting transition from Idle to Executing */
2059 else if(eState == OMX_StateExecuting)
2060 {
2061 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2062 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2063 bFlag = 1;
2064 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2065 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002066 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002067 }
2068 /* Requesting transition from Idle to Idle */
2069 else if(eState == OMX_StateIdle)
2070 {
2071 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2072 post_event(OMX_EventError,OMX_ErrorSameState,\
2073 OMX_COMPONENT_GENERATE_EVENT);
2074 eRet = OMX_ErrorSameState;
2075 }
2076 /* Requesting transition from Idle to WaitForResources */
2077 else if(eState == OMX_StateWaitForResources)
2078 {
2079 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2080 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2081 OMX_COMPONENT_GENERATE_EVENT);
2082 eRet = OMX_ErrorIncorrectStateTransition;
2083 }
2084 /* Requesting transition from Idle to Pause */
2085 else if(eState == OMX_StatePause)
2086 {
2087 /*To pause the Video core we need to start the driver*/
2088 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2089 NULL) < */0)
2090 {
2091 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2092 omx_report_error ();
2093 eRet = OMX_ErrorHardware;
2094 }
2095 else
2096 {
2097 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2098 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2099 bFlag = 0;
2100 }
2101 }
2102 /* Requesting transition from Idle to Invalid */
2103 else if(eState == OMX_StateInvalid)
2104 {
2105 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2106 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2107 eRet = OMX_ErrorInvalidState;
2108 }
2109 else
2110 {
2111 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2112 eRet = OMX_ErrorBadParameter;
2113 }
2114 }
2115
2116 /******************************/
2117 /* Current State is Executing */
2118 /******************************/
2119 else if(m_state == OMX_StateExecuting)
2120 {
2121 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2122 /* Requesting transition from Executing to Idle */
2123 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002124 {
2125 /* Since error is None , we will post an event
2126 at the end of this function definition
2127 */
2128 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002129 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002130 if(!sem_posted)
2131 {
2132 sem_posted = 1;
2133 sem_post (&m_cmd_lock);
2134 execute_omx_flush(OMX_ALL);
2135 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002136 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002137 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002138 /* Requesting transition from Executing to Paused */
2139 else if(eState == OMX_StatePause)
2140 {
2141 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002142 m_state = OMX_StatePause;
2143 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002144 }
2145 /* Requesting transition from Executing to Loaded */
2146 else if(eState == OMX_StateLoaded)
2147 {
2148 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2149 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2150 OMX_COMPONENT_GENERATE_EVENT);
2151 eRet = OMX_ErrorIncorrectStateTransition;
2152 }
2153 /* Requesting transition from Executing to WaitForResources */
2154 else if(eState == OMX_StateWaitForResources)
2155 {
2156 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2157 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2158 OMX_COMPONENT_GENERATE_EVENT);
2159 eRet = OMX_ErrorIncorrectStateTransition;
2160 }
2161 /* Requesting transition from Executing to Executing */
2162 else if(eState == OMX_StateExecuting)
2163 {
2164 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2165 post_event(OMX_EventError,OMX_ErrorSameState,\
2166 OMX_COMPONENT_GENERATE_EVENT);
2167 eRet = OMX_ErrorSameState;
2168 }
2169 /* Requesting transition from Executing to Invalid */
2170 else if(eState == OMX_StateInvalid)
2171 {
2172 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2173 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorInvalidState;
2175 }
2176 else
2177 {
2178 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2179 eRet = OMX_ErrorBadParameter;
2180 }
2181 }
2182 /***************************/
2183 /* Current State is Pause */
2184 /***************************/
2185 else if(m_state == OMX_StatePause)
2186 {
2187 /* Requesting transition from Pause to Executing */
2188 if(eState == OMX_StateExecuting)
2189 {
2190 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002191 m_state = OMX_StateExecuting;
2192 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002193 }
2194 /* Requesting transition from Pause to Idle */
2195 else if(eState == OMX_StateIdle)
2196 {
2197 /* Since error is None , we will post an event
2198 at the end of this function definition */
2199 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2200 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2201 if(!sem_posted)
2202 {
2203 sem_posted = 1;
2204 sem_post (&m_cmd_lock);
2205 execute_omx_flush(OMX_ALL);
2206 }
2207 bFlag = 0;
2208 }
2209 /* Requesting transition from Pause to loaded */
2210 else if(eState == OMX_StateLoaded)
2211 {
2212 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2213 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2214 OMX_COMPONENT_GENERATE_EVENT);
2215 eRet = OMX_ErrorIncorrectStateTransition;
2216 }
2217 /* Requesting transition from Pause to WaitForResources */
2218 else if(eState == OMX_StateWaitForResources)
2219 {
2220 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2221 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2222 OMX_COMPONENT_GENERATE_EVENT);
2223 eRet = OMX_ErrorIncorrectStateTransition;
2224 }
2225 /* Requesting transition from Pause to Pause */
2226 else if(eState == OMX_StatePause)
2227 {
2228 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2229 post_event(OMX_EventError,OMX_ErrorSameState,\
2230 OMX_COMPONENT_GENERATE_EVENT);
2231 eRet = OMX_ErrorSameState;
2232 }
2233 /* Requesting transition from Pause to Invalid */
2234 else if(eState == OMX_StateInvalid)
2235 {
2236 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2237 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2238 eRet = OMX_ErrorInvalidState;
2239 }
2240 else
2241 {
2242 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2243 eRet = OMX_ErrorBadParameter;
2244 }
2245 }
2246 /***************************/
2247 /* Current State is WaitForResources */
2248 /***************************/
2249 else if(m_state == OMX_StateWaitForResources)
2250 {
2251 /* Requesting transition from WaitForResources to Loaded */
2252 if(eState == OMX_StateLoaded)
2253 {
2254 /* Since error is None , we will post an event
2255 at the end of this function definition */
2256 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2257 }
2258 /* Requesting transition from WaitForResources to WaitForResources */
2259 else if (eState == OMX_StateWaitForResources)
2260 {
2261 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2262 post_event(OMX_EventError,OMX_ErrorSameState,
2263 OMX_COMPONENT_GENERATE_EVENT);
2264 eRet = OMX_ErrorSameState;
2265 }
2266 /* Requesting transition from WaitForResources to Executing */
2267 else if(eState == OMX_StateExecuting)
2268 {
2269 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2270 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2271 OMX_COMPONENT_GENERATE_EVENT);
2272 eRet = OMX_ErrorIncorrectStateTransition;
2273 }
2274 /* Requesting transition from WaitForResources to Pause */
2275 else if(eState == OMX_StatePause)
2276 {
2277 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2278 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2279 OMX_COMPONENT_GENERATE_EVENT);
2280 eRet = OMX_ErrorIncorrectStateTransition;
2281 }
2282 /* Requesting transition from WaitForResources to Invalid */
2283 else if(eState == OMX_StateInvalid)
2284 {
2285 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2286 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2287 eRet = OMX_ErrorInvalidState;
2288 }
2289 /* Requesting transition from WaitForResources to Loaded -
2290 is NOT tested by Khronos TS */
2291
2292 }
2293 else
2294 {
2295 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2296 eRet = OMX_ErrorBadParameter;
2297 }
2298 }
2299 /********************************/
2300 /* Current State is Invalid */
2301 /*******************************/
2302 else if(m_state == OMX_StateInvalid)
2303 {
2304 /* State Transition from Inavlid to any state */
2305 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2306 || OMX_StateIdle || OMX_StateExecuting
2307 || OMX_StatePause || OMX_StateInvalid))
2308 {
2309 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2310 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2311 OMX_COMPONENT_GENERATE_EVENT);
2312 eRet = OMX_ErrorInvalidState;
2313 }
2314 }
2315 else if (cmd == OMX_CommandFlush)
2316 {
2317 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002318 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002319 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2320 {
2321 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2322 }
2323 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2324 {
2325 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2326 }
2327 if (!sem_posted){
2328 sem_posted = 1;
2329 DEBUG_PRINT_LOW("\n Set the Semaphore");
2330 sem_post (&m_cmd_lock);
2331 execute_omx_flush(param1);
2332 }
2333 bFlag = 0;
2334 }
2335 else if ( cmd == OMX_CommandPortEnable)
2336 {
2337 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002338 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002339 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2340 {
2341 m_inp_bEnabled = OMX_TRUE;
2342
2343 if( (m_state == OMX_StateLoaded &&
2344 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2345 || allocate_input_done())
2346 {
2347 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2348 OMX_COMPONENT_GENERATE_EVENT);
2349 }
2350 else
2351 {
2352 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2353 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2354 // Skip the event notification
2355 bFlag = 0;
2356 }
2357 }
2358 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2359 {
2360 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2361 m_out_bEnabled = OMX_TRUE;
2362
2363 if( (m_state == OMX_StateLoaded &&
2364 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2365 || (allocate_output_done()))
2366 {
2367 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2368 OMX_COMPONENT_GENERATE_EVENT);
2369
2370 }
2371 else
2372 {
2373 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2374 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2375 // Skip the event notification
2376 bFlag = 0;
2377 }
2378 }
2379 }
2380 else if (cmd == OMX_CommandPortDisable)
2381 {
2382 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002383 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002384 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2385 {
2386 m_inp_bEnabled = OMX_FALSE;
2387 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2388 && release_input_done())
2389 {
2390 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2391 OMX_COMPONENT_GENERATE_EVENT);
2392 }
2393 else
2394 {
2395 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2396 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2397 {
2398 if(!sem_posted)
2399 {
2400 sem_posted = 1;
2401 sem_post (&m_cmd_lock);
2402 }
2403 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2404 }
2405
2406 // Skip the event notification
2407 bFlag = 0;
2408 }
2409 }
2410 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2411 {
2412 m_out_bEnabled = OMX_FALSE;
2413 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2414 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2415 && release_output_done())
2416 {
2417 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2418 OMX_COMPONENT_GENERATE_EVENT);
2419 }
2420 else
2421 {
2422 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2423 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2424 {
2425 if (!sem_posted)
2426 {
2427 sem_posted = 1;
2428 sem_post (&m_cmd_lock);
2429 }
2430 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2431 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2432 }
2433 // Skip the event notification
2434 bFlag = 0;
2435
2436 }
2437 }
2438 }
2439 else
2440 {
2441 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2442 eRet = OMX_ErrorNotImplemented;
2443 }
2444 if(eRet == OMX_ErrorNone && bFlag)
2445 {
2446 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2447 }
2448 if(!sem_posted)
2449 {
2450 sem_post(&m_cmd_lock);
2451 }
2452
2453 return eRet;
2454}
2455
2456/* ======================================================================
2457FUNCTION
2458 omx_vdec::ExecuteOmxFlush
2459
2460DESCRIPTION
2461 Executes the OMX flush.
2462
2463PARAMETERS
2464 flushtype - input flush(1)/output flush(0)/ both.
2465
2466RETURN VALUE
2467 true/false
2468
2469========================================================================== */
2470bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2471{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002472 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002473 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002474 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002475 struct v4l2_decoder_cmd dec;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002476 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002477 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002478 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002479
2480 DEBUG_PRINT_ERROR("in %s: reconfig? %d", __func__, in_reconfig);
2481
2482 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483 {
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002484 output_flush_progress = true;
2485 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2486 }
2487 else
2488 {
2489 /* XXX: The driver/hardware does not support flushing of individual ports
2490 * in all states. So we pretty much need to flush both ports internally,
2491 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2492 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2493 * we automatically omit sending the FLUSH done for the "opposite" port. */
2494 input_flush_progress = true;
2495 output_flush_progress = true;
2496 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002497 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002498
2499 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002500 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002501 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002502 bRet = false;
2503 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002504
Shalaj Jain273b3e02012-06-22 19:08:03 -07002505 return bRet;
2506}
2507/*=========================================================================
2508FUNCTION : execute_output_flush
2509
2510DESCRIPTION
2511 Executes the OMX flush at OUTPUT PORT.
2512
2513PARAMETERS
2514 None.
2515
2516RETURN VALUE
2517 true/false
2518==========================================================================*/
2519bool omx_vdec::execute_output_flush()
2520{
2521 unsigned p1 = 0; // Parameter - 1
2522 unsigned p2 = 0; // Parameter - 2
2523 unsigned ident = 0;
2524 bool bRet = true;
2525
2526 /*Generate FBD for all Buffers in the FTBq*/
2527 pthread_mutex_lock(&m_lock);
2528 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2529 while (m_ftb_q.m_size)
2530 {
2531 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2532 m_ftb_q.m_size,pending_output_buffers);
2533 m_ftb_q.pop_entry(&p1,&p2,&ident);
2534 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002535 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002536 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002537 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002538 }
2539 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2540 {
2541 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2542 }
2543 }
2544 pthread_mutex_unlock(&m_lock);
2545 output_flush_progress = false;
2546
2547 if (arbitrary_bytes)
2548 {
2549 prev_ts = LLONG_MAX;
2550 rst_prev_ts = true;
2551 }
2552 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2553 return bRet;
2554}
2555/*=========================================================================
2556FUNCTION : execute_input_flush
2557
2558DESCRIPTION
2559 Executes the OMX flush at INPUT PORT.
2560
2561PARAMETERS
2562 None.
2563
2564RETURN VALUE
2565 true/false
2566==========================================================================*/
2567bool omx_vdec::execute_input_flush()
2568{
2569 unsigned i =0;
2570 unsigned p1 = 0; // Parameter - 1
2571 unsigned p2 = 0; // Parameter - 2
2572 unsigned ident = 0;
2573 bool bRet = true;
2574
2575 /*Generate EBD for all Buffers in the ETBq*/
2576 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2577
2578 pthread_mutex_lock(&m_lock);
2579 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2580 while (m_etb_q.m_size)
2581 {
2582 m_etb_q.pop_entry(&p1,&p2,&ident);
2583
2584 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2585 {
2586 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2587 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2588 }
2589 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2590 {
2591 pending_input_buffers++;
2592 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2593 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2594 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2595 }
2596 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2597 {
2598 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2599 (OMX_BUFFERHEADERTYPE *)p1);
2600 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2601 }
2602 }
2603 time_stamp_dts.flush_timestamp();
2604 /*Check if Heap Buffers are to be flushed*/
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07002605 if (arbitrary_bytes && !(codec_config_flag))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002606 {
2607 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2608 h264_scratch.nFilledLen = 0;
2609 nal_count = 0;
2610 look_ahead_nal = false;
2611 frame_count = 0;
2612 h264_last_au_ts = LLONG_MAX;
2613 h264_last_au_flags = 0;
2614 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2615 m_demux_entries = 0;
2616 DEBUG_PRINT_LOW("\n Initialize parser");
2617 if (m_frame_parser.mutils)
2618 {
2619 m_frame_parser.mutils->initialize_frame_checking_environment();
2620 }
2621
2622 while (m_input_pending_q.m_size)
2623 {
2624 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2625 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2626 }
2627
2628 if (psource_frame)
2629 {
2630 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2631 psource_frame = NULL;
2632 }
2633
2634 if (pdest_frame)
2635 {
2636 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002637 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2638 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002639 pdest_frame = NULL;
2640 }
2641 m_frame_parser.flush();
2642 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07002643 else if (codec_config_flag)
2644 {
2645 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2646 "is not sent to the driver yet");
2647 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002648 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 Kalia586d0242013-04-29 11:39:00 -07002717 OMX_ERRORTYPE eRet = OMX_ErrorNone;
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 }
Eric (Quic613bc1f2012-12-18 11:02:07 -08002800 else
2801 {
2802 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2803 eRet = OMX_ErrorNoMore;
2804 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002805 }
2806 else
2807 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002808 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 -07002809 eRet = OMX_ErrorBadPortIndex;
2810 }
2811 return eRet;
2812}
2813
2814/* ======================================================================
2815FUNCTION
2816 omx_vdec::GetParameter
2817
2818DESCRIPTION
2819 OMX Get Parameter method implementation
2820
2821PARAMETERS
2822 <TBD>.
2823
2824RETURN VALUE
2825 Error None if successful.
2826
2827========================================================================== */
2828OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2829 OMX_IN OMX_INDEXTYPE paramIndex,
2830 OMX_INOUT OMX_PTR paramData)
2831{
2832 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2833
2834 DEBUG_PRINT_LOW("get_parameter: \n");
2835 if(m_state == OMX_StateInvalid)
2836 {
2837 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2838 return OMX_ErrorInvalidState;
2839 }
2840 if(paramData == NULL)
2841 {
2842 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2843 return OMX_ErrorBadParameter;
2844 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002845 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002846 {
2847 case OMX_IndexParamPortDefinition:
2848 {
2849 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2850 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2851 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2852 eRet = update_portdef(portDefn);
2853 if (eRet == OMX_ErrorNone)
2854 m_port_def = *portDefn;
2855 break;
2856 }
2857 case OMX_IndexParamVideoInit:
2858 {
2859 OMX_PORT_PARAM_TYPE *portParamType =
2860 (OMX_PORT_PARAM_TYPE *) paramData;
2861 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2862
2863 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2864 portParamType->nSize = sizeof(portParamType);
2865 portParamType->nPorts = 2;
2866 portParamType->nStartPortNumber = 0;
2867 break;
2868 }
2869 case OMX_IndexParamVideoPortFormat:
2870 {
2871 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2872 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2873 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2874
2875 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2876 portFmt->nSize = sizeof(portFmt);
2877
2878 if (0 == portFmt->nPortIndex)
2879 {
2880 if (0 == portFmt->nIndex)
2881 {
2882 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2883 portFmt->eCompressionFormat = eCompressionFormat;
2884 }
2885 else
2886 {
2887 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2888 " NoMore compression formats\n");
2889 eRet = OMX_ErrorNoMore;
2890 }
2891 }
2892 else if (1 == portFmt->nPortIndex)
2893 {
2894 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2895
2896 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002897 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2898 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2899 else if (1 == portFmt->nIndex)
2900 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002901 else
2902 {
2903 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2904 " NoMore Color formats\n");
2905 eRet = OMX_ErrorNoMore;
2906 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002907 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002908 }
2909 else
2910 {
2911 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2912 (int)portFmt->nPortIndex);
2913 eRet = OMX_ErrorBadPortIndex;
2914 }
2915 break;
2916 }
2917 /*Component should support this port definition*/
2918 case OMX_IndexParamAudioInit:
2919 {
2920 OMX_PORT_PARAM_TYPE *audioPortParamType =
2921 (OMX_PORT_PARAM_TYPE *) paramData;
2922 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2923 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2924 audioPortParamType->nSize = sizeof(audioPortParamType);
2925 audioPortParamType->nPorts = 0;
2926 audioPortParamType->nStartPortNumber = 0;
2927 break;
2928 }
2929 /*Component should support this port definition*/
2930 case OMX_IndexParamImageInit:
2931 {
2932 OMX_PORT_PARAM_TYPE *imagePortParamType =
2933 (OMX_PORT_PARAM_TYPE *) paramData;
2934 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2935 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2936 imagePortParamType->nSize = sizeof(imagePortParamType);
2937 imagePortParamType->nPorts = 0;
2938 imagePortParamType->nStartPortNumber = 0;
2939 break;
2940
2941 }
2942 /*Component should support this port definition*/
2943 case OMX_IndexParamOtherInit:
2944 {
2945 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2946 paramIndex);
2947 eRet =OMX_ErrorUnsupportedIndex;
2948 break;
2949 }
2950 case OMX_IndexParamStandardComponentRole:
2951 {
2952 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2953 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2954 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2955 comp_role->nSize = sizeof(*comp_role);
2956
2957 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2958 paramIndex);
2959 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2960 OMX_MAX_STRINGNAME_SIZE);
2961 break;
2962 }
2963 /* Added for parameter test */
2964 case OMX_IndexParamPriorityMgmt:
2965 {
2966
2967 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2968 (OMX_PRIORITYMGMTTYPE *) paramData;
2969 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2970 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2971 priorityMgmType->nSize = sizeof(priorityMgmType);
2972
2973 break;
2974 }
2975 /* Added for parameter test */
2976 case OMX_IndexParamCompBufferSupplier:
2977 {
2978 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2979 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2980 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2981
2982 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2983 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2984 if(0 == bufferSupplierType->nPortIndex)
2985 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2986 else if (1 == bufferSupplierType->nPortIndex)
2987 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2988 else
2989 eRet = OMX_ErrorBadPortIndex;
2990
2991
2992 break;
2993 }
2994 case OMX_IndexParamVideoAvc:
2995 {
2996 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2997 paramIndex);
2998 break;
2999 }
3000 case OMX_IndexParamVideoH263:
3001 {
3002 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
3003 paramIndex);
3004 break;
3005 }
3006 case OMX_IndexParamVideoMpeg4:
3007 {
3008 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
3009 paramIndex);
3010 break;
3011 }
3012 case OMX_IndexParamVideoMpeg2:
3013 {
3014 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
3015 paramIndex);
3016 break;
3017 }
3018 case OMX_IndexParamVideoProfileLevelQuerySupported:
3019 {
3020 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
3021 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3022 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3023 eRet = get_supported_profile_level_for_1080p(profileLevelType);
3024 break;
3025 }
3026#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3027 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
3028 {
3029 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
3030 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3031 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3032
3033 if(secure_mode) {
3034 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05303035 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003036 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08003037 nativeBuffersUsage->nUsage =
3038 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
3039 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003040 }
3041 } else {
3042 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
3043 eRet = OMX_ErrorBadParameter;
3044 }
3045 }
3046 break;
3047#endif
3048
3049 default:
3050 {
3051 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
3052 eRet =OMX_ErrorUnsupportedIndex;
3053 }
3054
3055 }
3056
3057 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3058 drv_ctx.video_resolution.frame_width,
3059 drv_ctx.video_resolution.frame_height,
3060 drv_ctx.video_resolution.stride,
3061 drv_ctx.video_resolution.scan_lines);
3062
3063 return eRet;
3064}
3065
3066#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3067OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3068{
3069 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3070 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3071 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3072
3073 if((params == NULL) ||
3074 (params->nativeBuffer == NULL) ||
3075 (params->nativeBuffer->handle == NULL) ||
3076 !m_enable_android_native_buffers)
3077 return OMX_ErrorBadParameter;
3078 m_use_android_native_buffers = OMX_TRUE;
3079 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3080 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3081 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3082 OMX_U8 *buffer = NULL;
3083 if(!secure_mode) {
3084 buffer = (OMX_U8*)mmap(0, handle->size,
3085 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3086 if(buffer == MAP_FAILED) {
3087 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3088 return OMX_ErrorInsufficientResources;
3089 }
3090 }
3091 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3092 } else {
3093 eRet = OMX_ErrorBadParameter;
3094 }
3095 return eRet;
3096}
3097#endif
3098/* ======================================================================
3099FUNCTION
3100 omx_vdec::Setparameter
3101
3102DESCRIPTION
3103 OMX Set Parameter method implementation.
3104
3105PARAMETERS
3106 <TBD>.
3107
3108RETURN VALUE
3109 OMX Error None if successful.
3110
3111========================================================================== */
3112OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3113 OMX_IN OMX_INDEXTYPE paramIndex,
3114 OMX_IN OMX_PTR paramData)
3115{
3116 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003117 int ret=0;
3118 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003119 if(m_state == OMX_StateInvalid)
3120 {
3121 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3122 return OMX_ErrorInvalidState;
3123 }
3124 if(paramData == NULL)
3125 {
3126 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3127 return OMX_ErrorBadParameter;
3128 }
3129 if((m_state != OMX_StateLoaded) &&
3130 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3131 (m_out_bEnabled == OMX_TRUE) &&
3132 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3133 (m_inp_bEnabled == OMX_TRUE)) {
3134 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3135 return OMX_ErrorIncorrectStateOperation;
3136 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003137 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003138 {
3139 case OMX_IndexParamPortDefinition:
3140 {
3141 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3142 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3143 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3144 //been called.
3145 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3146 (int)portDefn->format.video.nFrameHeight,
3147 (int)portDefn->format.video.nFrameWidth);
3148 if(OMX_DirOutput == portDefn->eDir)
3149 {
3150 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3151 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003152 unsigned int buffer_size;
3153 if (!client_buffers.get_buffer_req(buffer_size)) {
3154 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003155 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003156 } else {
3157 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3158 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3159 {
3160 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3161 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
Arun Menonefe1a8e2013-04-22 10:49:26 -07003162 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3163 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3164 drv_ctx.extradata_info.buffer_size;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003165 eRet = set_buffer_req(&drv_ctx.op_buf);
3166 if (eRet == OMX_ErrorNone)
3167 m_port_def = *portDefn;
3168 }
3169 else
3170 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003171 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003172 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3173 portDefn->nBufferCountActual, portDefn->nBufferSize);
3174 eRet = OMX_ErrorBadParameter;
3175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003176 }
3177 }
3178 else if(OMX_DirInput == portDefn->eDir)
3179 {
3180 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3181 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3182 {
3183 // Frame rate only should be set if this is a "known value" or to
3184 // activate ts prediction logic (arbitrary mode only) sending input
3185 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003186 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003187 portDefn->format.video.xFramerate >> 16);
3188 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3189 drv_ctx.frame_rate.fps_denominator);
3190 if(!drv_ctx.frame_rate.fps_numerator)
3191 {
3192 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3193 drv_ctx.frame_rate.fps_numerator = 30;
3194 }
3195 if(drv_ctx.frame_rate.fps_denominator)
3196 drv_ctx.frame_rate.fps_numerator = (int)
3197 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3198 drv_ctx.frame_rate.fps_denominator = 1;
3199 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3200 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003201 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003202 frm_int, drv_ctx.frame_rate.fps_numerator /
3203 (float)drv_ctx.frame_rate.fps_denominator);
3204 }
3205 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3206 if(drv_ctx.video_resolution.frame_height !=
3207 portDefn->format.video.nFrameHeight ||
3208 drv_ctx.video_resolution.frame_width !=
3209 portDefn->format.video.nFrameWidth)
3210 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003211 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003212 portDefn->format.video.nFrameWidth,
3213 portDefn->format.video.nFrameHeight);
3214 if (portDefn->format.video.nFrameHeight != 0x0 &&
3215 portDefn->format.video.nFrameWidth != 0x0)
3216 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003217 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003218 portDefn->format.video.nFrameHeight,
3219 portDefn->format.video.nFrameWidth,
3220 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003221 eRet = is_video_session_supported();
3222 if (eRet)
3223 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003224 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3225 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3226 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3227 fmt.fmt.pix_mp.pixelformat = output_capability;
3228 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);
3229 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003230 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003231 {
3232 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3233 eRet = OMX_ErrorUnsupportedSetting;
3234 }
3235 else
3236 eRet = get_buffer_req(&drv_ctx.op_buf);
3237 }
3238 }
3239 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003240 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003241 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003242 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003243 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003244 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3245 (~(buffer_prop->alignment - 1));
3246 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247 }
3248 else
3249 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003250 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003251 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3252 portDefn->nBufferCountActual, portDefn->nBufferSize);
3253 eRet = OMX_ErrorBadParameter;
3254 }
3255 }
3256 else if (portDefn->eDir == OMX_DirMax)
3257 {
3258 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3259 (int)portDefn->nPortIndex);
3260 eRet = OMX_ErrorBadPortIndex;
3261 }
3262 }
3263 break;
3264 case OMX_IndexParamVideoPortFormat:
3265 {
3266 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3267 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3268 int ret=0;
3269 struct v4l2_format fmt;
3270 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3271 portFmt->eColorFormat);
3272
3273 if(1 == portFmt->nPortIndex)
3274 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003275 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3276 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3277 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3278 fmt.fmt.pix_mp.pixelformat = capture_capability;
3279 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003280 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3281 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003282 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003283 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003284 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003285 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003286 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3287 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3288 else
3289 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003290
Vinay Kaliada4f4422013-01-09 10:45:03 -08003291 if(eRet == OMX_ErrorNone)
3292 {
3293 drv_ctx.output_format = op_format;
3294 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3295 if(ret)
3296 {
3297 DEBUG_PRINT_ERROR("\n Set output format failed");
3298 eRet = OMX_ErrorUnsupportedSetting;
3299 /*TODO: How to handle this case */
3300 }
3301 else
3302 {
3303 eRet = get_buffer_req(&drv_ctx.op_buf);
3304 }
3305 }
3306 if (eRet == OMX_ErrorNone){
3307 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3308 DEBUG_PRINT_ERROR("\n Set color format failed");
3309 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003310 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003311 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003312 }
3313 }
3314 break;
3315
3316 case OMX_QcomIndexPortDefn:
3317 {
3318 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3319 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003320 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003321 portFmt->nFramePackingFormat);
3322
3323 /* Input port */
3324 if (portFmt->nPortIndex == 0)
3325 {
3326 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3327 {
3328 if(secure_mode) {
3329 arbitrary_bytes = false;
3330 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3331 eRet = OMX_ErrorUnsupportedSetting;
3332 } else {
3333 arbitrary_bytes = true;
3334 }
3335 }
3336 else if (portFmt->nFramePackingFormat ==
3337 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3338 {
3339 arbitrary_bytes = false;
3340 }
3341 else
3342 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003343 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003344 portFmt->nFramePackingFormat);
3345 eRet = OMX_ErrorUnsupportedSetting;
3346 }
3347 }
3348 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3349 {
3350 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3351 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3352 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3353 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3354 {
3355 m_out_mem_region_smi = OMX_TRUE;
3356 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3357 {
3358 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3359 m_use_output_pmem = OMX_TRUE;
3360 }
3361 }
3362 }
3363 }
3364 break;
3365
3366 case OMX_IndexParamStandardComponentRole:
3367 {
3368 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3369 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3370 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3371 comp_role->cRole);
3372
3373 if((m_state == OMX_StateLoaded)&&
3374 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3375 {
3376 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3377 }
3378 else
3379 {
3380 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3381 return OMX_ErrorIncorrectStateOperation;
3382 }
3383
3384 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3385 {
3386 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3387 {
3388 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3389 }
3390 else
3391 {
3392 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3393 eRet =OMX_ErrorUnsupportedSetting;
3394 }
3395 }
3396 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3397 {
3398 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3399 {
3400 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3401 }
3402 else
3403 {
3404 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3405 eRet = OMX_ErrorUnsupportedSetting;
3406 }
3407 }
3408 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3409 {
3410 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3411 {
3412 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3413 }
3414 else
3415 {
3416 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3417 eRet =OMX_ErrorUnsupportedSetting;
3418 }
3419 }
3420 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3421 {
3422 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3423 {
3424 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3425 }
3426 else
3427 {
3428 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3429 eRet = OMX_ErrorUnsupportedSetting;
3430 }
3431 }
3432 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3433 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3434 )
3435 {
3436 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3437 {
3438 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3439 }
3440 else
3441 {
3442 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3443 eRet =OMX_ErrorUnsupportedSetting;
3444 }
3445 }
3446 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3447 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3448 )
3449 {
3450 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3451 {
3452 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3453 }
3454 else
3455 {
3456 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3457 eRet =OMX_ErrorUnsupportedSetting;
3458 }
3459 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003460 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3461 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003462 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3463 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003464 {
3465 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3466 }
3467 else
3468 {
3469 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3470 eRet = OMX_ErrorUnsupportedSetting;
3471 }
3472 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003473 else
3474 {
3475 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3476 eRet = OMX_ErrorInvalidComponentName;
3477 }
3478 break;
3479 }
3480
3481 case OMX_IndexParamPriorityMgmt:
3482 {
3483 if(m_state != OMX_StateLoaded)
3484 {
3485 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3486 return OMX_ErrorIncorrectStateOperation;
3487 }
3488 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003489 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003490 priorityMgmtype->nGroupID);
3491
Shalaj Jainaf08f302013-03-18 13:15:35 -07003492 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003493 priorityMgmtype->nGroupPriority);
3494
3495 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3496 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3497
3498 break;
3499 }
3500
3501 case OMX_IndexParamCompBufferSupplier:
3502 {
3503 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3504 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3505 bufferSupplierType->eBufferSupplier);
3506 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3507 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3508
3509 else
3510
3511 eRet = OMX_ErrorBadPortIndex;
3512
3513 break;
3514
3515 }
3516 case OMX_IndexParamVideoAvc:
3517 {
3518 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3519 paramIndex);
3520 break;
3521 }
3522 case OMX_IndexParamVideoH263:
3523 {
3524 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3525 paramIndex);
3526 break;
3527 }
3528 case OMX_IndexParamVideoMpeg4:
3529 {
3530 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3531 paramIndex);
3532 break;
3533 }
3534 case OMX_IndexParamVideoMpeg2:
3535 {
3536 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3537 paramIndex);
3538 break;
3539 }
3540 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3541 {
3542 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3543 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003544 struct v4l2_control control;
3545 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003546 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3547 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003548 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3549 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3550 }
3551 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3552 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003553 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003554 }
3555 else
3556 eRet = OMX_ErrorBadParameter;
3557 if (eRet == OMX_ErrorNone)
3558 {
3559 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3560 control.value = pic_order;
3561 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3562 if(rc)
3563 {
3564 DEBUG_PRINT_ERROR("\n Set picture order failed");
3565 eRet = OMX_ErrorUnsupportedSetting;
3566 }
3567 }
3568 break;
3569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003570 case OMX_QcomIndexParamConcealMBMapExtraData:
3571 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003572 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003573 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3574 else {
3575 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3576 eRet = OMX_ErrorUnsupportedSetting;
3577 }
3578 break;
3579 case OMX_QcomIndexParamFrameInfoExtraData:
3580 {
3581 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003582 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3584 else {
3585 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3586 eRet = OMX_ErrorUnsupportedSetting;
3587 }
3588 break;
3589 }
3590 case OMX_QcomIndexParamInterlaceExtraData:
3591 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003592 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003593 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3594 else {
3595 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3596 eRet = OMX_ErrorUnsupportedSetting;
3597 }
3598 break;
3599 case OMX_QcomIndexParamH264TimeInfo:
3600 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003601 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003602 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3603 else {
3604 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3605 eRet = OMX_ErrorUnsupportedSetting;
3606 }
3607 break;
3608 case OMX_QcomIndexParamVideoDivx:
3609 {
3610 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003611 }
3612 break;
3613 case OMX_QcomIndexPlatformPvt:
3614 {
3615 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3616 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3617 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3618 {
3619 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3620 eRet = OMX_ErrorUnsupportedSetting;
3621 }
3622 else
3623 {
3624 m_out_pvt_entry_pmem = OMX_TRUE;
3625 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3626 {
3627 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3628 m_use_output_pmem = OMX_TRUE;
3629 }
3630 }
3631
3632 }
3633 break;
3634 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3635 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003636 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3637 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3638 struct v4l2_control control;
3639 int rc;
3640 drv_ctx.idr_only_decoding = 1;
3641 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3642 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3643 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3644 if(rc)
3645 {
3646 DEBUG_PRINT_ERROR("\n Set picture order failed");
3647 eRet = OMX_ErrorUnsupportedSetting;
3648 } else {
3649 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3650 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3651 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3652 if(rc)
3653 {
3654 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3655 eRet = OMX_ErrorUnsupportedSetting;
3656 }
3657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003658 }
3659 break;
3660
3661 case OMX_QcomIndexParamIndexExtraDataType:
3662 {
3663 if(!secure_mode) {
3664 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3665 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3666 (extradataIndexType->bEnabled == OMX_TRUE) &&
3667 (extradataIndexType->nPortIndex == 1))
3668 {
3669 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003670 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003671
Shalaj Jain273b3e02012-06-22 19:08:03 -07003672 }
3673 }
3674 }
3675 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003676 case OMX_QcomIndexParamEnableSmoothStreaming:
3677 {
Arun Menonc821d8a2013-06-15 10:03:29 -07003678#ifndef SMOOTH_STREAMING_DISABLED
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003679 struct v4l2_control control;
3680 struct v4l2_format fmt;
3681 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3682 control.value = 1;
3683 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3684 if(rc < 0) {
3685 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3686 eRet = OMX_ErrorHardware;
3687 }
Arun Menonc821d8a2013-06-15 10:03:29 -07003688#endif
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003689 }
3690 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003691#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3692 /* Need to allow following two set_parameters even in Idle
3693 * state. This is ANDROID architecture which is not in sync
3694 * with openmax standard. */
3695 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3696 {
3697 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3698 if(enableNativeBuffers) {
3699 m_enable_android_native_buffers = enableNativeBuffers->enable;
3700 }
3701 }
3702 break;
3703 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3704 {
3705 eRet = use_android_native_buffer(hComp, paramData);
3706 }
3707 break;
3708#endif
3709 case OMX_QcomIndexParamEnableTimeStampReorder:
3710 {
3711 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003712 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003713 if (reorder->bEnable == OMX_TRUE) {
3714 frm_int =0;
3715 time_stamp_dts.set_timestamp_reorder_mode(true);
3716 }
3717 else
3718 time_stamp_dts.set_timestamp_reorder_mode(false);
3719 } else {
3720 time_stamp_dts.set_timestamp_reorder_mode(false);
3721 if (reorder->bEnable == OMX_TRUE)
3722 {
3723 eRet = OMX_ErrorUnsupportedSetting;
3724 }
3725 }
3726 }
3727 break;
3728 default:
3729 {
3730 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3731 eRet = OMX_ErrorUnsupportedIndex;
3732 }
3733 }
3734 return eRet;
3735}
3736
3737/* ======================================================================
3738FUNCTION
3739 omx_vdec::GetConfig
3740
3741DESCRIPTION
3742 OMX Get Config Method implementation.
3743
3744PARAMETERS
3745 <TBD>.
3746
3747RETURN VALUE
3748 OMX Error None if successful.
3749
3750========================================================================== */
3751OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3752 OMX_IN OMX_INDEXTYPE configIndex,
3753 OMX_INOUT OMX_PTR configData)
3754{
3755 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3756
3757 if (m_state == OMX_StateInvalid)
3758 {
3759 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3760 return OMX_ErrorInvalidState;
3761 }
3762
Shalaj Jain286b0062013-02-21 20:35:48 -08003763 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003764 {
3765 case OMX_QcomIndexConfigInterlaced:
3766 {
3767 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3768 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3769 if (configFmt->nPortIndex == 1)
3770 {
3771 if (configFmt->nIndex == 0)
3772 {
3773 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3774 }
3775 else if (configFmt->nIndex == 1)
3776 {
3777 configFmt->eInterlaceType =
3778 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3779 }
3780 else if (configFmt->nIndex == 2)
3781 {
3782 configFmt->eInterlaceType =
3783 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3784 }
3785 else
3786 {
3787 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3788 " NoMore Interlaced formats\n");
3789 eRet = OMX_ErrorNoMore;
3790 }
3791
3792 }
3793 else
3794 {
3795 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3796 (int)configFmt->nPortIndex);
3797 eRet = OMX_ErrorBadPortIndex;
3798 }
3799 break;
3800 }
3801 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3802 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003803 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3804 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003805 decoderinstances->nNumOfInstances = 16;
3806 /*TODO: How to handle this case */
3807 break;
3808 }
3809 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3810 {
3811 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3812 {
3813 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3814 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3815 h264_parser->get_frame_pack_data(configFmt);
3816 }
3817 else
3818 {
3819 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3820 }
3821 break;
3822 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07003823 case OMX_IndexConfigCommonOutputCrop:
Vinay Kalia592e4b42012-12-19 15:55:47 -08003824 {
3825 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3826 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3827 break;
3828 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07003829 default:
Shalaj Jain273b3e02012-06-22 19:08:03 -07003830 {
3831 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3832 eRet = OMX_ErrorBadParameter;
3833 }
3834
3835 }
3836
3837 return eRet;
3838}
3839
3840/* ======================================================================
3841FUNCTION
3842 omx_vdec::SetConfig
3843
3844DESCRIPTION
3845 OMX Set Config method implementation
3846
3847PARAMETERS
3848 <TBD>.
3849
3850RETURN VALUE
3851 OMX Error None if successful.
3852========================================================================== */
3853OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3854 OMX_IN OMX_INDEXTYPE configIndex,
3855 OMX_IN OMX_PTR configData)
3856{
3857 if(m_state == OMX_StateInvalid)
3858 {
3859 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3860 return OMX_ErrorInvalidState;
3861 }
3862
3863 OMX_ERRORTYPE ret = OMX_ErrorNone;
3864 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3865
3866 DEBUG_PRINT_LOW("\n Set Config Called");
3867
Shalaj Jain286b0062013-02-21 20:35:48 -08003868 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003869 {
3870 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3871 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3872 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3873 {
3874 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3875 OMX_U32 extra_size;
3876 // Parsing done here for the AVC atom is definitely not generic
3877 // Currently this piece of code is working, but certainly
3878 // not tested with all .mp4 files.
3879 // Incase of failure, we might need to revisit this
3880 // for a generic piece of code.
3881
3882 // Retrieve size of NAL length field
3883 // byte #4 contains the size of NAL lenght field
3884 nal_length = (config->pData[4] & 0x03) + 1;
3885
3886 extra_size = 0;
3887 if (nal_length > 2)
3888 {
3889 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3890 extra_size = (nal_length - 2) * 2;
3891 }
3892
3893 // SPS starts from byte #6
3894 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3895 OMX_U8 *pDestBuf;
3896 m_vendor_config.nPortIndex = config->nPortIndex;
3897
3898 // minus 6 --> SPS starts from byte #6
3899 // minus 1 --> picture param set byte to be ignored from avcatom
3900 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3901 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3902 OMX_U32 len;
3903 OMX_U8 index = 0;
3904 // case where SPS+PPS is sent as part of set_config
3905 pDestBuf = m_vendor_config.pData;
3906
Shalaj Jainaf08f302013-03-18 13:15:35 -07003907 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003908 m_vendor_config.nPortIndex,
3909 m_vendor_config.nDataSize,
3910 m_vendor_config.pData);
3911 while (index < 2)
3912 {
3913 uint8 *psize;
3914 len = *pSrcBuf;
3915 len = len << 8;
3916 len |= *(pSrcBuf + 1);
3917 psize = (uint8 *) & len;
3918 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003919 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003920 {
3921 pDestBuf[i] = psize[nal_length - 1 - i];
3922 }
3923 //memcpy(pDestBuf,pSrcBuf,(len+2));
3924 pDestBuf += len + nal_length;
3925 pSrcBuf += len + 2;
3926 index++;
3927 pSrcBuf++; // skip picture param set
3928 len = 0;
3929 }
3930 }
3931 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3932 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3933 {
3934 m_vendor_config.nPortIndex = config->nPortIndex;
3935 m_vendor_config.nDataSize = config->nDataSize;
3936 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3937 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3938 }
3939 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3940 {
3941 if(m_vendor_config.pData)
3942 {
3943 free(m_vendor_config.pData);
3944 m_vendor_config.pData = NULL;
3945 m_vendor_config.nDataSize = 0;
3946 }
3947
3948 if (((*((OMX_U32 *) config->pData)) &
3949 VC1_SP_MP_START_CODE_MASK) ==
3950 VC1_SP_MP_START_CODE)
3951 {
3952 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3953 m_vendor_config.nPortIndex = config->nPortIndex;
3954 m_vendor_config.nDataSize = config->nDataSize;
3955 m_vendor_config.pData =
3956 (OMX_U8 *) malloc(config->nDataSize);
3957 memcpy(m_vendor_config.pData, config->pData,
3958 config->nDataSize);
3959 m_vc1_profile = VC1_SP_MP_RCV;
3960 }
3961 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3962 {
3963 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3964 m_vendor_config.nPortIndex = config->nPortIndex;
3965 m_vendor_config.nDataSize = config->nDataSize;
3966 m_vendor_config.pData =
3967 (OMX_U8 *) malloc((config->nDataSize));
3968 memcpy(m_vendor_config.pData, config->pData,
3969 config->nDataSize);
3970 m_vc1_profile = VC1_AP;
3971 }
3972 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3973 {
3974 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3975 m_vendor_config.nPortIndex = config->nPortIndex;
3976 m_vendor_config.nDataSize = config->nDataSize;
3977 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3978 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3979 m_vc1_profile = VC1_SP_MP_RCV;
3980 }
3981 else
3982 {
3983 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3984 }
3985 }
3986 return ret;
3987 }
3988 else if (configIndex == OMX_IndexConfigVideoNalSize)
3989 {
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07003990 struct v4l2_control temp;
3991 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003992
3993 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07003994 switch (pNal->nNaluBytes) {
3995 case 0:
3996 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3997 break;
3998 case 2:
3999 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4000 break;
4001 case 4:
4002 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4003 break;
4004 default:
4005 return OMX_ErrorUnsupportedSetting;
4006 }
4007
4008 if (!arbitrary_bytes) {
4009 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4010 * with start code, so only need to notify driver in frame by frame mode */
4011 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp))
4012 {
4013 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4014 return OMX_ErrorHardware;
4015 }
4016 }
4017
Shalaj Jain273b3e02012-06-22 19:08:03 -07004018 nal_length = pNal->nNaluBytes;
4019 m_frame_parser.init_nal_length(nal_length);
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07004020
4021 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004022 return ret;
4023 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07004024 else if (configIndex == OMX_IndexVendorVideoFrameRate)
4025 {
4026 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
4027 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
4028
4029 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
4030 {
4031 if (config->bEnabled)
4032 {
4033 if ((config->nFps >> 16) > 0)
4034 {
4035 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
4036 config->nFps >> 16);
4037 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4038 drv_ctx.frame_rate.fps_denominator);
4039
4040 if (!drv_ctx.frame_rate.fps_numerator)
4041 {
4042 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4043 drv_ctx.frame_rate.fps_numerator = 30;
4044 }
4045
4046 if (drv_ctx.frame_rate.fps_denominator)
4047 {
4048 drv_ctx.frame_rate.fps_numerator = (int)
4049 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4050 }
4051
4052 drv_ctx.frame_rate.fps_denominator = 1;
4053 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4054 drv_ctx.frame_rate.fps_numerator;
4055
4056 struct v4l2_outputparm oparm;
4057 /*XXX: we're providing timing info as seconds per frame rather than frames
4058 * per second.*/
4059 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4060 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4061
4062 struct v4l2_streamparm sparm;
4063 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4064 sparm.parm.output = oparm;
4065 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm))
4066 {
4067 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4068 performance might be affected");
4069 ret = OMX_ErrorHardware;
4070 }
4071 client_set_fps = true;
4072 }
4073 else
4074 {
4075 DEBUG_PRINT_ERROR("Frame rate not supported.");
4076 ret = OMX_ErrorUnsupportedSetting;
4077 }
4078 }
4079 else
4080 {
4081 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4082 client_set_fps = false;
4083 }
4084 }
4085 else
4086 {
4087 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4088 (int)config->nPortIndex);
4089 ret = OMX_ErrorBadPortIndex;
4090 }
4091
4092 return ret;
4093 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004094
4095 return OMX_ErrorNotImplemented;
4096}
4097
4098/* ======================================================================
4099FUNCTION
4100 omx_vdec::GetExtensionIndex
4101
4102DESCRIPTION
4103 OMX GetExtensionIndex method implementaion. <TBD>
4104
4105PARAMETERS
4106 <TBD>.
4107
4108RETURN VALUE
4109 OMX Error None if everything successful.
4110
4111========================================================================== */
4112OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4113 OMX_IN OMX_STRING paramName,
4114 OMX_OUT OMX_INDEXTYPE* indexType)
4115{
4116 if(m_state == OMX_StateInvalid)
4117 {
4118 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
4119 return OMX_ErrorInvalidState;
4120 }
4121 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
4122 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
4123 }
4124 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
4125 {
4126 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
4127 }
4128#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4129 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
4130 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
4131 }
4132 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
4133 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
4134 }
4135 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
4136 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
4137 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
4138 }
4139 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
4140 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4141 }
4142#endif
4143 else {
4144 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
4145 return OMX_ErrorNotImplemented;
4146 }
4147 return OMX_ErrorNone;
4148}
4149
4150/* ======================================================================
4151FUNCTION
4152 omx_vdec::GetState
4153
4154DESCRIPTION
4155 Returns the state information back to the caller.<TBD>
4156
4157PARAMETERS
4158 <TBD>.
4159
4160RETURN VALUE
4161 Error None if everything is successful.
4162========================================================================== */
4163OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4164 OMX_OUT OMX_STATETYPE* state)
4165{
4166 *state = m_state;
4167 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4168 return OMX_ErrorNone;
4169}
4170
4171/* ======================================================================
4172FUNCTION
4173 omx_vdec::ComponentTunnelRequest
4174
4175DESCRIPTION
4176 OMX Component Tunnel Request method implementation. <TBD>
4177
4178PARAMETERS
4179 None.
4180
4181RETURN VALUE
4182 OMX Error None if everything successful.
4183
4184========================================================================== */
4185OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4186 OMX_IN OMX_U32 port,
4187 OMX_IN OMX_HANDLETYPE peerComponent,
4188 OMX_IN OMX_U32 peerPort,
4189 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4190{
4191 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4192 return OMX_ErrorNotImplemented;
4193}
4194
4195/* ======================================================================
4196FUNCTION
4197 omx_vdec::UseOutputBuffer
4198
4199DESCRIPTION
4200 Helper function for Use buffer in the input pin
4201
4202PARAMETERS
4203 None.
4204
4205RETURN VALUE
4206 true/false
4207
4208========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004209OMX_ERRORTYPE omx_vdec::allocate_extradata()
4210{
4211#ifdef USE_ION
4212 if (drv_ctx.extradata_info.buffer_size) {
4213 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4214 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4215 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4216 free_ion_memory(&drv_ctx.extradata_info.ion);
4217 }
4218 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4219 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
Arun Menonefe1a8e2013-04-22 10:49:26 -07004220 drv_ctx.extradata_info.size, 4096,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004221 &drv_ctx.extradata_info.ion.ion_alloc_data,
4222 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4223 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4224 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4225 return OMX_ErrorInsufficientResources;
4226 }
4227 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4228 drv_ctx.extradata_info.size,
4229 PROT_READ|PROT_WRITE, MAP_SHARED,
4230 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4231 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4232 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4233 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4234 free_ion_memory(&drv_ctx.extradata_info.ion);
4235 return OMX_ErrorInsufficientResources;
4236 }
4237 }
4238#endif
4239 return OMX_ErrorNone;
4240}
4241
4242void omx_vdec::free_extradata() {
4243#ifdef USE_ION
4244 if (drv_ctx.extradata_info.uaddr) {
4245 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4246 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4247 free_ion_memory(&drv_ctx.extradata_info.ion);
4248 }
4249 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4250#endif
4251}
4252
Shalaj Jain273b3e02012-06-22 19:08:03 -07004253OMX_ERRORTYPE omx_vdec::use_output_buffer(
4254 OMX_IN OMX_HANDLETYPE hComp,
4255 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4256 OMX_IN OMX_U32 port,
4257 OMX_IN OMX_PTR appData,
4258 OMX_IN OMX_U32 bytes,
4259 OMX_IN OMX_U8* buffer)
4260{
4261 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4262 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4263 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004264 struct vdec_setbuffer_cmd setbuffers;
4265 OMX_PTR privateAppData = NULL;
4266 private_handle_t *handle = NULL;
4267 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004268 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004269 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4270 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004271
Shalaj Jain273b3e02012-06-22 19:08:03 -07004272 if (!m_out_mem_ptr) {
4273 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4274 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004275 if (eRet == OMX_ErrorNone)
4276 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004277 }
4278
4279 if (eRet == OMX_ErrorNone) {
4280 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4281 if(BITMASK_ABSENT(&m_out_bm_count,i))
4282 {
4283 break;
4284 }
4285 }
4286 }
4287
4288 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004289 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004290 eRet = OMX_ErrorInsufficientResources;
4291 }
4292
4293 if (eRet == OMX_ErrorNone) {
4294#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4295 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004296 if (m_use_android_native_buffers) {
4297 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4298 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4299 handle = (private_handle_t *)nBuf->handle;
4300 privateAppData = params->pAppPrivate;
4301 } else {
4302 handle = (private_handle_t *)buff;
4303 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004304 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004305
4306 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4307 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4308 " expected %u, got %lu",
4309 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4310 return OMX_ErrorBadParameter;
4311 }
4312
4313 if (!m_use_android_native_buffers) {
4314 if (!secure_mode) {
4315 buff = (OMX_U8*)mmap(0, handle->size,
4316 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4317 if (buff == MAP_FAILED) {
4318 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4319 return OMX_ErrorInsufficientResources;
4320 }
4321 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004322 }
4323#if defined(_ANDROID_ICS_)
4324 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004325 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004326#endif
4327 if(!handle) {
4328 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4329 return OMX_ErrorBadParameter;
4330 }
4331 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4332 drv_ctx.ptr_outputbuffer[i].offset = 0;
4333 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
Vinay Kaliaac837f72013-05-28 17:29:30 -07004334 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4335 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004336 } else
4337#endif
4338
4339 if (!ouput_egl_buffers && !m_use_output_pmem) {
4340#ifdef USE_ION
4341 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4342 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4343 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004344 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004345 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004346 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 -07004347 return OMX_ErrorInsufficientResources;
4348 }
4349 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4350 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4351#else
4352 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4353 open (MEM_DEVICE,O_RDWR);
4354
4355 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004356 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 -07004357 return OMX_ErrorInsufficientResources;
4358 }
4359
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004360 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004361 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4362 {
4363 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4364 open (MEM_DEVICE,O_RDWR);
4365 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004366 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 -07004367 return OMX_ErrorInsufficientResources;
4368 }
4369 }
4370
4371 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4372 drv_ctx.op_buf.buffer_size,
4373 drv_ctx.op_buf.alignment))
4374 {
4375 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4376 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4377 return OMX_ErrorInsufficientResources;
4378 }
4379#endif
4380 if(!secure_mode) {
4381 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4382 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4383 PROT_READ|PROT_WRITE, MAP_SHARED,
4384 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4385 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4386 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4387#ifdef USE_ION
4388 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4389#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004390 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004391 return OMX_ErrorInsufficientResources;
4392 }
4393 }
4394 drv_ctx.ptr_outputbuffer[i].offset = 0;
4395 privateAppData = appData;
4396 }
4397 else {
4398
4399 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4400 if (!appData || !bytes ) {
4401 if(!secure_mode && !buffer) {
4402 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4403 return OMX_ErrorBadParameter;
4404 }
4405 }
4406
4407 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4408 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4409 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4410 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4411 !pmem_list->nEntries ||
4412 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4413 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4414 return OMX_ErrorBadParameter;
4415 }
4416 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4417 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004418 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004419 pmem_info->pmem_fd);
4420 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4421 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4422 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4423 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4424 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4425 privateAppData = appData;
4426 }
4427 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4428 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4429
4430 *bufferHdr = (m_out_mem_ptr + i );
4431 if(secure_mode)
4432 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4433 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4434 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4435 sizeof (vdec_bufferpayload));
4436
Shalaj Jain286b0062013-02-21 20:35:48 -08004437 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4438 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4439 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004440
4441 buf.index = i;
4442 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4443 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004444 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004445 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4446 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004447 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4448 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4449 plane[0].data_offset = 0;
4450 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4451 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4452 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4453 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4454#ifdef USE_ION
4455 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4456#endif
4457 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4458 plane[extra_idx].data_offset = 0;
4459 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4460 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4461 return OMX_ErrorBadParameter;
4462 }
4463 buf.m.planes = plane;
4464 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004465
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004466 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4467 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4468 /*TODO: How to handle this case */
4469 return OMX_ErrorInsufficientResources;
4470 }
4471
4472 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4473 enum v4l2_buf_type buf_type;
4474 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4475 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4476 return OMX_ErrorInsufficientResources;
4477 } else {
4478 streaming[CAPTURE_PORT] = true;
4479 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4480 }
4481 }
4482
Shalaj Jain273b3e02012-06-22 19:08:03 -07004483 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004484 if (m_enable_android_native_buffers) {
4485 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4486 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4487 } else {
4488 (*bufferHdr)->pBuffer = buff;
4489 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004490 (*bufferHdr)->pAppPrivate = privateAppData;
4491 BITMASK_SET(&m_out_bm_count,i);
4492 }
4493 return eRet;
4494}
4495
4496/* ======================================================================
4497FUNCTION
4498 omx_vdec::use_input_heap_buffers
4499
4500DESCRIPTION
4501 OMX Use Buffer Heap allocation method implementation.
4502
4503PARAMETERS
4504 <TBD>.
4505
4506RETURN VALUE
4507 OMX Error None , if everything successful.
4508
4509========================================================================== */
4510OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4511 OMX_IN OMX_HANDLETYPE hComp,
4512 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4513 OMX_IN OMX_U32 port,
4514 OMX_IN OMX_PTR appData,
4515 OMX_IN OMX_U32 bytes,
4516 OMX_IN OMX_U8* buffer)
4517{
4518 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4519 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4520 if(!m_inp_heap_ptr)
4521 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4522 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4523 drv_ctx.ip_buf.actualcount);
4524 if(!m_phdr_pmem_ptr)
4525 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4526 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4527 drv_ctx.ip_buf.actualcount);
4528 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4529 {
4530 DEBUG_PRINT_ERROR("Insufficent memory");
4531 eRet = OMX_ErrorInsufficientResources;
4532 }
4533 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4534 {
4535 input_use_buffer = true;
4536 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4537 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4538 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4539 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4540 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4541 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4542 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4543 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4544 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 -08004545 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4546 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004547 {
4548 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4549 return OMX_ErrorInsufficientResources;
4550 }
4551 m_in_alloc_cnt++;
4552 }
4553 else
4554 {
4555 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4556 eRet = OMX_ErrorInsufficientResources;
4557 }
4558 return eRet;
4559}
4560
4561/* ======================================================================
4562FUNCTION
4563 omx_vdec::UseBuffer
4564
4565DESCRIPTION
4566 OMX Use Buffer method implementation.
4567
4568PARAMETERS
4569 <TBD>.
4570
4571RETURN VALUE
4572 OMX Error None , if everything successful.
4573
4574========================================================================== */
4575OMX_ERRORTYPE omx_vdec::use_buffer(
4576 OMX_IN OMX_HANDLETYPE hComp,
4577 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4578 OMX_IN OMX_U32 port,
4579 OMX_IN OMX_PTR appData,
4580 OMX_IN OMX_U32 bytes,
4581 OMX_IN OMX_U8* buffer)
4582{
4583 OMX_ERRORTYPE error = OMX_ErrorNone;
4584 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585
4586 if (bufferHdr == NULL || bytes == 0)
4587 {
4588 if(!secure_mode && buffer == NULL) {
4589 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4590 return OMX_ErrorBadParameter;
4591 }
4592 }
4593 if(m_state == OMX_StateInvalid)
4594 {
4595 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4596 return OMX_ErrorInvalidState;
4597 }
4598 if(port == OMX_CORE_INPUT_PORT_INDEX)
4599 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4600 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4601 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4602 else
4603 {
4604 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4605 error = OMX_ErrorBadPortIndex;
4606 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004607 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004608 if(error == OMX_ErrorNone)
4609 {
4610 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4611 {
4612 // Send the callback now
4613 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4614 post_event(OMX_CommandStateSet,OMX_StateIdle,
4615 OMX_COMPONENT_GENERATE_EVENT);
4616 }
4617 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4618 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4619 {
4620 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4621 post_event(OMX_CommandPortEnable,
4622 OMX_CORE_INPUT_PORT_INDEX,
4623 OMX_COMPONENT_GENERATE_EVENT);
4624 }
4625 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4626 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4627 {
4628 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4629 post_event(OMX_CommandPortEnable,
4630 OMX_CORE_OUTPUT_PORT_INDEX,
4631 OMX_COMPONENT_GENERATE_EVENT);
4632 }
4633 }
4634 return error;
4635}
4636
4637OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4638 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4639{
4640 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4641 {
4642 if(m_inp_heap_ptr[bufferindex].pBuffer)
4643 free(m_inp_heap_ptr[bufferindex].pBuffer);
4644 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4645 }
4646 if (pmem_bufferHdr)
4647 free_input_buffer(pmem_bufferHdr);
4648 return OMX_ErrorNone;
4649}
4650
4651OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4652{
4653 unsigned int index = 0;
4654 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4655 {
4656 return OMX_ErrorBadParameter;
4657 }
4658
4659 index = bufferHdr - m_inp_mem_ptr;
4660 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4661
4662 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4663 {
4664 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4665 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4666 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004667 struct vdec_setbuffer_cmd setbuffers;
4668 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4669 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4670 sizeof (vdec_bufferpayload));
Praveen Chavan212671f2013-04-05 20:00:42 -07004671 if(!secure_mode) {
4672 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4673 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4674 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4675 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4676 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4677 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4678 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4679 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004680 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4681 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4682 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4683 {
4684 free(m_desc_buffer_ptr[index].buf_addr);
4685 m_desc_buffer_ptr[index].buf_addr = NULL;
4686 m_desc_buffer_ptr[index].desc_data_size = 0;
4687 }
4688#ifdef USE_ION
4689 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4690#endif
4691 }
4692 }
4693
4694 return OMX_ErrorNone;
4695}
4696
4697OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4698{
4699 unsigned int index = 0;
4700
4701 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4702 {
4703 return OMX_ErrorBadParameter;
4704 }
4705
4706 index = bufferHdr - m_out_mem_ptr;
4707 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4708
4709 if (index < drv_ctx.op_buf.actualcount
4710 && drv_ctx.ptr_outputbuffer)
4711 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004712 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004713 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4714
Shalaj Jain273b3e02012-06-22 19:08:03 -07004715 struct vdec_setbuffer_cmd setbuffers;
4716 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4717 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4718 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004719#ifdef _ANDROID_
4720 if(m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004721 if (!secure_mode) {
4722 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4723 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4724 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4725 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004726 }
4727 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4728 } else {
4729#endif
4730 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4731 {
Praveen Chavan212671f2013-04-05 20:00:42 -07004732 if (!secure_mode) {
4733 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4734 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4735 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4736 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4737 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4738 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4739 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4740 }
4741 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4742 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004743#ifdef USE_ION
Praveen Chavan212671f2013-04-05 20:00:42 -07004744 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004745#endif
4746 }
4747#ifdef _ANDROID_
4748 }
4749#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004750 if (release_output_done()) {
4751 free_extradata();
4752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004753 }
4754
4755 return OMX_ErrorNone;
4756
4757}
4758
4759OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4760 OMX_BUFFERHEADERTYPE **bufferHdr,
4761 OMX_U32 port,
4762 OMX_PTR appData,
4763 OMX_U32 bytes)
4764{
4765 OMX_BUFFERHEADERTYPE *input = NULL;
4766 unsigned char *buf_addr = NULL;
4767 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4768 unsigned i = 0;
4769
4770 /* Sanity Check*/
4771 if (bufferHdr == NULL)
4772 {
4773 return OMX_ErrorBadParameter;
4774 }
4775
4776 if (m_inp_heap_ptr == NULL)
4777 {
4778 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4779 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4780 drv_ctx.ip_buf.actualcount);
4781 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4782 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4783 drv_ctx.ip_buf.actualcount);
4784
4785 if (m_inp_heap_ptr == NULL)
4786 {
4787 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4788 return OMX_ErrorInsufficientResources;
4789 }
4790 }
4791
4792 /*Find a Free index*/
4793 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4794 {
4795 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4796 {
4797 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4798 break;
4799 }
4800 }
4801
4802 if (i < drv_ctx.ip_buf.actualcount)
4803 {
4804 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4805
4806 if (buf_addr == NULL)
4807 {
4808 return OMX_ErrorInsufficientResources;
4809 }
4810
4811 *bufferHdr = (m_inp_heap_ptr + i);
4812 input = *bufferHdr;
4813 BITMASK_SET(&m_heap_inp_bm_count,i);
4814
4815 input->pBuffer = (OMX_U8 *)buf_addr;
4816 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4817 input->nVersion.nVersion = OMX_SPEC_VERSION;
4818 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4819 input->pAppPrivate = appData;
4820 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4821 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4822 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004823 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004825 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4826 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004827 {
4828 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4829 return OMX_ErrorInsufficientResources;
4830 }
4831 }
4832 else
4833 {
4834 return OMX_ErrorBadParameter;
4835 }
4836
4837 return eRet;
4838
4839}
4840
4841
4842/* ======================================================================
4843FUNCTION
4844 omx_vdec::AllocateInputBuffer
4845
4846DESCRIPTION
4847 Helper function for allocate buffer in the input pin
4848
4849PARAMETERS
4850 None.
4851
4852RETURN VALUE
4853 true/false
4854
4855========================================================================== */
4856OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4857 OMX_IN OMX_HANDLETYPE hComp,
4858 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4859 OMX_IN OMX_U32 port,
4860 OMX_IN OMX_PTR appData,
4861 OMX_IN OMX_U32 bytes)
4862{
4863
4864 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4865 struct vdec_setbuffer_cmd setbuffers;
4866 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004867 unsigned i = 0;
4868 unsigned char *buf_addr = NULL;
4869 int pmem_fd = -1;
4870
4871 if(bytes != drv_ctx.ip_buf.buffer_size)
4872 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004873 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004874 bytes, drv_ctx.ip_buf.buffer_size);
4875 return OMX_ErrorBadParameter;
4876 }
4877
4878 if(!m_inp_mem_ptr)
4879 {
4880 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4881 drv_ctx.ip_buf.actualcount,
4882 drv_ctx.ip_buf.buffer_size);
4883
4884 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4885 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4886
4887 if (m_inp_mem_ptr == NULL)
4888 {
4889 return OMX_ErrorInsufficientResources;
4890 }
4891
4892 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4893 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4894
4895 if (drv_ctx.ptr_inputbuffer == NULL)
4896 {
4897 return OMX_ErrorInsufficientResources;
4898 }
4899#ifdef USE_ION
4900 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4901 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4902
4903 if (drv_ctx.ip_buf_ion_info == NULL)
4904 {
4905 return OMX_ErrorInsufficientResources;
4906 }
4907#endif
4908
4909 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4910 {
4911 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4912#ifdef USE_ION
4913 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4914#endif
4915 }
4916 }
4917
4918 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4919 {
4920 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4921 {
4922 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4923 break;
4924 }
4925 }
4926
4927 if(i < drv_ctx.ip_buf.actualcount)
4928 {
4929 struct v4l2_buffer buf;
4930 struct v4l2_plane plane;
4931 int rc;
4932 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4933#ifdef USE_ION
4934 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4935 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4936 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004937 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004938 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4939 return OMX_ErrorInsufficientResources;
4940 }
4941 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4942#else
4943 pmem_fd = open (MEM_DEVICE,O_RDWR);
4944
4945 if (pmem_fd < 0)
4946 {
4947 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4948 return OMX_ErrorInsufficientResources;
4949 }
4950
4951 if (pmem_fd == 0)
4952 {
4953 pmem_fd = open (MEM_DEVICE,O_RDWR);
4954
4955 if (pmem_fd < 0)
4956 {
4957 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4958 return OMX_ErrorInsufficientResources;
4959 }
4960 }
4961
4962 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4963 drv_ctx.ip_buf.alignment))
4964 {
4965 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4966 close(pmem_fd);
4967 return OMX_ErrorInsufficientResources;
4968 }
4969#endif
4970 if (!secure_mode) {
4971 buf_addr = (unsigned char *)mmap(NULL,
4972 drv_ctx.ip_buf.buffer_size,
4973 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4974
4975 if (buf_addr == MAP_FAILED)
4976 {
4977 close(pmem_fd);
4978#ifdef USE_ION
4979 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4980#endif
4981 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4982 return OMX_ErrorInsufficientResources;
4983 }
4984 }
4985 *bufferHdr = (m_inp_mem_ptr + i);
4986 if (secure_mode)
4987 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4988 else
4989 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4990 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4991 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4992 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4993 drv_ctx.ptr_inputbuffer [i].offset = 0;
4994
4995
4996 buf.index = i;
4997 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4998 buf.memory = V4L2_MEMORY_USERPTR;
4999 plane.bytesused = 0;
5000 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5001 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5002 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5003 plane.reserved[1] = 0;
5004 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5005 buf.m.planes = &plane;
5006 buf.length = 1;
5007
Shalaj Jainaf08f302013-03-18 13:15:35 -07005008 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
5009 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005010
5011 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5012
5013 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005014 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005015 /*TODO: How to handle this case */
5016 return OMX_ErrorInsufficientResources;
5017 }
5018
5019 input = *bufferHdr;
5020 BITMASK_SET(&m_inp_bm_count,i);
5021 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
5022 if (secure_mode)
5023 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5024 else
5025 input->pBuffer = (OMX_U8 *)buf_addr;
5026 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5027 input->nVersion.nVersion = OMX_SPEC_VERSION;
5028 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5029 input->pAppPrivate = appData;
5030 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5031 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5032
5033 if (drv_ctx.disable_dmx)
5034 {
5035 eRet = allocate_desc_buffer(i);
5036 }
5037 }
5038 else
5039 {
5040 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
5041 eRet = OMX_ErrorInsufficientResources;
5042 }
5043 return eRet;
5044}
5045
5046
5047/* ======================================================================
5048FUNCTION
5049 omx_vdec::AllocateOutputBuffer
5050
5051DESCRIPTION
5052 Helper fn for AllocateBuffer in the output pin
5053
5054PARAMETERS
5055 <TBD>.
5056
5057RETURN VALUE
5058 OMX Error None if everything went well.
5059
5060========================================================================== */
5061OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
5062 OMX_IN OMX_HANDLETYPE hComp,
5063 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5064 OMX_IN OMX_U32 port,
5065 OMX_IN OMX_PTR appData,
5066 OMX_IN OMX_U32 bytes)
5067{
5068 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5069 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5070 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07005071 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005072 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005073#ifdef USE_ION
5074 int ion_device_fd =-1;
5075 struct ion_allocation_data ion_alloc_data;
5076 struct ion_fd_data fd_ion_data;
5077#endif
5078 if(!m_out_mem_ptr)
5079 {
5080 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
5081 drv_ctx.op_buf.actualcount,
5082 drv_ctx.op_buf.buffer_size);
5083 int nBufHdrSize = 0;
5084 int nPlatformEntrySize = 0;
5085 int nPlatformListSize = 0;
5086 int nPMEMInfoSize = 0;
5087 int pmem_fd = -1;
5088 unsigned char *pmem_baseaddress = NULL;
5089
5090 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5091 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5092 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
5093
5094 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
5095 drv_ctx.op_buf.actualcount);
5096 nBufHdrSize = drv_ctx.op_buf.actualcount *
5097 sizeof(OMX_BUFFERHEADERTYPE);
5098
5099 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5100 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5101 nPlatformListSize = drv_ctx.op_buf.actualcount *
5102 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5103 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5104 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
5105
5106 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
5107 sizeof(OMX_BUFFERHEADERTYPE),
5108 nPMEMInfoSize,
5109 nPlatformListSize);
5110 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
5111 drv_ctx.op_buf.actualcount);
5112#ifdef USE_ION
5113 ion_device_fd = alloc_map_ion_memory(
5114 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5115 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07005116 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005117 if (ion_device_fd < 0) {
5118 return OMX_ErrorInsufficientResources;
5119 }
5120 pmem_fd = fd_ion_data.fd;
5121#else
5122 pmem_fd = open (MEM_DEVICE,O_RDWR);
5123
5124 if (pmem_fd < 0)
5125 {
5126 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5127 drv_ctx.op_buf.buffer_size);
5128 return OMX_ErrorInsufficientResources;
5129 }
5130
5131 if(pmem_fd == 0)
5132 {
5133 pmem_fd = open (MEM_DEVICE,O_RDWR);
5134
5135 if (pmem_fd < 0)
5136 {
5137 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5138 drv_ctx.op_buf.buffer_size);
5139 return OMX_ErrorInsufficientResources;
5140 }
5141 }
5142
5143 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5144 drv_ctx.op_buf.actualcount,
5145 drv_ctx.op_buf.alignment))
5146 {
5147 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5148 close(pmem_fd);
5149 return OMX_ErrorInsufficientResources;
5150 }
5151#endif
5152 if (!secure_mode) {
5153 pmem_baseaddress = (unsigned char *)mmap(NULL,
5154 (drv_ctx.op_buf.buffer_size *
5155 drv_ctx.op_buf.actualcount),
5156 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5157 if (pmem_baseaddress == MAP_FAILED)
5158 {
5159 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5160 drv_ctx.op_buf.buffer_size);
5161 close(pmem_fd);
5162#ifdef USE_ION
5163 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5164#endif
5165 return OMX_ErrorInsufficientResources;
5166 }
5167 }
5168 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5169 // Alloc mem for platform specific info
5170 char *pPtr=NULL;
5171 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5172 nPMEMInfoSize,1);
5173 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5174 calloc (sizeof(struct vdec_bufferpayload),
5175 drv_ctx.op_buf.actualcount);
5176 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5177 calloc (sizeof (struct vdec_output_frameinfo),
5178 drv_ctx.op_buf.actualcount);
5179#ifdef USE_ION
5180 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5181 calloc (sizeof(struct vdec_ion),
5182 drv_ctx.op_buf.actualcount);
5183#endif
5184
5185 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5186 && drv_ctx.ptr_respbuffer)
5187 {
5188 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5189 (drv_ctx.op_buf.buffer_size *
5190 drv_ctx.op_buf.actualcount);
5191 bufHdr = m_out_mem_ptr;
5192 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5193 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5194 (((char *) m_platform_list) + nPlatformListSize);
5195 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5196 (((char *) m_platform_entry) + nPlatformEntrySize);
5197 pPlatformList = m_platform_list;
5198 pPlatformEntry = m_platform_entry;
5199 pPMEMInfo = m_pmem_info;
5200
5201 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5202
5203 // Settting the entire storage nicely
5204 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5205 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5206 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5207 {
5208 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5209 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5210 // Set the values when we determine the right HxW param
5211 bufHdr->nAllocLen = bytes;
5212 bufHdr->nFilledLen = 0;
5213 bufHdr->pAppPrivate = appData;
5214 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5215 // Platform specific PMEM Information
5216 // Initialize the Platform Entry
5217 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5218 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5219 pPlatformEntry->entry = pPMEMInfo;
5220 // Initialize the Platform List
5221 pPlatformList->nEntries = 1;
5222 pPlatformList->entryList = pPlatformEntry;
5223 // Keep pBuffer NULL till vdec is opened
5224 bufHdr->pBuffer = NULL;
5225 bufHdr->nOffset = 0;
5226
5227 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5228 pPMEMInfo->pmem_fd = 0;
5229 bufHdr->pPlatformPrivate = pPlatformList;
5230
5231 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005232 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233#ifdef USE_ION
5234 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5235 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5236 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5237#endif
5238
5239 /*Create a mapping between buffers*/
5240 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5241 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5242 &drv_ctx.ptr_outputbuffer[i];
5243 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5244 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5245 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5246
5247 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5248 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5249 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5250 // Move the buffer and buffer header pointers
5251 bufHdr++;
5252 pPMEMInfo++;
5253 pPlatformEntry++;
5254 pPlatformList++;
5255 }
5256 }
5257 else
5258 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005259 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005260 m_out_mem_ptr, pPtr);
5261 if(m_out_mem_ptr)
5262 {
5263 free(m_out_mem_ptr);
5264 m_out_mem_ptr = NULL;
5265 }
5266 if(pPtr)
5267 {
5268 free(pPtr);
5269 pPtr = NULL;
5270 }
5271 if(drv_ctx.ptr_outputbuffer)
5272 {
5273 free(drv_ctx.ptr_outputbuffer);
5274 drv_ctx.ptr_outputbuffer = NULL;
5275 }
5276 if(drv_ctx.ptr_respbuffer)
5277 {
5278 free(drv_ctx.ptr_respbuffer);
5279 drv_ctx.ptr_respbuffer = NULL;
5280 }
5281#ifdef USE_ION
5282 if (drv_ctx.op_buf_ion_info) {
5283 DEBUG_PRINT_LOW("\n Free o/p ion context");
5284 free(drv_ctx.op_buf_ion_info);
5285 drv_ctx.op_buf_ion_info = NULL;
5286 }
5287#endif
5288 eRet = OMX_ErrorInsufficientResources;
5289 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005290 if (eRet == OMX_ErrorNone)
5291 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005292 }
5293
5294 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5295 {
5296 if(BITMASK_ABSENT(&m_out_bm_count,i))
5297 {
5298 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5299 break;
5300 }
5301 }
5302
5303 if (eRet == OMX_ErrorNone)
5304 {
5305 if(i < drv_ctx.op_buf.actualcount)
5306 {
5307 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005308 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005309 int rc;
5310 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5311
5312 drv_ctx.ptr_outputbuffer[i].buffer_len =
5313 drv_ctx.op_buf.buffer_size;
5314
5315 *bufferHdr = (m_out_mem_ptr + i );
5316 if (secure_mode) {
5317 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5318 }
5319 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5320
5321 buf.index = i;
5322 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5323 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005324 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005325 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5326 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005328 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005329#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005330 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5331 plane[0].data_offset = 0;
5332 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5333 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5334 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5335 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5336#ifdef USE_ION
5337 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5338#endif
5339 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5340 plane[extra_idx].data_offset = 0;
5341 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5342 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5343 return OMX_ErrorBadParameter;
5344 }
5345 buf.m.planes = plane;
5346 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005347 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 -07005348 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5349 if (rc) {
5350 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005351 return OMX_ErrorInsufficientResources;
5352 }
5353
5354 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5355 enum v4l2_buf_type buf_type;
5356 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5357 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5358 if (rc) {
5359 return OMX_ErrorInsufficientResources;
5360 } else {
5361 streaming[CAPTURE_PORT] = true;
5362 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5363 }
5364 }
5365
5366 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5367 (*bufferHdr)->pAppPrivate = appData;
5368 BITMASK_SET(&m_out_bm_count,i);
5369 }
5370 else
5371 {
5372 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5373 eRet = OMX_ErrorInsufficientResources;
5374 }
5375 }
5376
5377 return eRet;
5378}
5379
5380
5381// AllocateBuffer -- API Call
5382/* ======================================================================
5383FUNCTION
5384 omx_vdec::AllocateBuffer
5385
5386DESCRIPTION
5387 Returns zero if all the buffers released..
5388
5389PARAMETERS
5390 None.
5391
5392RETURN VALUE
5393 true/false
5394
5395========================================================================== */
5396OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5397 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5398 OMX_IN OMX_U32 port,
5399 OMX_IN OMX_PTR appData,
5400 OMX_IN OMX_U32 bytes)
5401{
5402 unsigned i = 0;
5403 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5404
5405 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5406 if(m_state == OMX_StateInvalid)
5407 {
5408 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5409 return OMX_ErrorInvalidState;
5410 }
5411
5412 if(port == OMX_CORE_INPUT_PORT_INDEX)
5413 {
5414 if (arbitrary_bytes)
5415 {
5416 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5417 }
5418 else
5419 {
5420 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5421 }
5422 }
5423 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5424 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005425 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5426 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427 }
5428 else
5429 {
5430 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5431 eRet = OMX_ErrorBadPortIndex;
5432 }
5433 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5434 if(eRet == OMX_ErrorNone)
5435 {
5436 if(allocate_done()){
5437 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5438 {
5439 // Send the callback now
5440 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5441 post_event(OMX_CommandStateSet,OMX_StateIdle,
5442 OMX_COMPONENT_GENERATE_EVENT);
5443 }
5444 }
5445 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5446 {
5447 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5448 {
5449 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5450 post_event(OMX_CommandPortEnable,
5451 OMX_CORE_INPUT_PORT_INDEX,
5452 OMX_COMPONENT_GENERATE_EVENT);
5453 }
5454 }
5455 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5456 {
5457 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5458 {
5459 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5460 post_event(OMX_CommandPortEnable,
5461 OMX_CORE_OUTPUT_PORT_INDEX,
5462 OMX_COMPONENT_GENERATE_EVENT);
5463 }
5464 }
5465 }
5466 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5467 return eRet;
5468}
5469
5470// Free Buffer - API call
5471/* ======================================================================
5472FUNCTION
5473 omx_vdec::FreeBuffer
5474
5475DESCRIPTION
5476
5477PARAMETERS
5478 None.
5479
5480RETURN VALUE
5481 true/false
5482
5483========================================================================== */
5484OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5485 OMX_IN OMX_U32 port,
5486 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5487{
5488 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5489 unsigned int nPortIndex;
5490 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5491
5492 if(m_state == OMX_StateIdle &&
5493 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5494 {
5495 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5496 }
5497 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5498 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5499 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005500 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005501 }
Arun Menon9f098152013-05-08 13:53:54 -07005502 else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5503 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5504 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5505 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)))
5506 {
5507 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
5508 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005509 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5510 {
5511 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5512 post_event(OMX_EventError,
5513 OMX_ErrorPortUnpopulated,
5514 OMX_COMPONENT_GENERATE_EVENT);
5515
5516 return OMX_ErrorIncorrectStateOperation;
5517 }
5518 else if (m_state != OMX_StateInvalid)
5519 {
5520 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5521 post_event(OMX_EventError,
5522 OMX_ErrorPortUnpopulated,
5523 OMX_COMPONENT_GENERATE_EVENT);
5524 }
5525
5526 if(port == OMX_CORE_INPUT_PORT_INDEX)
5527 {
5528 /*Check if arbitrary bytes*/
5529 if(!arbitrary_bytes && !input_use_buffer)
5530 nPortIndex = buffer - m_inp_mem_ptr;
5531 else
5532 nPortIndex = buffer - m_inp_heap_ptr;
5533
5534 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5535 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5536 {
5537 // Clear the bit associated with it.
5538 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5539 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5540 if (input_use_buffer == true)
5541 {
5542
5543 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5544 if(m_phdr_pmem_ptr)
5545 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5546 }
5547 else
5548 {
5549 if (arbitrary_bytes)
5550 {
5551 if(m_phdr_pmem_ptr)
5552 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5553 else
5554 free_input_buffer(nPortIndex,NULL);
5555 }
5556 else
5557 free_input_buffer(buffer);
5558 }
5559 m_inp_bPopulated = OMX_FALSE;
5560 /*Free the Buffer Header*/
5561 if (release_input_done())
5562 {
5563 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5564 free_input_buffer_header();
5565 }
5566 }
5567 else
5568 {
5569 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5570 eRet = OMX_ErrorBadPortIndex;
5571 }
5572
5573 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5574 && release_input_done())
5575 {
5576 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5577 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5578 post_event(OMX_CommandPortDisable,
5579 OMX_CORE_INPUT_PORT_INDEX,
5580 OMX_COMPONENT_GENERATE_EVENT);
5581 }
5582 }
5583 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5584 {
5585 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005586 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005587 if(nPortIndex < drv_ctx.op_buf.actualcount)
5588 {
5589 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5590 // Clear the bit associated with it.
5591 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5592 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005593 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005594
5595 if (release_output_done())
5596 {
5597 free_output_buffer_header();
5598 }
5599 }
5600 else
5601 {
5602 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5603 eRet = OMX_ErrorBadPortIndex;
5604 }
5605 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5606 && release_output_done())
5607 {
5608 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5609
5610 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5611 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5612#ifdef _ANDROID_ICS_
5613 if (m_enable_android_native_buffers)
5614 {
5615 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5616 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5617 }
5618#endif
5619
5620 post_event(OMX_CommandPortDisable,
5621 OMX_CORE_OUTPUT_PORT_INDEX,
5622 OMX_COMPONENT_GENERATE_EVENT);
5623 }
5624 }
5625 else
5626 {
5627 eRet = OMX_ErrorBadPortIndex;
5628 }
5629 if((eRet == OMX_ErrorNone) &&
5630 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5631 {
5632 if(release_done())
5633 {
5634 // Send the callback now
5635 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5636 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5637 OMX_COMPONENT_GENERATE_EVENT);
5638 }
5639 }
5640 return eRet;
5641}
5642
5643
5644/* ======================================================================
5645FUNCTION
5646 omx_vdec::EmptyThisBuffer
5647
5648DESCRIPTION
5649 This routine is used to push the encoded video frames to
5650 the video decoder.
5651
5652PARAMETERS
5653 None.
5654
5655RETURN VALUE
5656 OMX Error None if everything went successful.
5657
5658========================================================================== */
5659OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5660 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5661{
5662 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5663 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5664
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005665 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
5666 {
5667 codec_config_flag = true;
5668 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5669 }
5670 else
5671 {
5672 codec_config_flag = false;
5673 }
5674
Shalaj Jain273b3e02012-06-22 19:08:03 -07005675 if(m_state == OMX_StateInvalid)
5676 {
5677 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5678 return OMX_ErrorInvalidState;
5679 }
5680
5681 if (buffer == NULL)
5682 {
5683 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5684 return OMX_ErrorBadParameter;
5685 }
5686
5687 if (!m_inp_bEnabled)
5688 {
5689 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5690 return OMX_ErrorIncorrectStateOperation;
5691 }
5692
5693 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5694 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005695 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005696 return OMX_ErrorBadPortIndex;
5697 }
5698
5699#ifdef _ANDROID_
5700 if(iDivXDrmDecrypt)
5701 {
5702 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5703 if(drmErr != OMX_ErrorNone) {
5704 // this error can be ignored
5705 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5706 }
5707 }
5708#endif //_ANDROID_
5709 if (perf_flag)
5710 {
5711 if (!latency)
5712 {
5713 dec_time.stop();
5714 latency = dec_time.processing_time_us();
5715 dec_time.start();
5716 }
5717 }
5718
5719 if (arbitrary_bytes)
5720 {
5721 nBufferIndex = buffer - m_inp_heap_ptr;
5722 }
5723 else
5724 {
5725 if (input_use_buffer == true)
5726 {
5727 nBufferIndex = buffer - m_inp_heap_ptr;
5728 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5729 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5730 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5731 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005732 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 -07005733 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5734 }
5735 else{
5736 nBufferIndex = buffer - m_inp_mem_ptr;
5737 }
5738 }
5739
5740 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5741 {
5742 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5743 return OMX_ErrorBadParameter;
5744 }
5745
5746 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5747 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5748 if (arbitrary_bytes)
5749 {
5750 post_event ((unsigned)hComp,(unsigned)buffer,
5751 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5752 }
5753 else
5754 {
5755 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5756 set_frame_rate(buffer->nTimeStamp);
5757 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5758 }
5759 return OMX_ErrorNone;
5760}
5761
5762/* ======================================================================
5763FUNCTION
5764 omx_vdec::empty_this_buffer_proxy
5765
5766DESCRIPTION
5767 This routine is used to push the encoded video frames to
5768 the video decoder.
5769
5770PARAMETERS
5771 None.
5772
5773RETURN VALUE
5774 OMX Error None if everything went successful.
5775
5776========================================================================== */
5777OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5778 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5779{
5780 int push_cnt = 0,i=0;
5781 unsigned nPortIndex = 0;
5782 OMX_ERRORTYPE ret = OMX_ErrorNone;
5783 struct vdec_input_frameinfo frameinfo;
5784 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785 struct vdec_seqheader seq_header;
5786 bool port_setting_changed = true;
5787 bool not_coded_vop = false;
5788
5789 /*Should we generate a Aync error event*/
5790 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5791 {
5792 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5793 return OMX_ErrorBadParameter;
5794 }
5795
5796 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5797
5798 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5799 {
5800 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5801 nPortIndex);
5802 return OMX_ErrorBadParameter;
5803 }
5804
5805 pending_input_buffers++;
5806
5807 /* return zero length and not an EOS buffer */
5808 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5809 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5810 {
5811 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5812 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5813 OMX_COMPONENT_GENERATE_EBD);
5814 return OMX_ErrorNone;
5815 }
5816
5817
5818 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5819 mp4StreamType psBits;
5820 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5821 psBits.numBytes = buffer->nFilledLen;
5822 mp4_headerparser.parseHeader(&psBits);
5823 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5824 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5825 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005826 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005827 buffer->nFilledLen,frame_count);
5828 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5829 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5830 not_coded_vop = false;
5831 buffer->nFilledLen = 0;
5832 }
5833 }
5834 }
5835
5836 if(input_flush_progress == true
5837
5838 || not_coded_vop
5839
5840 )
5841 {
5842 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5843 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5844 OMX_COMPONENT_GENERATE_EBD);
5845 return OMX_ErrorNone;
5846 }
5847
5848 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5849
5850 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5851 {
5852 return OMX_ErrorBadParameter;
5853 }
5854
5855 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5856 /*for use buffer we need to memcpy the data*/
5857 temp_buffer->buffer_len = buffer->nFilledLen;
5858
5859 if (input_use_buffer)
5860 {
5861 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5862 {
5863 if(arbitrary_bytes)
5864 {
5865 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5866 }
5867 else
5868 {
5869 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5870 buffer->nFilledLen);
5871 }
5872 }
5873 else
5874 {
5875 return OMX_ErrorBadParameter;
5876 }
5877
5878 }
5879
5880 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5881 frameinfo.client_data = (void *) buffer;
5882 frameinfo.datalen = temp_buffer->buffer_len;
5883 frameinfo.flags = 0;
5884 frameinfo.offset = buffer->nOffset;
5885 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5886 frameinfo.pmem_offset = temp_buffer->offset;
5887 frameinfo.timestamp = buffer->nTimeStamp;
5888 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5889 {
5890 DEBUG_PRINT_LOW("ETB: dmx enabled");
5891 if (m_demux_entries == 0)
5892 {
5893 extract_demux_addr_offsets(buffer);
5894 }
5895
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005896 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005897 handle_demux_data(buffer);
5898 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5899 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5900 }
5901 else
5902 {
5903 frameinfo.desc_addr = NULL;
5904 frameinfo.desc_size = 0;
5905 }
5906 if(!arbitrary_bytes)
5907 {
5908 frameinfo.flags |= buffer->nFlags;
5909 }
5910
5911#ifdef _ANDROID_
5912 if (m_debug_timestamp)
5913 {
5914 if(arbitrary_bytes)
5915 {
5916 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5917 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5918 }
5919 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5920 {
5921 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5922 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5923 }
5924 }
5925#endif
5926
5927#ifdef INPUT_BUFFER_LOG
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07005928 if (output_capability == V4L2_PIX_FMT_VP8) {
5929 struct vp8_ivf_frame_header{
5930 OMX_U32 framesize;
5931 OMX_U32 timestamp_lo;
5932 OMX_U32 timestamp_hi;
5933 } vp8_frame_header;
5934 vp8_frame_header.framesize = temp_buffer->buffer_len;
5935 /* Currently FW doesn't use timestamp values */
5936 vp8_frame_header.timestamp_lo = 0;
5937 vp8_frame_header.timestamp_hi = 0;
5938 if (inputBufferFile1)
5939 {
5940 fwrite((const char *)&vp8_frame_header,
5941 sizeof(vp8_frame_header),1,inputBufferFile1);
5942 fwrite((const char *)temp_buffer->bufferaddr,
5943 temp_buffer->buffer_len,1,inputBufferFile1);
5944 }
5945 } else {
5946 if (inputBufferFile1)
5947 {
5948 fwrite((const char *)temp_buffer->bufferaddr,
5949 temp_buffer->buffer_len,1,inputBufferFile1);
5950 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005951 }
5952#endif
5953
5954 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5955 {
5956 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5957 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5958 }
5959
5960 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5961 {
5962 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5963 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5964 h264_scratch.nFilledLen = 0;
5965 nal_count = 0;
5966 look_ahead_nal = false;
5967 frame_count = 0;
5968 if (m_frame_parser.mutils)
5969 m_frame_parser.mutils->initialize_frame_checking_environment();
5970 m_frame_parser.flush();
5971 h264_last_au_ts = LLONG_MAX;
5972 h264_last_au_flags = 0;
5973 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5974 m_demux_entries = 0;
5975 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005976 struct v4l2_buffer buf;
5977 struct v4l2_plane plane;
5978 memset( (void *)&buf, 0, sizeof(buf));
5979 memset( (void *)&plane, 0, sizeof(plane));
5980 int rc;
5981 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005982 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5983 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005984 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005985 }
5986 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5987 buf.index = nPortIndex;
5988 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5989 buf.memory = V4L2_MEMORY_USERPTR;
5990 plane.bytesused = temp_buffer->buffer_len;
5991 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005992 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5993 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005994 plane.reserved[0] = temp_buffer->pmem_fd;
5995 plane.reserved[1] = temp_buffer->offset;
5996 plane.data_offset = 0;
5997 buf.m.planes = &plane;
5998 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005999 if (frameinfo.timestamp >= LLONG_MAX) {
6000 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
6001 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006002 //assumption is that timestamp is in milliseconds
6003 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
6004 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07006005 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
6006
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07006008 if(rc)
6009 {
6010 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
6011 return OMX_ErrorHardware;
6012 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006013 if(!streaming[OUTPUT_PORT])
6014 {
6015 enum v4l2_buf_type buf_type;
6016 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07006017
Shalaj Jain273b3e02012-06-22 19:08:03 -07006018 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6019 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
6020 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
6021 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07006022 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006023 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006024 } else{
Ashray Kulkarni46373df2012-06-05 20:11:31 -07006025 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Arun Menon4d7d3b52013-05-23 11:43:50 -07006026 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
6027 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
Praneeth Paladugub227af72013-05-08 01:33:06 -07006028 OMX_COMPONENT_GENERATE_EBD);
Praneeth Paladugub227af72013-05-08 01:33:06 -07006029 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030 }
6031}
6032 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
6033 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
6034 time_stamp_dts.insert_timestamp(buffer);
6035
6036 return ret;
6037}
6038
6039/* ======================================================================
6040FUNCTION
6041 omx_vdec::FillThisBuffer
6042
6043DESCRIPTION
6044 IL client uses this method to release the frame buffer
6045 after displaying them.
6046
6047PARAMETERS
6048 None.
6049
6050RETURN VALUE
6051 true/false
6052
6053========================================================================== */
6054OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
6055 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
6056{
6057
6058 if(m_state == OMX_StateInvalid)
6059 {
6060 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
6061 return OMX_ErrorInvalidState;
6062 }
6063
6064 if (!m_out_bEnabled)
6065 {
6066 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
6067 return OMX_ErrorIncorrectStateOperation;
6068 }
6069
Vinay Kaliada4f4422013-01-09 10:45:03 -08006070 if (buffer == NULL ||
6071 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072 {
6073 return OMX_ErrorBadParameter;
6074 }
6075
6076 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
6077 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08006078 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079 return OMX_ErrorBadPortIndex;
6080 }
6081
6082 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08006083 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006084 return OMX_ErrorNone;
6085}
6086/* ======================================================================
6087FUNCTION
6088 omx_vdec::fill_this_buffer_proxy
6089
6090DESCRIPTION
6091 IL client uses this method to release the frame buffer
6092 after displaying them.
6093
6094PARAMETERS
6095 None.
6096
6097RETURN VALUE
6098 true/false
6099
6100========================================================================== */
6101OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
6102 OMX_IN OMX_HANDLETYPE hComp,
6103 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
6104{
6105 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6107 unsigned nPortIndex = 0;
6108 struct vdec_fillbuffer_cmd fillbuffer;
6109 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6110 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
6111
Vinay Kaliada4f4422013-01-09 10:45:03 -08006112 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113
Vinay Kaliada4f4422013-01-09 10:45:03 -08006114 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006115 return OMX_ErrorBadParameter;
6116
6117 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
6118 bufferAdd, bufferAdd->pBuffer);
6119 /*Return back the output buffer to client*/
6120 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
6121 {
6122 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
6123 buffer->nFilledLen = 0;
6124 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6125 return OMX_ErrorNone;
6126 }
6127 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006128 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006129 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6130 if (ptr_respbuffer)
6131 {
6132 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6133 }
6134
6135 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
6136 {
6137 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6138 buffer->nFilledLen = 0;
6139 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6140 pending_output_buffers--;
6141 return OMX_ErrorBadParameter;
6142 }
6143
Shalaj Jain286b0062013-02-21 20:35:48 -08006144 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07006145 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08006146 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147
6148#ifdef _ANDROID_ICS_
6149 if (m_enable_android_native_buffers)
6150 {
6151 // Acquire a write lock on this buffer.
6152 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
6153 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
6154 DEBUG_PRINT_ERROR("Failed to acquire genlock");
6155 buffer->nFilledLen = 0;
6156 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6157 pending_output_buffers--;
6158 return OMX_ErrorInsufficientResources;
6159 } else {
6160 native_buffer[buffer - m_out_mem_ptr].inuse = true;
6161 }
6162 }
6163#endif
6164 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08006165 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006166 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08006167 memset( (void *)&buf, 0, sizeof(buf));
6168 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006169 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006170
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006171 buf.index = nPortIndex;
6172 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6173 buf.memory = V4L2_MEMORY_USERPTR;
6174 plane[0].bytesused = buffer->nFilledLen;
6175 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08006176 plane[0].m.userptr =
6177 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6178 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006179 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6180 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6181 plane[0].data_offset = 0;
6182 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6183 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6184 plane[extra_idx].bytesused = 0;
6185 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6186 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
6187#ifdef USE_ION
6188 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
6189#endif
6190 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6191 plane[extra_idx].data_offset = 0;
6192 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6193 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6194 return OMX_ErrorBadParameter;
6195 }
6196 buf.m.planes = plane;
6197 buf.length = drv_ctx.num_planes;
6198 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6199 if (rc) {
6200 /*TODO: How to handle this case */
6201 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006203//#ifdef _ANDROID_ICS_
6204 // if (m_enable_android_native_buffers)
6205 // {
6206 // Unlock the buffer
6207 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6208 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6209 // return OMX_ErrorInsufficientResources;
6210 /// } else {
6211 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6212 // }
6213 // }
6214//#endif
6215 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6216 // pending_output_buffers--;
6217 // return OMX_ErrorBadParameter;
6218 //}
6219 return OMX_ErrorNone;
6220}
6221
6222/* ======================================================================
6223FUNCTION
6224 omx_vdec::SetCallbacks
6225
6226DESCRIPTION
6227 Set the callbacks.
6228
6229PARAMETERS
6230 None.
6231
6232RETURN VALUE
6233 OMX Error None if everything successful.
6234
6235========================================================================== */
6236OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6237 OMX_IN OMX_CALLBACKTYPE* callbacks,
6238 OMX_IN OMX_PTR appData)
6239{
6240
6241 m_cb = *callbacks;
6242 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6243 m_cb.EventHandler,m_cb.FillBufferDone);
6244 m_app_data = appData;
6245 return OMX_ErrorNotImplemented;
6246}
6247
6248/* ======================================================================
6249FUNCTION
6250 omx_vdec::ComponentDeInit
6251
6252DESCRIPTION
6253 Destroys the component and release memory allocated to the heap.
6254
6255PARAMETERS
6256 <TBD>.
6257
6258RETURN VALUE
6259 OMX Error None if everything successful.
6260
6261========================================================================== */
6262OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6263{
6264#ifdef _ANDROID_
6265 if(iDivXDrmDecrypt)
6266 {
6267 delete iDivXDrmDecrypt;
6268 iDivXDrmDecrypt=NULL;
6269 }
6270#endif //_ANDROID_
6271
Shalaj Jain286b0062013-02-21 20:35:48 -08006272 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006273 if (OMX_StateLoaded != m_state)
6274 {
6275 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6276 m_state);
6277 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6278 }
6279 else
6280 {
6281 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6282 }
6283
6284 /*Check if the output buffers have to be cleaned up*/
6285 if(m_out_mem_ptr)
6286 {
6287 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006288 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006289 {
6290 free_output_buffer (&m_out_mem_ptr[i]);
6291#ifdef _ANDROID_ICS_
6292 if (m_enable_android_native_buffers)
6293 {
6294 if (native_buffer[i].inuse)
6295 {
6296 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6297 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6298 }
6299 native_buffer[i].inuse = false;
6300 }
6301 }
6302#endif
6303 }
6304#ifdef _ANDROID_ICS_
6305 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6306#endif
6307 }
6308
6309 /*Check if the input buffers have to be cleaned up*/
6310 if(m_inp_mem_ptr || m_inp_heap_ptr)
6311 {
6312 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006313 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006314 {
6315 if (m_inp_mem_ptr)
6316 free_input_buffer (i,&m_inp_mem_ptr[i]);
6317 else
6318 free_input_buffer (i,NULL);
6319 }
6320 }
6321 free_input_buffer_header();
6322 free_output_buffer_header();
6323 if(h264_scratch.pBuffer)
6324 {
6325 free(h264_scratch.pBuffer);
6326 h264_scratch.pBuffer = NULL;
6327 }
6328
6329 if (h264_parser)
6330 {
6331 delete h264_parser;
6332 h264_parser = NULL;
6333 }
6334
6335 if(m_platform_list)
6336 {
6337 free(m_platform_list);
6338 m_platform_list = NULL;
6339 }
6340 if(m_vendor_config.pData)
6341 {
6342 free(m_vendor_config.pData);
6343 m_vendor_config.pData = NULL;
6344 }
6345
6346 // Reset counters in mesg queues
6347 m_ftb_q.m_size=0;
6348 m_cmd_q.m_size=0;
6349 m_etb_q.m_size=0;
6350 m_ftb_q.m_read = m_ftb_q.m_write =0;
6351 m_cmd_q.m_read = m_cmd_q.m_write =0;
6352 m_etb_q.m_read = m_etb_q.m_write =0;
6353#ifdef _ANDROID_
6354 if (m_debug_timestamp)
6355 {
6356 m_timestamp_list.reset_ts_list();
6357 }
6358#endif
6359
6360 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6361 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6362 // NULL);
6363 DEBUG_PRINT_HIGH("\n Close the driver instance");
6364
6365#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006366 if (inputBufferFile1)
6367 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006368#endif
6369#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006370 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006371 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006372#endif
6373#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006374 if (outputExtradataFile)
6375 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006376#endif
6377 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6378 return OMX_ErrorNone;
6379}
6380
6381/* ======================================================================
6382FUNCTION
6383 omx_vdec::UseEGLImage
6384
6385DESCRIPTION
6386 OMX Use EGL Image method implementation <TBD>.
6387
6388PARAMETERS
6389 <TBD>.
6390
6391RETURN VALUE
6392 Not Implemented error.
6393
6394========================================================================== */
6395OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6396 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6397 OMX_IN OMX_U32 port,
6398 OMX_IN OMX_PTR appData,
6399 OMX_IN void* eglImage)
6400{
6401 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6402 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6403 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6404
6405#ifdef USE_EGL_IMAGE_GPU
6406 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6407 EGLint fd = -1, offset = 0,pmemPtr = 0;
6408#else
6409 int fd = -1, offset = 0;
6410#endif
6411 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6412 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6413 DEBUG_PRINT_ERROR("\n ");
6414 }
6415#ifdef USE_EGL_IMAGE_GPU
6416 if(m_display_id == NULL) {
6417 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6418 return OMX_ErrorInsufficientResources;
6419 }
6420 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6421 eglGetProcAddress("eglQueryImageKHR");
6422 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6423 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6424 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6425#else //with OMX test app
6426 struct temp_egl {
6427 int pmem_fd;
6428 int offset;
6429 };
6430 struct temp_egl *temp_egl_id = NULL;
6431 void * pmemPtr = (void *) eglImage;
6432 temp_egl_id = (struct temp_egl *)eglImage;
6433 if (temp_egl_id != NULL)
6434 {
6435 fd = temp_egl_id->pmem_fd;
6436 offset = temp_egl_id->offset;
6437 }
6438#endif
6439 if (fd < 0) {
6440 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6441 return OMX_ErrorInsufficientResources;
6442 }
6443 pmem_info.pmem_fd = (OMX_U32) fd;
6444 pmem_info.offset = (OMX_U32) offset;
6445 pmem_entry.entry = (void *) &pmem_info;
6446 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6447 pmem_list.entryList = &pmem_entry;
6448 pmem_list.nEntries = 1;
6449 ouput_egl_buffers = true;
6450 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6451 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6452 (OMX_U8 *)pmemPtr)) {
6453 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6454 return OMX_ErrorInsufficientResources;
6455 }
6456 return OMX_ErrorNone;
6457}
6458
6459/* ======================================================================
6460FUNCTION
6461 omx_vdec::ComponentRoleEnum
6462
6463DESCRIPTION
6464 OMX Component Role Enum method implementation.
6465
6466PARAMETERS
6467 <TBD>.
6468
6469RETURN VALUE
6470 OMX Error None if everything is successful.
6471========================================================================== */
6472OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6473 OMX_OUT OMX_U8* role,
6474 OMX_IN OMX_U32 index)
6475{
6476 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6477
6478 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6479 {
6480 if((0 == index) && role)
6481 {
6482 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6483 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6484 }
6485 else
6486 {
6487 eRet = OMX_ErrorNoMore;
6488 }
6489 }
6490 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6491 {
6492 if((0 == index) && role)
6493 {
6494 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6495 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6496 }
6497 else
6498 {
6499 eRet = OMX_ErrorNoMore;
6500 }
6501 }
6502 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6503 {
6504 if((0 == index) && role)
6505 {
6506 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6507 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6508 }
6509 else
6510 {
6511 DEBUG_PRINT_LOW("\n No more roles \n");
6512 eRet = OMX_ErrorNoMore;
6513 }
6514 }
6515
6516 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6517 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6518 )
6519
6520 {
6521 if((0 == index) && role)
6522 {
6523 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6524 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6525 }
6526 else
6527 {
6528 DEBUG_PRINT_LOW("\n No more roles \n");
6529 eRet = OMX_ErrorNoMore;
6530 }
6531 }
6532 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6533 {
6534 if((0 == index) && role)
6535 {
6536 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6537 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6538 }
6539 else
6540 {
6541 DEBUG_PRINT_LOW("\n No more roles \n");
6542 eRet = OMX_ErrorNoMore;
6543 }
6544 }
6545 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6546 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6547 )
6548 {
6549 if((0 == index) && role)
6550 {
6551 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6552 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6553 }
6554 else
6555 {
6556 DEBUG_PRINT_LOW("\n No more roles \n");
6557 eRet = OMX_ErrorNoMore;
6558 }
6559 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006560 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6561 {
6562 if((0 == index) && role)
6563 {
6564 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6565 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6566 }
6567 else
6568 {
6569 DEBUG_PRINT_LOW("\n No more roles \n");
6570 eRet = OMX_ErrorNoMore;
6571 }
6572 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006573 else
6574 {
6575 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6576 eRet = OMX_ErrorInvalidComponentName;
6577 }
6578 return eRet;
6579}
6580
6581
6582
6583
6584/* ======================================================================
6585FUNCTION
6586 omx_vdec::AllocateDone
6587
6588DESCRIPTION
6589 Checks if entire buffer pool is allocated by IL Client or not.
6590 Need this to move to IDLE state.
6591
6592PARAMETERS
6593 None.
6594
6595RETURN VALUE
6596 true/false.
6597
6598========================================================================== */
6599bool omx_vdec::allocate_done(void)
6600{
6601 bool bRet = false;
6602 bool bRet_In = false;
6603 bool bRet_Out = false;
6604
6605 bRet_In = allocate_input_done();
6606 bRet_Out = allocate_output_done();
6607
6608 if(bRet_In && bRet_Out)
6609 {
6610 bRet = true;
6611 }
6612
6613 return bRet;
6614}
6615/* ======================================================================
6616FUNCTION
6617 omx_vdec::AllocateInputDone
6618
6619DESCRIPTION
6620 Checks if I/P buffer pool is allocated by IL Client or not.
6621
6622PARAMETERS
6623 None.
6624
6625RETURN VALUE
6626 true/false.
6627
6628========================================================================== */
6629bool omx_vdec::allocate_input_done(void)
6630{
6631 bool bRet = false;
6632 unsigned i=0;
6633
6634 if (m_inp_mem_ptr == NULL)
6635 {
6636 return bRet;
6637 }
6638 if(m_inp_mem_ptr )
6639 {
6640 for(;i<drv_ctx.ip_buf.actualcount;i++)
6641 {
6642 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6643 {
6644 break;
6645 }
6646 }
6647 }
6648 if(i == drv_ctx.ip_buf.actualcount)
6649 {
6650 bRet = true;
6651 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6652 }
6653 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6654 {
6655 m_inp_bPopulated = OMX_TRUE;
6656 }
6657 return bRet;
6658}
6659/* ======================================================================
6660FUNCTION
6661 omx_vdec::AllocateOutputDone
6662
6663DESCRIPTION
6664 Checks if entire O/P buffer pool is allocated by IL Client or not.
6665
6666PARAMETERS
6667 None.
6668
6669RETURN VALUE
6670 true/false.
6671
6672========================================================================== */
6673bool omx_vdec::allocate_output_done(void)
6674{
6675 bool bRet = false;
6676 unsigned j=0;
6677
6678 if (m_out_mem_ptr == NULL)
6679 {
6680 return bRet;
6681 }
6682
6683 if (m_out_mem_ptr)
6684 {
6685 for(;j < drv_ctx.op_buf.actualcount;j++)
6686 {
6687 if(BITMASK_ABSENT(&m_out_bm_count,j))
6688 {
6689 break;
6690 }
6691 }
6692 }
6693
6694 if(j == drv_ctx.op_buf.actualcount)
6695 {
6696 bRet = true;
6697 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6698 if(m_out_bEnabled)
6699 m_out_bPopulated = OMX_TRUE;
6700 }
6701
6702 return bRet;
6703}
6704
6705/* ======================================================================
6706FUNCTION
6707 omx_vdec::ReleaseDone
6708
6709DESCRIPTION
6710 Checks if IL client has released all the buffers.
6711
6712PARAMETERS
6713 None.
6714
6715RETURN VALUE
6716 true/false
6717
6718========================================================================== */
6719bool omx_vdec::release_done(void)
6720{
6721 bool bRet = false;
6722
6723 if(release_input_done())
6724 {
6725 if(release_output_done())
6726 {
6727 bRet = true;
6728 }
6729 }
6730 return bRet;
6731}
6732
6733
6734/* ======================================================================
6735FUNCTION
6736 omx_vdec::ReleaseOutputDone
6737
6738DESCRIPTION
6739 Checks if IL client has released all the buffers.
6740
6741PARAMETERS
6742 None.
6743
6744RETURN VALUE
6745 true/false
6746
6747========================================================================== */
6748bool omx_vdec::release_output_done(void)
6749{
6750 bool bRet = false;
6751 unsigned i=0,j=0;
6752
6753 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6754 if(m_out_mem_ptr)
6755 {
6756 for(;j < drv_ctx.op_buf.actualcount ; j++)
6757 {
6758 if(BITMASK_PRESENT(&m_out_bm_count,j))
6759 {
6760 break;
6761 }
6762 }
6763 if(j == drv_ctx.op_buf.actualcount)
6764 {
6765 m_out_bm_count = 0;
6766 bRet = true;
6767 }
6768 }
6769 else
6770 {
6771 m_out_bm_count = 0;
6772 bRet = true;
6773 }
6774 return bRet;
6775}
6776/* ======================================================================
6777FUNCTION
6778 omx_vdec::ReleaseInputDone
6779
6780DESCRIPTION
6781 Checks if IL client has released all the buffers.
6782
6783PARAMETERS
6784 None.
6785
6786RETURN VALUE
6787 true/false
6788
6789========================================================================== */
6790bool omx_vdec::release_input_done(void)
6791{
6792 bool bRet = false;
6793 unsigned i=0,j=0;
6794
6795 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6796 if(m_inp_mem_ptr)
6797 {
6798 for(;j<drv_ctx.ip_buf.actualcount;j++)
6799 {
6800 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6801 {
6802 break;
6803 }
6804 }
6805 if(j==drv_ctx.ip_buf.actualcount)
6806 {
6807 bRet = true;
6808 }
6809 }
6810 else
6811 {
6812 bRet = true;
6813 }
6814 return bRet;
6815}
6816
6817OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6818 OMX_BUFFERHEADERTYPE * buffer)
6819{
6820 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6821 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6822 {
6823 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6824 return OMX_ErrorBadParameter;
6825 }
6826 else if (output_flush_progress)
6827 {
6828 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6829 buffer->nFilledLen = 0;
6830 buffer->nTimeStamp = 0;
6831 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6832 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6833 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6834 }
6835
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006836 if (m_debug_extradata)
6837 {
6838 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
6839 {
6840 DEBUG_PRINT_HIGH("\n");
6841 DEBUG_PRINT_HIGH("***************************************************\n");
6842 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6843 DEBUG_PRINT_HIGH("***************************************************\n");
6844 }
6845
6846 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT)
6847 {
6848 DEBUG_PRINT_HIGH("\n");
6849 DEBUG_PRINT_HIGH("***************************************************\n");
6850 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6851 DEBUG_PRINT_HIGH("***************************************************\n");
6852 }
6853 }
6854
6855
Shalaj Jain273b3e02012-06-22 19:08:03 -07006856 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6857 buffer, buffer->pBuffer);
6858 pending_output_buffers --;
6859
6860 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6861 {
6862 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6863 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006864 post_event((unsigned)NULL, (unsigned)NULL,
6865 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006866
6867 if (psource_frame)
6868 {
6869 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6870 psource_frame = NULL;
6871 }
6872 if (pdest_frame)
6873 {
6874 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006875 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6876 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006877 pdest_frame = NULL;
6878 }
6879 }
6880
6881 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6882#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006883 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006884 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006885 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006886 int stride = drv_ctx.video_resolution.stride;
6887 int scanlines = drv_ctx.video_resolution.scan_lines;
6888 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006889 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006890 int bytes_written = 0;
6891 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6892 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6893 temp += stride;
6894 }
6895 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006896 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006897 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6898 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6899 temp += stride_c;
6900 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006901 }
6902#endif
6903
6904 /* For use buffer we need to copy the data */
6905 if (!output_flush_progress)
6906 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006907 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006908 bool is_duplicate_ts_valid = true;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006909 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
6910
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006911 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6912 output_capability == V4L2_PIX_FMT_DIVX ||
6913 output_capability == V4L2_PIX_FMT_DIVX_311)
6914 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006915
6916 if (buffer->nFilledLen > 0) {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006917 time_stamp_dts.get_next_timestamp(buffer,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006918 is_interlaced && is_duplicate_ts_valid);
6919 } else {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006920 m_inp_err_count++;
6921 time_stamp_dts.remove_time_stamp(
6922 buffer->nTimeStamp,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006923 is_interlaced && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006924 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006925
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006926 if (m_debug_timestamp)
6927 {
6928 {
6929 OMX_TICKS expected_ts = 0;
6930 m_timestamp_list.pop_min_ts(expected_ts);
Arun Menoncca4b1f2013-06-05 19:27:15 -07006931 if (is_interlaced && is_duplicate_ts_valid) {
6932 m_timestamp_list.pop_min_ts(expected_ts);
6933 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006934 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6935 buffer->nTimeStamp, expected_ts);
6936
6937 if (buffer->nTimeStamp != expected_ts)
6938 {
6939 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6940 }
6941 }
6942 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006943 }
6944 if (m_cb.FillBufferDone)
6945 {
6946 if (buffer->nFilledLen > 0)
6947 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006948 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006949 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006950 set_frame_rate(buffer->nTimeStamp);
6951 else if (arbitrary_bytes)
6952 adjust_timestamp(buffer->nTimeStamp);
6953 if (perf_flag)
6954 {
6955 if (!proc_frms)
6956 {
6957 dec_time.stop();
6958 latency = dec_time.processing_time_us() - latency;
6959 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6960 dec_time.start();
6961 fps_metrics.start();
6962 }
6963 proc_frms++;
6964 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6965 {
6966 OMX_U64 proc_time = 0;
6967 fps_metrics.stop();
6968 proc_time = fps_metrics.processing_time_us();
6969 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6970 proc_frms, (float)proc_time / 1e6,
6971 (float)(1e6 * proc_frms) / proc_time);
6972 proc_frms = 0;
6973 }
6974 }
6975
6976#ifdef OUTPUT_EXTRADATA_LOG
6977 if (outputExtradataFile)
6978 {
6979
6980 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6981 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6982 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6983 buffer->nFilledLen + 3)&(~3));
6984 while(p_extra &&
6985 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6986 {
6987 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6988 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6989 if (p_extra->eType == OMX_ExtraDataNone)
6990 {
6991 break;
6992 }
6993 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6994 }
6995 }
6996#endif
6997 }
6998 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6999 prev_ts = LLONG_MAX;
7000 rst_prev_ts = true;
7001 }
7002
7003 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7004 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
7005 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007006 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007007#ifdef _ANDROID_ICS_
7008 if (m_enable_android_native_buffers)
7009 {
7010 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
7011 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
7012 DEBUG_PRINT_ERROR("Unlocking genlock failed");
7013 return OMX_ErrorInsufficientResources;
7014 }
7015 else {
7016 native_buffer[buffer - m_out_mem_ptr].inuse = false;
7017 }
7018 }
7019 }
7020#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08007021 OMX_BUFFERHEADERTYPE *il_buffer;
7022 il_buffer = client_buffers.get_il_buf_hdr(buffer);
7023 if (il_buffer)
7024 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
7025 else {
7026 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
7027 return OMX_ErrorBadParameter;
7028 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007029 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007030 }
7031 else
7032 {
7033 return OMX_ErrorBadParameter;
7034 }
7035
7036 return OMX_ErrorNone;
7037}
7038
7039OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
7040 OMX_BUFFERHEADERTYPE* buffer)
7041{
7042
7043 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
7044 {
7045 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
7046 return OMX_ErrorBadParameter;
7047 }
7048
7049 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
7050 buffer, buffer->pBuffer);
7051 pending_input_buffers--;
7052
7053 if (arbitrary_bytes)
7054 {
7055 if (pdest_frame == NULL && input_flush_progress == false)
7056 {
7057 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
7058 pdest_frame = buffer;
7059 buffer->nFilledLen = 0;
7060 buffer->nTimeStamp = LLONG_MAX;
7061 push_input_buffer (hComp);
7062 }
7063 else
7064 {
7065 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
7066 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08007067 if (!m_input_free_q.insert_entry((unsigned)buffer,
7068 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007069 {
7070 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
7071 }
7072 }
7073 }
7074 else if(m_cb.EmptyBufferDone)
7075 {
7076 buffer->nFilledLen = 0;
7077 if (input_use_buffer == true){
7078 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
7079 }
7080 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
7081 }
7082 return OMX_ErrorNone;
7083}
7084
Shalaj Jain273b3e02012-06-22 19:08:03 -07007085int omx_vdec::async_message_process (void *context, void* message)
7086{
7087 omx_vdec* omx = NULL;
7088 struct vdec_msginfo *vdec_msg = NULL;
7089 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08007090 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007091 struct vdec_output_frameinfo *output_respbuf = NULL;
7092 int rc=1;
7093 if (context == NULL || message == NULL)
7094 {
7095 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
7096 return -1;
7097 }
7098 vdec_msg = (struct vdec_msginfo *)message;
7099
7100 omx = reinterpret_cast<omx_vdec*>(context);
7101
Shalaj Jain273b3e02012-06-22 19:08:03 -07007102 switch (vdec_msg->msgcode)
7103 {
7104
7105 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08007106 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007107 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7108 break;
7109
7110 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007111 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007112 OMX_COMPONENT_GENERATE_START_DONE);
7113 break;
7114
7115 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007116 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007117 OMX_COMPONENT_GENERATE_STOP_DONE);
7118 break;
7119
7120 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007121 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007122 OMX_COMPONENT_GENERATE_RESUME_DONE);
7123 break;
7124
7125 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007126 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007127 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7128 break;
7129
7130 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007131 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007132 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7133 break;
7134 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007135 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007136 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7137 break;
7138 case VDEC_MSG_RESP_INPUT_FLUSHED:
7139 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7140
Shalaj Jain286b0062013-02-21 20:35:48 -08007141 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7142 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07007143
7144 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7145 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7146 if (omxhdr == NULL ||
7147 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
7148 {
7149 omxhdr = NULL;
7150 vdec_msg->status_code = VDEC_S_EFATAL;
7151 }
7152
7153 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7154 OMX_COMPONENT_GENERATE_EBD);
7155 break;
7156 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7157 int64_t *timestamp;
7158 timestamp = (int64_t *) malloc(sizeof(int64_t));
7159 if (timestamp) {
7160 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7161 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7162 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
7163 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
7164 vdec_msg->msgdata.output_frame.time_stamp);
7165 }
7166 break;
7167 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7168 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7169
7170 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7171 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
7172 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
7173 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
7174 vdec_msg->msgdata.output_frame.pic_type);
7175
7176 if (omxhdr && omxhdr->pOutputPortPrivate &&
7177 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
7178 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
7179 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
7180 {
7181 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
7182 {
7183 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7184 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007185 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007186 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
7187
7188 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
7189 {
7190 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7191 //rc = -1;
7192 }
Praneeth Paladuguba248592013-06-04 23:08:11 -07007193 if (omxhdr->nFilledLen)
7194 {
7195 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7196 }
7197 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
7198 {
7199 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7200 }
7201 else
7202 {
7203 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7204 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08007205 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
7206 {
7207 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7208 }
Praneeth Paladugufc7dc592013-04-29 12:25:23 -07007209 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
7210 {
7211 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7212 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07007213 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT)
7214 {
7215 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7216 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007217 vdec_msg->msgdata.output_frame.bufferaddr =
7218 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007219 int format_notably_changed = 0;
7220 if (omxhdr->nFilledLen &&
7221 (omxhdr->nFilledLen != omx->prev_n_filled_len))
7222 {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007223 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7224 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7225 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7226 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7227 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7228 format_notably_changed = 1;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007229 }
7230 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007231 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7232 vdec_msg->msgdata.output_frame.framesize.left)
7233 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08007234 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7235 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007236 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7237 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7238 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7239 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7240 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
7241 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
7242 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kaliafa7cc352013-04-03 17:02:37 -07007243 }
Vinay Kalia0321dc12013-04-08 20:45:54 -07007244 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
7245 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
7246 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007247 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7248 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7249 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7250 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007251 format_notably_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08007252 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007253 if (format_notably_changed) {
7254 if(omx->is_video_session_supported()) {
7255 omx->post_event (NULL, vdec_msg->status_code,
7256 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7257 } else {
Eric (Quicef17df02013-05-15 15:14:46 -07007258 if (!omx->client_buffers.update_buffer_req()) {
7259 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7260 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007261 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7262 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7263 }
7264 }
7265 if (omxhdr->nFilledLen)
7266 omx->prev_n_filled_len = omxhdr->nFilledLen;
7267
Shalaj Jain273b3e02012-06-22 19:08:03 -07007268 output_respbuf = (struct vdec_output_frameinfo *)\
7269 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007270 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7271 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08007272 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7273 {
7274 output_respbuf->pic_type = PICTURE_TYPE_I;
7275 }
7276 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7277 {
7278 output_respbuf->pic_type = PICTURE_TYPE_P;
7279 }
7280 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7281 output_respbuf->pic_type = PICTURE_TYPE_B;
7282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283
7284 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007285 memcpy ( omxhdr->pBuffer, (void *)
7286 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7287 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7288 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007289 }
7290 else
7291 omxhdr->nFilledLen = 0;
7292 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7293 OMX_COMPONENT_GENERATE_FBD);
7294 }
7295 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007296 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007297 OMX_COMPONENT_GENERATE_EOS_DONE);
7298 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007299 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007300 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7301 break;
7302 case VDEC_MSG_EVT_CONFIG_CHANGED:
7303 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007304 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7305 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007306 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007307 default:
7308 break;
7309 }
7310 return rc;
7311}
7312
7313OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7314 OMX_HANDLETYPE hComp,
7315 OMX_BUFFERHEADERTYPE *buffer
7316 )
7317{
7318 unsigned address,p2,id;
7319 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7320
7321 if (buffer == NULL)
7322 {
7323 return OMX_ErrorBadParameter;
7324 }
7325 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007326 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7327 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007328
7329 /* return zero length and not an EOS buffer */
7330 /* return buffer if input flush in progress */
7331 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7332 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7333 {
7334 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7335 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7336 return OMX_ErrorNone;
7337 }
7338
7339 if (psource_frame == NULL)
7340 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007341 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007342 psource_frame = buffer;
7343 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7344 push_input_buffer (hComp);
7345 }
7346 else
7347 {
7348 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007349 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7350 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007351 {
7352 return OMX_ErrorBadParameter;
7353 }
7354 }
7355
7356
7357 return OMX_ErrorNone;
7358}
7359
7360OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7361{
7362 unsigned address,p2,id;
7363 OMX_ERRORTYPE ret = OMX_ErrorNone;
7364
7365 if (pdest_frame == NULL || psource_frame == NULL)
7366 {
7367 /*Check if we have a destination buffer*/
7368 if (pdest_frame == NULL)
7369 {
7370 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7371 if (m_input_free_q.m_size)
7372 {
7373 m_input_free_q.pop_entry(&address,&p2,&id);
7374 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7375 pdest_frame->nFilledLen = 0;
7376 pdest_frame->nTimeStamp = LLONG_MAX;
7377 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7378 }
7379 }
7380
7381 /*Check if we have a destination buffer*/
7382 if (psource_frame == NULL)
7383 {
7384 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7385 if (m_input_pending_q.m_size)
7386 {
7387 m_input_pending_q.pop_entry(&address,&p2,&id);
7388 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007389 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007391 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007392 psource_frame->nFlags,psource_frame->nFilledLen);
7393
7394 }
7395 }
7396
7397 }
7398
7399 while ((pdest_frame != NULL) && (psource_frame != NULL))
7400 {
7401 switch (codec_type_parse)
7402 {
7403 case CODEC_TYPE_MPEG4:
7404 case CODEC_TYPE_H263:
7405 case CODEC_TYPE_MPEG2:
7406 ret = push_input_sc_codec(hComp);
7407 break;
7408 case CODEC_TYPE_H264:
7409 ret = push_input_h264(hComp);
7410 break;
7411 case CODEC_TYPE_VC1:
7412 ret = push_input_vc1(hComp);
7413 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007414 default:
7415 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007416 }
7417 if (ret != OMX_ErrorNone)
7418 {
7419 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7420 omx_report_error ();
7421 break;
7422 }
7423 }
7424
7425 return ret;
7426}
7427
7428OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7429{
7430 OMX_U32 partial_frame = 1;
7431 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007432 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007433
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007434 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007435 psource_frame,psource_frame->nTimeStamp);
7436 if (m_frame_parser.parse_sc_frame(psource_frame,
7437 pdest_frame,&partial_frame) == -1)
7438 {
7439 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7440 return OMX_ErrorBadParameter;
7441 }
7442
7443 if (partial_frame == 0)
7444 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007445 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446 pdest_frame->nFilledLen,psource_frame,frame_count);
7447
7448
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007449 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450 /*First Parsed buffer will have only header Hence skip*/
7451 if (frame_count == 0)
7452 {
7453 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7454
7455 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7456 codec_type_parse == CODEC_TYPE_DIVX) {
7457 mp4StreamType psBits;
7458 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7459 psBits.numBytes = pdest_frame->nFilledLen;
7460 mp4_headerparser.parseHeader(&psBits);
7461 }
7462
7463 frame_count++;
7464 }
7465 else
7466 {
7467 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7468 if(pdest_frame->nFilledLen)
7469 {
7470 /*Push the frame to the Decoder*/
7471 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7472 {
7473 return OMX_ErrorBadParameter;
7474 }
7475 frame_count++;
7476 pdest_frame = NULL;
7477
7478 if (m_input_free_q.m_size)
7479 {
7480 m_input_free_q.pop_entry(&address,&p2,&id);
7481 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7482 pdest_frame->nFilledLen = 0;
7483 }
7484 }
7485 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7486 {
7487 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007488 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7489 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007490 pdest_frame = NULL;
7491 }
7492 }
7493 }
7494 else
7495 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007496 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007497 /*Check if Destination Buffer is full*/
7498 if (pdest_frame->nAllocLen ==
7499 pdest_frame->nFilledLen + pdest_frame->nOffset)
7500 {
7501 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7502 return OMX_ErrorStreamCorrupt;
7503 }
7504 }
7505
7506 if (psource_frame->nFilledLen == 0)
7507 {
7508 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7509 {
7510 if (pdest_frame)
7511 {
7512 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007513 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007514 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007515 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007516 pdest_frame->nFilledLen,frame_count++);
7517 /*Push the frame to the Decoder*/
7518 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7519 {
7520 return OMX_ErrorBadParameter;
7521 }
7522 frame_count++;
7523 pdest_frame = NULL;
7524 }
7525 else
7526 {
7527 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7528 generate_ebd = OMX_FALSE;
7529 }
7530 }
7531 if(generate_ebd)
7532 {
7533 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7534 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7535 psource_frame = NULL;
7536
7537 if (m_input_pending_q.m_size)
7538 {
7539 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7540 m_input_pending_q.pop_entry(&address,&p2,&id);
7541 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007542 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007543 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007544 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007545 psource_frame->nFlags,psource_frame->nFilledLen);
7546 }
7547 }
7548 }
7549 return OMX_ErrorNone;
7550}
7551
7552OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7553{
7554 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007555 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007556 OMX_BOOL isNewFrame = OMX_FALSE;
7557 OMX_BOOL generate_ebd = OMX_TRUE;
7558
7559 if (h264_scratch.pBuffer == NULL)
7560 {
7561 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7562 return OMX_ErrorBadParameter;
7563 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007564 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007566 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007567 if (h264_scratch.nFilledLen && look_ahead_nal)
7568 {
7569 look_ahead_nal = false;
7570 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7571 h264_scratch.nFilledLen)
7572 {
7573 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7574 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7575 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7576 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7577 h264_scratch.nFilledLen = 0;
7578 }
7579 else
7580 {
7581 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7582 return OMX_ErrorBadParameter;
7583 }
7584 }
7585 if (nal_length == 0)
7586 {
7587 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7588 if (m_frame_parser.parse_sc_frame(psource_frame,
7589 &h264_scratch,&partial_frame) == -1)
7590 {
7591 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7592 return OMX_ErrorBadParameter;
7593 }
7594 }
7595 else
7596 {
7597 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7598 if (m_frame_parser.parse_h264_nallength(psource_frame,
7599 &h264_scratch,&partial_frame) == -1)
7600 {
7601 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7602 return OMX_ErrorBadParameter;
7603 }
7604 }
7605
7606 if (partial_frame == 0)
7607 {
7608 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7609 {
7610 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7611 nal_count++;
7612 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7613 h264_scratch.nFlags = psource_frame->nFlags;
7614 }
7615 else
7616 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007617 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007618 if(h264_scratch.nFilledLen)
7619 {
7620 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7621 NALU_TYPE_SPS);
7622#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7623 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7624 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7625 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7626 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7627 // If timeinfo is present frame info from SEI is already processed
7628 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7629 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7630#endif
7631 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7632 nal_count++;
7633 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7634 pdest_frame->nTimeStamp = h264_last_au_ts;
7635 pdest_frame->nFlags = h264_last_au_flags;
7636#ifdef PANSCAN_HDLR
7637 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7638 h264_parser->update_panscan_data(h264_last_au_ts);
7639#endif
7640 }
7641 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7642 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7643 h264_last_au_ts = h264_scratch.nTimeStamp;
7644 h264_last_au_flags = h264_scratch.nFlags;
7645#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7646 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7647 {
7648 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7649 if (!VALID_TS(h264_last_au_ts))
7650 h264_last_au_ts = ts_in_sei;
7651 }
7652#endif
7653 } else
7654 h264_last_au_ts = LLONG_MAX;
7655 }
7656
7657 if (!isNewFrame)
7658 {
7659 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7660 h264_scratch.nFilledLen)
7661 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007662 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007663 h264_scratch.nFilledLen);
7664 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7665 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7666 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7667 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7668 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7669 h264_scratch.nFilledLen = 0;
7670 }
7671 else
7672 {
7673 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7674 return OMX_ErrorBadParameter;
7675 }
7676 }
7677 else
7678 {
7679 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007680 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007681 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007682 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007683 pdest_frame->nFilledLen,frame_count++);
7684
7685 if (pdest_frame->nFilledLen == 0)
7686 {
7687 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7688 look_ahead_nal = false;
7689 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7690 h264_scratch.nFilledLen)
7691 {
7692 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7693 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7694 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7695 h264_scratch.nFilledLen = 0;
7696 }
7697 else
7698 {
7699 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7700 return OMX_ErrorBadParameter;
7701 }
7702 }
7703 else
7704 {
7705 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7706 {
7707 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7708 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7709 }
7710 /*Push the frame to the Decoder*/
7711 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7712 {
7713 return OMX_ErrorBadParameter;
7714 }
7715 //frame_count++;
7716 pdest_frame = NULL;
7717 if (m_input_free_q.m_size)
7718 {
7719 m_input_free_q.pop_entry(&address,&p2,&id);
7720 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7721 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7722 pdest_frame->nFilledLen = 0;
7723 pdest_frame->nFlags = 0;
7724 pdest_frame->nTimeStamp = LLONG_MAX;
7725 }
7726 }
7727 }
7728 }
7729 }
7730 else
7731 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007732 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007733 /*Check if Destination Buffer is full*/
7734 if (h264_scratch.nAllocLen ==
7735 h264_scratch.nFilledLen + h264_scratch.nOffset)
7736 {
7737 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7738 return OMX_ErrorStreamCorrupt;
7739 }
7740 }
7741
7742 if (!psource_frame->nFilledLen)
7743 {
7744 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7745
7746 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7747 {
7748 if (pdest_frame)
7749 {
7750 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7751 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7752 h264_scratch.nFilledLen)
7753 {
7754 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7755 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7756 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7757 h264_scratch.nFilledLen = 0;
7758 }
7759 else
7760 {
7761 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7762 return OMX_ErrorBadParameter;
7763 }
7764 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7765 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7766
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007767 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007768 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7769 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7770#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7771 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7772 {
7773 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7774 if (!VALID_TS(pdest_frame->nTimeStamp))
7775 pdest_frame->nTimeStamp = ts_in_sei;
7776 }
7777#endif
7778 /*Push the frame to the Decoder*/
7779 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7780 {
7781 return OMX_ErrorBadParameter;
7782 }
7783 frame_count++;
7784 pdest_frame = NULL;
7785 }
7786 else
7787 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007788 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007789 pdest_frame,h264_scratch.nFilledLen);
7790 generate_ebd = OMX_FALSE;
7791 }
7792 }
7793 }
7794 if(generate_ebd && !psource_frame->nFilledLen)
7795 {
7796 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7797 psource_frame = NULL;
7798 if (m_input_pending_q.m_size)
7799 {
7800 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7801 m_input_pending_q.pop_entry(&address,&p2,&id);
7802 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007803 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007804 psource_frame->nFlags,psource_frame->nFilledLen);
7805 }
7806 }
7807 return OMX_ErrorNone;
7808}
7809
7810OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7811{
7812 OMX_U8 *buf, *pdest;
7813 OMX_U32 partial_frame = 1;
7814 OMX_U32 buf_len, dest_len;
7815
7816 if(first_frame == 0)
7817 {
7818 first_frame = 1;
7819 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7820 if(!m_vendor_config.pData)
7821 {
7822 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7823 buf = psource_frame->pBuffer;
7824 buf_len = psource_frame->nFilledLen;
7825
7826 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7827 VC1_SP_MP_START_CODE)
7828 {
7829 m_vc1_profile = VC1_SP_MP_RCV;
7830 }
7831 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7832 {
7833 m_vc1_profile = VC1_AP;
7834 }
7835 else
7836 {
7837 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7838 return OMX_ErrorStreamCorrupt;
7839 }
7840 }
7841 else
7842 {
7843 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7844 pdest_frame->nOffset;
7845 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7846 pdest_frame->nOffset);
7847
7848 if(dest_len < m_vendor_config.nDataSize)
7849 {
7850 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7851 return OMX_ErrorBadParameter;
7852 }
7853 else
7854 {
7855 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7856 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7857 }
7858 }
7859 }
7860
7861 switch(m_vc1_profile)
7862 {
7863 case VC1_AP:
7864 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7865 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7866 {
7867 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7868 return OMX_ErrorBadParameter;
7869 }
7870 break;
7871
7872 case VC1_SP_MP_RCV:
7873 default:
7874 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7875 return OMX_ErrorBadParameter;
7876 }
7877 return OMX_ErrorNone;
7878}
7879
David Ng38e2d232013-03-15 20:05:58 -07007880#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007881bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7882 OMX_U32 alignment)
7883{
7884 struct pmem_allocation allocation;
7885 allocation.size = buffer_size;
7886 allocation.align = clip2(alignment);
7887 if (allocation.align < 4096)
7888 {
7889 allocation.align = 4096;
7890 }
7891 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7892 {
7893 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7894 allocation.align, allocation.size);
7895 return false;
7896 }
7897 return true;
7898}
David Ng38e2d232013-03-15 20:05:58 -07007899#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900#ifdef USE_ION
7901int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7902 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7903 struct ion_fd_data *fd_data, int flag)
7904{
7905 int fd = -EINVAL;
7906 int rc = -EINVAL;
7907 int ion_dev_flag;
7908 struct vdec_ion ion_buf_info;
7909 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7910 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7911 return -EINVAL;
7912 }
Arun Menon737de532012-09-14 14:48:18 -07007913 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007914 fd = open (MEM_DEVICE, ion_dev_flag);
7915 if (fd < 0) {
7916 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7917 return fd;
7918 }
Arun Menon737de532012-09-14 14:48:18 -07007919 alloc_data->flags = 0;
7920 if(!secure_mode && (flag & ION_FLAG_CACHED))
7921 {
7922 alloc_data->flags |= ION_FLAG_CACHED;
7923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007924 alloc_data->len = buffer_size;
7925 alloc_data->align = clip2(alignment);
7926 if (alloc_data->align < 4096)
7927 {
7928 alloc_data->align = 4096;
7929 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007930 if ((secure_mode) && (flag & ION_SECURE))
7931 alloc_data->flags |= ION_SECURE;
7932
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007933 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7934 if (secure_mode)
7935 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007936 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7937 if (rc || !alloc_data->handle) {
7938 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7939 alloc_data->handle = NULL;
7940 close(fd);
7941 fd = -ENOMEM;
7942 return fd;
7943 }
7944 fd_data->handle = alloc_data->handle;
7945 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7946 if (rc) {
7947 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7948 ion_buf_info.ion_alloc_data = *alloc_data;
7949 ion_buf_info.ion_device_fd = fd;
7950 ion_buf_info.fd_ion_data = *fd_data;
7951 free_ion_memory(&ion_buf_info);
7952 fd_data->fd =-1;
7953 close(fd);
7954 fd = -ENOMEM;
7955 }
7956
7957 return fd;
7958}
7959
7960void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7961
7962 if(!buf_ion_info) {
7963 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7964 return;
7965 }
7966 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7967 &buf_ion_info->ion_alloc_data.handle)) {
7968 DEBUG_PRINT_ERROR("\n ION: free failed" );
7969 }
7970 close(buf_ion_info->ion_device_fd);
7971 buf_ion_info->ion_device_fd = -1;
7972 buf_ion_info->ion_alloc_data.handle = NULL;
7973 buf_ion_info->fd_ion_data.fd = -1;
7974}
7975#endif
7976void omx_vdec::free_output_buffer_header()
7977{
7978 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7979 output_use_buffer = false;
7980 ouput_egl_buffers = false;
7981
7982 if (m_out_mem_ptr)
7983 {
7984 free (m_out_mem_ptr);
7985 m_out_mem_ptr = NULL;
7986 }
7987
7988 if(m_platform_list)
7989 {
7990 free(m_platform_list);
7991 m_platform_list = NULL;
7992 }
7993
7994 if (drv_ctx.ptr_respbuffer)
7995 {
7996 free (drv_ctx.ptr_respbuffer);
7997 drv_ctx.ptr_respbuffer = NULL;
7998 }
7999 if (drv_ctx.ptr_outputbuffer)
8000 {
8001 free (drv_ctx.ptr_outputbuffer);
8002 drv_ctx.ptr_outputbuffer = NULL;
8003 }
8004#ifdef USE_ION
8005 if (drv_ctx.op_buf_ion_info) {
8006 DEBUG_PRINT_LOW("\n Free o/p ion context");
8007 free(drv_ctx.op_buf_ion_info);
8008 drv_ctx.op_buf_ion_info = NULL;
8009 }
8010#endif
8011}
8012
8013void omx_vdec::free_input_buffer_header()
8014{
8015 input_use_buffer = false;
8016 if (arbitrary_bytes)
8017 {
8018 if (m_frame_parser.mutils)
8019 {
8020 DEBUG_PRINT_LOW("\n Free utils parser");
8021 delete (m_frame_parser.mutils);
8022 m_frame_parser.mutils = NULL;
8023 }
8024
8025 if (m_inp_heap_ptr)
8026 {
8027 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
8028 free (m_inp_heap_ptr);
8029 m_inp_heap_ptr = NULL;
8030 }
8031
8032 if (m_phdr_pmem_ptr)
8033 {
8034 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
8035 free (m_phdr_pmem_ptr);
8036 m_phdr_pmem_ptr = NULL;
8037 }
8038 }
8039 if (m_inp_mem_ptr)
8040 {
8041 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
8042 free (m_inp_mem_ptr);
8043 m_inp_mem_ptr = NULL;
8044 }
8045 if (drv_ctx.ptr_inputbuffer)
8046 {
8047 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
8048 free (drv_ctx.ptr_inputbuffer);
8049 drv_ctx.ptr_inputbuffer = NULL;
8050 }
8051#ifdef USE_ION
8052 if (drv_ctx.ip_buf_ion_info) {
8053 DEBUG_PRINT_LOW("\n Free ion context");
8054 free(drv_ctx.ip_buf_ion_info);
8055 drv_ctx.ip_buf_ion_info = NULL;
8056 }
8057#endif
8058}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008059
8060int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008061{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008062 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008063 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008064 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008065
8066 if (port == OMX_CORE_INPUT_PORT_INDEX) {
8067 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8068 v4l2_port = OUTPUT_PORT;
8069 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
8070 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8071 v4l2_port = CAPTURE_PORT;
8072 } else if (port == OMX_ALL) {
8073 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
8074 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
8075
8076 if (!rc_input)
8077 return rc_input;
8078 else
8079 return rc_output;
8080 }
8081
8082 if (!streaming[v4l2_port]) {
8083 // already streamed off, warn and move on
8084 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
8085 " which is already streamed off", v4l2_port);
8086 return 0;
8087 }
8088
8089 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
8090
Shalaj Jain273b3e02012-06-22 19:08:03 -07008091 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
8092 if (rc) {
8093 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008094 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008095 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008096 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008097 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008098
8099 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008100}
8101
8102OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
8103{
8104 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8105 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008106 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008107 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008108 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008109 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8110 buffer_prop->actualcount, buffer_prop->buffer_size);
8111 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07008112 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008113 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8114 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8115 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8116 fmt.fmt.pix_mp.pixelformat = output_capability;
8117 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
8118 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8119 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8120 fmt.fmt.pix_mp.pixelformat = capture_capability;
8121 }else {eRet = OMX_ErrorBadParameter;}
8122 if(eRet==OMX_ErrorNone){
8123 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8124 }
8125 if(ret)
8126 {
8127 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8128 /*TODO: How to handle this case */
8129 eRet = OMX_ErrorInsufficientResources;
8130 return eRet;
8131 }
8132 else
8133 {
8134 buffer_prop->actualcount = bufreq.count;
8135 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07008136 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008137 }
8138 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8139 buffer_prop->actualcount, buffer_prop->buffer_size);
8140
8141 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8142 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8143
8144 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8145
Vinay Kalia21649b32013-03-18 17:28:07 -07008146 update_resolution(fmt.fmt.pix_mp.width,
8147 fmt.fmt.pix_mp.height,
8148 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8149 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08008150 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8151 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07008152 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008153
8154 if(ret)
8155 {
8156 /*TODO: How to handle this case */
8157 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8158 eRet = OMX_ErrorInsufficientResources;
8159 }
8160 else
8161 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008162 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08008163
8164 eRet = is_video_session_supported();
8165 if (eRet)
8166 return eRet;
8167
Shalaj Jain273b3e02012-06-22 19:08:03 -07008168 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8169 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008170 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8171 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8172 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8173 } else if (extra_idx >= VIDEO_MAX_PLANES) {
8174 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
8175 return OMX_ErrorBadParameter;
8176 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008177 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8178 {
8179 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008180 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008181 }
8182 if (client_extradata & OMX_INTERLACE_EXTRADATA)
8183 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008184 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008185 }
8186 if (client_extradata & OMX_PORTDEF_EXTRADATA)
8187 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008188 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
8189 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
8190 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008191 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008192 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008193 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008194 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07008195 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
8196 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008197 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
8198 drv_ctx.extradata_info.count = buffer_prop->actualcount;
8199 drv_ctx.extradata_info.buffer_size = extra_data_size;
8200 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008201 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8202 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008203 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008204 if (in_reconfig) // BufReq will be set to driver when port is disabled
8205 buffer_prop->buffer_size = buf_size;
8206 else if (buf_size != buffer_prop->buffer_size)
8207 {
8208 buffer_prop->buffer_size = buf_size;
8209 eRet = set_buffer_req(buffer_prop);
8210 }
8211 }
8212 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8213 buffer_prop->actualcount, buffer_prop->buffer_size);
8214 return eRet;
8215}
8216
8217OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8218{
8219 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8220 unsigned buf_size = 0;
8221 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008222 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008223 int ret;
8224 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8225 buffer_prop->actualcount, buffer_prop->buffer_size);
8226 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8227 if (buf_size != buffer_prop->buffer_size)
8228 {
8229 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8230 buffer_prop->buffer_size, buf_size);
8231 eRet = OMX_ErrorBadParameter;
8232 }
8233 else
8234 {
8235 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8236 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008237
8238 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8239 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8240 fmt.fmt.pix_mp.pixelformat = output_capability;
8241 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8242 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8243 fmt.fmt.pix_mp.pixelformat = capture_capability;
8244 } else {eRet = OMX_ErrorBadParameter;}
8245
8246 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8247 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008248 {
8249 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008250 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008251 eRet = OMX_ErrorInsufficientResources;
8252 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008253
8254 bufreq.memory = V4L2_MEMORY_USERPTR;
8255 bufreq.count = buffer_prop->actualcount;
8256 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8257 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8258 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8259 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8260 } else {eRet = OMX_ErrorBadParameter;}
8261
8262 if (eRet==OMX_ErrorNone) {
8263 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8264 }
8265
8266 if (ret)
8267 {
8268 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8269 /*TODO: How to handle this case */
8270 eRet = OMX_ErrorInsufficientResources;
8271 } else if (bufreq.count < buffer_prop->actualcount) {
8272 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8273 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8274 buffer_prop->actualcount, bufreq.count);
8275 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008276 } else {
8277 if (!client_buffers.update_buffer_req()) {
8278 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8279 eRet = OMX_ErrorInsufficientResources;
8280 }
8281 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008282 }
8283 return eRet;
8284}
8285
Shalaj Jain273b3e02012-06-22 19:08:03 -07008286OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8287{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008288 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008289 return eRet;
8290}
8291
8292OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8293{
8294 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8295 if (!portDefn)
8296 {
8297 return OMX_ErrorBadParameter;
8298 }
8299 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8300 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8301 portDefn->nSize = sizeof(portDefn);
8302 portDefn->eDomain = OMX_PortDomainVideo;
8303 if (drv_ctx.frame_rate.fps_denominator > 0)
8304 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8305 drv_ctx.frame_rate.fps_denominator;
8306 else {
8307 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8308 return OMX_ErrorBadParameter;
8309 }
8310 if (0 == portDefn->nPortIndex)
8311 {
8312 portDefn->eDir = OMX_DirInput;
8313 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8314 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8315 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8316 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8317 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8318 portDefn->bEnabled = m_inp_bEnabled;
8319 portDefn->bPopulated = m_inp_bPopulated;
8320 }
8321 else if (1 == portDefn->nPortIndex)
8322 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008323 unsigned int buf_size = 0;
8324 if (!client_buffers.update_buffer_req()) {
8325 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8326 return OMX_ErrorHardware;
8327 }
8328 if (!client_buffers.get_buffer_req(buf_size)) {
8329 DEBUG_PRINT_ERROR("\n update buffer requirements");
8330 return OMX_ErrorHardware;
8331 }
8332 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008333 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008334 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8335 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008336 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8337 portDefn->bEnabled = m_out_bEnabled;
8338 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008339 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8340 DEBUG_PRINT_ERROR("\n Error in getting color format");
8341 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008342 }
8343 }
8344 else
8345 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008346 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008347 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8348 (int)portDefn->nPortIndex);
8349 eRet = OMX_ErrorBadPortIndex;
8350 }
8351 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8352 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8353 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8354 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008355 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8356 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008357 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008358 portDefn->format.video.nStride,
8359 portDefn->format.video.nSliceHeight);
8360 return eRet;
8361
8362}
8363
8364OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8365{
8366 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8367 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8368 unsigned i= 0;
8369
8370 if(!m_out_mem_ptr) {
8371 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8372 int nBufHdrSize = 0;
8373 int nPlatformEntrySize = 0;
8374 int nPlatformListSize = 0;
8375 int nPMEMInfoSize = 0;
8376 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8377 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8378 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8379
8380 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8381 drv_ctx.op_buf.actualcount);
8382 nBufHdrSize = drv_ctx.op_buf.actualcount *
8383 sizeof(OMX_BUFFERHEADERTYPE);
8384
8385 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8386 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8387 nPlatformListSize = drv_ctx.op_buf.actualcount *
8388 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8389 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8390 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8391
8392 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8393 sizeof(OMX_BUFFERHEADERTYPE),
8394 nPMEMInfoSize,
8395 nPlatformListSize);
8396 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8397 m_out_bm_count);
8398 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8399 // Alloc mem for platform specific info
8400 char *pPtr=NULL;
8401 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8402 nPMEMInfoSize,1);
8403 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8404 calloc (sizeof(struct vdec_bufferpayload),
8405 drv_ctx.op_buf.actualcount);
8406 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8407 calloc (sizeof (struct vdec_output_frameinfo),
8408 drv_ctx.op_buf.actualcount);
8409#ifdef USE_ION
8410 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8411 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8412#endif
8413
8414 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8415 && drv_ctx.ptr_respbuffer)
8416 {
8417 bufHdr = m_out_mem_ptr;
8418 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8419 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8420 (((char *) m_platform_list) + nPlatformListSize);
8421 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8422 (((char *) m_platform_entry) + nPlatformEntrySize);
8423 pPlatformList = m_platform_list;
8424 pPlatformEntry = m_platform_entry;
8425 pPMEMInfo = m_pmem_info;
8426
8427 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8428
8429 // Settting the entire storage nicely
8430 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8431 m_out_mem_ptr,pPlatformEntry);
8432 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8433 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8434 {
8435 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8436 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8437 // Set the values when we determine the right HxW param
8438 bufHdr->nAllocLen = 0;
8439 bufHdr->nFilledLen = 0;
8440 bufHdr->pAppPrivate = NULL;
8441 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8442 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8443 pPlatformEntry->entry = pPMEMInfo;
8444 // Initialize the Platform List
8445 pPlatformList->nEntries = 1;
8446 pPlatformList->entryList = pPlatformEntry;
8447 // Keep pBuffer NULL till vdec is opened
8448 bufHdr->pBuffer = NULL;
8449 pPMEMInfo->offset = 0;
8450 pPMEMInfo->pmem_fd = 0;
8451 bufHdr->pPlatformPrivate = pPlatformList;
8452 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8453#ifdef USE_ION
8454 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8455#endif
8456 /*Create a mapping between buffers*/
8457 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8458 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8459 &drv_ctx.ptr_outputbuffer[i];
8460 // Move the buffer and buffer header pointers
8461 bufHdr++;
8462 pPMEMInfo++;
8463 pPlatformEntry++;
8464 pPlatformList++;
8465 }
8466 }
8467 else
8468 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008469 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470 m_out_mem_ptr, pPtr);
8471 if(m_out_mem_ptr)
8472 {
8473 free(m_out_mem_ptr);
8474 m_out_mem_ptr = NULL;
8475 }
8476 if(pPtr)
8477 {
8478 free(pPtr);
8479 pPtr = NULL;
8480 }
8481 if(drv_ctx.ptr_outputbuffer)
8482 {
8483 free(drv_ctx.ptr_outputbuffer);
8484 drv_ctx.ptr_outputbuffer = NULL;
8485 }
8486 if(drv_ctx.ptr_respbuffer)
8487 {
8488 free(drv_ctx.ptr_respbuffer);
8489 drv_ctx.ptr_respbuffer = NULL;
8490 }
8491#ifdef USE_ION
8492 if (drv_ctx.op_buf_ion_info) {
8493 DEBUG_PRINT_LOW("\n Free o/p ion context");
8494 free(drv_ctx.op_buf_ion_info);
8495 drv_ctx.op_buf_ion_info = NULL;
8496 }
8497#endif
8498 eRet = OMX_ErrorInsufficientResources;
8499 }
8500 } else {
8501 eRet = OMX_ErrorInsufficientResources;
8502 }
8503 return eRet;
8504}
8505
8506void omx_vdec::complete_pending_buffer_done_cbs()
8507{
8508 unsigned p1;
8509 unsigned p2;
8510 unsigned ident;
8511 omx_cmd_queue tmp_q, pending_bd_q;
8512 pthread_mutex_lock(&m_lock);
8513 // pop all pending GENERATE FDB from ftb queue
8514 while (m_ftb_q.m_size)
8515 {
8516 m_ftb_q.pop_entry(&p1,&p2,&ident);
8517 if(ident == OMX_COMPONENT_GENERATE_FBD)
8518 {
8519 pending_bd_q.insert_entry(p1,p2,ident);
8520 }
8521 else
8522 {
8523 tmp_q.insert_entry(p1,p2,ident);
8524 }
8525 }
8526 //return all non GENERATE FDB to ftb queue
8527 while(tmp_q.m_size)
8528 {
8529 tmp_q.pop_entry(&p1,&p2,&ident);
8530 m_ftb_q.insert_entry(p1,p2,ident);
8531 }
8532 // pop all pending GENERATE EDB from etb queue
8533 while (m_etb_q.m_size)
8534 {
8535 m_etb_q.pop_entry(&p1,&p2,&ident);
8536 if(ident == OMX_COMPONENT_GENERATE_EBD)
8537 {
8538 pending_bd_q.insert_entry(p1,p2,ident);
8539 }
8540 else
8541 {
8542 tmp_q.insert_entry(p1,p2,ident);
8543 }
8544 }
8545 //return all non GENERATE FDB to etb queue
8546 while(tmp_q.m_size)
8547 {
8548 tmp_q.pop_entry(&p1,&p2,&ident);
8549 m_etb_q.insert_entry(p1,p2,ident);
8550 }
8551 pthread_mutex_unlock(&m_lock);
8552 // process all pending buffer dones
8553 while(pending_bd_q.m_size)
8554 {
8555 pending_bd_q.pop_entry(&p1,&p2,&ident);
8556 switch(ident)
8557 {
8558 case OMX_COMPONENT_GENERATE_EBD:
8559 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8560 {
8561 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8562 omx_report_error ();
8563 }
8564 break;
8565
8566 case OMX_COMPONENT_GENERATE_FBD:
8567 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8568 {
8569 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8570 omx_report_error ();
8571 }
8572 break;
8573 }
8574 }
8575}
8576
8577void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8578{
8579 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008580 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07008581 && llabs(act_timestamp - prev_ts) > 2000)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008582 {
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07008583 new_frame_interval = client_set_fps ? frm_int :
8584 llabs(act_timestamp - prev_ts);
8585 if (new_frame_interval != frm_int || frm_int == 0)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586 {
8587 frm_int = new_frame_interval;
8588 if(frm_int)
8589 {
8590 drv_ctx.frame_rate.fps_numerator = 1e6;
8591 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008592 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008593 frm_int, drv_ctx.frame_rate.fps_numerator /
8594 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008595
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008596 /* We need to report the difference between this FBD and the previous FBD
8597 * back to the driver for clock scaling purposes. */
8598 struct v4l2_outputparm oparm;
8599 /*XXX: we're providing timing info as seconds per frame rather than frames
8600 * per second.*/
8601 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8602 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
8603
8604 struct v4l2_streamparm sparm;
8605 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8606 sparm.parm.output = oparm;
8607 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm))
8608 {
8609 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8610 performance might be affected");
8611 }
8612
Shalaj Jain273b3e02012-06-22 19:08:03 -07008613 }
8614 }
8615 }
8616 prev_ts = act_timestamp;
8617}
8618
8619void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8620{
8621 if (rst_prev_ts && VALID_TS(act_timestamp))
8622 {
8623 prev_ts = act_timestamp;
8624 rst_prev_ts = false;
8625 }
8626 else if (VALID_TS(prev_ts))
8627 {
8628 bool codec_cond = (drv_ctx.timestamp_adjust)?
8629 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8630 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8631 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8632 if(frm_int > 0 && codec_cond)
8633 {
8634 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8635 act_timestamp = prev_ts + frm_int;
8636 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8637 prev_ts = act_timestamp;
8638 }
8639 else
8640 set_frame_rate(act_timestamp);
8641 }
8642 else if (frm_int > 0) // In this case the frame rate was set along
8643 { // with the port definition, start ts with 0
8644 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8645 rst_prev_ts = true;
8646 }
8647}
8648
8649void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8650{
8651 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8652 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008653 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008654 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008655 OMX_U32 num_MB_in_frame;
8656 OMX_U32 recovery_sei_flags = 1;
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008657 int enable = 0;
8658 OMX_U32 mbaff = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008659 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008660 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008661 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8662 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008663 if (!drv_ctx.extradata_info.uaddr) {
8664 return;
8665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008666 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008667 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8668 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8669 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008670 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008671 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008672 if (data) {
8673 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008674 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008675 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008676 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008677 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008678 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008679 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008680 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008681 struct msm_vidc_interlace_payload *payload;
8682 payload = (struct msm_vidc_interlace_payload *)data->data;
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008683 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8684 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8685 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8686 else {
8687 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8688 enable = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008689 }
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008690 if(m_enable_android_native_buffers)
8691 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8692 PP_PARAM_INTERLACED, (void*)&enable);
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008693 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8694 append_interlace_extradata(p_extra, payload->format);
8695 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8696 }
8697 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008698 case EXTRADATA_FRAME_RATE:
8699 struct msm_vidc_framerate_payload *frame_rate_payload;
8700 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8701 frame_rate = frame_rate_payload->frame_rate;
8702 break;
8703 case EXTRADATA_TIMESTAMP:
8704 struct msm_vidc_ts_payload *time_stamp_payload;
8705 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008706 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008707 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008708 break;
8709 case EXTRADATA_NUM_CONCEALED_MB:
8710 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8711 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8712 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8713 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8714 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8715 break;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008716 case EXTRADATA_INDEX:
8717 int *etype;
8718 etype = (int *)(data->data);
8719 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008720 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008721 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8722 if (aspect_ratio_payload) {
8723 ((struct vdec_output_frameinfo *)
8724 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8725 ((struct vdec_output_frameinfo *)
8726 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8727 }
8728 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008729 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008730 case EXTRADATA_RECOVERY_POINT_SEI:
8731 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8732 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8733 recovery_sei_flags = recovery_sei_payload->flags;
8734 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008735 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8736 DEBUG_PRINT_HIGH("\n");
8737 DEBUG_PRINT_HIGH("***************************************************\n");
8738 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
8739 DEBUG_PRINT_HIGH("***************************************************\n");
8740 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008741 break;
8742 case EXTRADATA_PANSCAN_WINDOW:
8743 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8744 break;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008745 case EXTRADATA_MPEG2_SEQDISP:
8746 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8747 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8748 if (seqdisp_payload) {
8749 m_disp_hor_size = seqdisp_payload->disp_width;
8750 m_disp_vert_size = seqdisp_payload->disp_height;
8751 }
8752 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008753 default:
8754 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008755 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008756 consumed_len += data->nSize;
8757 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008758 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008759 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008760 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008761 append_frame_info_extradata(p_extra,
8762 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008763 panscan_payload,&((struct vdec_output_frameinfo *)
8764 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008765 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008766unrecognized_extradata:
8767 if(!secure_mode && client_extradata)
8768 append_terminator_extradata(p_extra);
8769 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008770}
8771
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008772OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8773 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008774{
8775 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008776 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008777 if(m_state != OMX_StateLoaded)
8778 {
8779 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8780 return OMX_ErrorIncorrectStateOperation;
8781 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008782 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008783 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008784
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008785 if (!is_internal) {
8786 if (enable)
8787 client_extradata |= requested_extradata;
8788 else
8789 client_extradata = client_extradata & ~requested_extradata;
8790 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008791
8792 if (enable) {
8793 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8794 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8795 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8796 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8797 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8798 " Quality of interlaced clips might be impacted.\n");
8799 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008800 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8801 {
8802 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8803 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8804 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8805 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8806 }
8807 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8808 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8809 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8810 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8811 }
8812 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8813 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8814 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8815 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8816 }
8817 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8818 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8819 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8820 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8821 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008822 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8823 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8824 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8825 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8826 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008827 if (output_capability == V4L2_PIX_FMT_MPEG2)
8828 {
8829 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8830 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8831 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8832 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8833 }
8834 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008835 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8836 {
8837 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8838 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8839 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8840 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8841 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008842 }
8843 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008844 return ret;
8845}
8846
8847OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8848{
8849 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8850 OMX_U8 *data_ptr = extra->data, data = 0;
8851 while (byte_count < extra->nDataSize)
8852 {
8853 data = *data_ptr;
8854 while (data)
8855 {
8856 num_MB += (data&0x01);
8857 data >>= 1;
8858 }
8859 data_ptr++;
8860 byte_count++;
8861 }
8862 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8863 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8864 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8865}
8866
8867void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8868{
8869 if (!m_debug_extradata)
8870 return;
8871
8872 DEBUG_PRINT_HIGH(
8873 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008874 " Size: %lu \n"
8875 " Version: %lu \n"
8876 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008877 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008878 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008879 extra->nSize, extra->nVersion.nVersion,
8880 extra->nPortIndex, extra->eType, extra->nDataSize);
8881
Shalaj Jain286b0062013-02-21 20:35:48 -08008882 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008883 {
8884 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8885 DEBUG_PRINT_HIGH(
8886 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008887 " Size: %lu \n"
8888 " Version: %lu \n"
8889 " PortIndex: %lu \n"
8890 " Is Interlace Format: %d \n"
8891 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008892 "=========== End of Interlace ===========\n",
8893 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8894 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8895 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008896 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008897 {
8898 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8899
8900 DEBUG_PRINT_HIGH(
8901 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008902 " Picture Type: %d \n"
8903 " Interlace Type: %d \n"
8904 " Pan Scan Total Frame Num: %lu \n"
8905 " Concealed Macro Blocks: %lu \n"
8906 " frame rate: %lu \n"
8907 " Aspect Ratio X: %lu \n"
8908 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008909 fminfo->ePicType,
8910 fminfo->interlaceType,
8911 fminfo->panScan.numWindows,
8912 fminfo->nConcealedMacroblocks,
8913 fminfo->nFrameRate,
8914 fminfo->aspectRatio.aspectRatioX,
8915 fminfo->aspectRatio.aspectRatioY);
8916
Praneeth Paladugu32284302013-02-14 22:53:06 -08008917 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008918 {
8919 DEBUG_PRINT_HIGH(
8920 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008921 " Pan Scan Frame Num: %lu \n"
8922 " Rectangle x: %ld \n"
8923 " Rectangle y: %ld \n"
8924 " Rectangle dx: %ld \n"
8925 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008926 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8927 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8928 }
8929
8930 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8931 }
8932 else if (extra->eType == OMX_ExtraDataNone)
8933 {
8934 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8935 }
8936 else
8937 {
8938 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8939 }
8940}
8941
8942void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8943 OMX_U32 interlaced_format_type)
8944{
8945 OMX_STREAMINTERLACEFORMAT *interlace_format;
8946 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008947 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8948 return;
8949 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008950 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8951 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8952 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8953 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8954 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8955 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8956 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8957 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8958 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8959 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008960 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008961 {
8962 interlace_format->bInterlaceFormat = OMX_FALSE;
8963 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8964 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8965 }
8966 else
8967 {
8968 interlace_format->bInterlaceFormat = OMX_TRUE;
8969 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8970 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8971 }
8972 print_debug_extradata(extra);
8973}
8974
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008975void omx_vdec::fill_aspect_ratio_info(
8976 struct vdec_aspectratioinfo *aspect_ratio_info,
8977 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8978{
8979 m_extradata = frame_info;
8980 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8981 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008982 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008983 m_extradata->aspectRatio.aspectRatioY);
8984}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008985
8986void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008987 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008988 struct msm_vidc_panscan_window_payload *panscan_payload,
8989 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008990{
8991 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008992 struct msm_vidc_panscan_window *panscan_window;
8993 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8994 return;
8995 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008996 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8997 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8998 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8999 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9000 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9001 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9002 switch (picture_type)
9003 {
9004 case PICTURE_TYPE_I:
9005 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9006 break;
9007 case PICTURE_TYPE_P:
9008 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9009 break;
9010 case PICTURE_TYPE_B:
9011 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9012 break;
9013 default:
9014 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9015 }
9016 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9017 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9018 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9019 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9020 else
9021 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009022 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07009023 frame_info->nConcealedMacroblocks = num_conceal_mb;
9024 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009025 frame_info->panScan.numWindows = 0;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009026 if (output_capability == V4L2_PIX_FMT_MPEG2)
9027 {
9028 if (m_disp_hor_size && m_disp_vert_size)
9029 {
9030 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9031 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
9032 }
9033 }
9034
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009035 if(panscan_payload) {
9036 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9037 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08009038 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009039 {
9040 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9041 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9042 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9043 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9044 panscan_window++;
9045 }
9046 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009047 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009048 print_debug_extradata(extra);
9049}
9050
9051void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9052{
9053 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9054 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9055 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9056 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9057 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9058 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9059 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9060 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009061 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
9062 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07009063 portDefn->format.video.nFrameWidth,
9064 portDefn->format.video.nStride,
9065 portDefn->format.video.nSliceHeight);
9066}
9067
9068void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9069{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08009070 if (!client_extradata) {
9071 return;
9072 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009073 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9074 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9075 extra->eType = OMX_ExtraDataNone;
9076 extra->nDataSize = 0;
9077 extra->data[0] = 0;
9078
9079 print_debug_extradata(extra);
9080}
9081
9082OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9083{
9084 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9085 if (index >= drv_ctx.ip_buf.actualcount)
9086 {
9087 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
9088 return OMX_ErrorInsufficientResources;
9089 }
9090 if (m_desc_buffer_ptr == NULL)
9091 {
9092 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9093 calloc( (sizeof(desc_buffer_hdr)),
9094 drv_ctx.ip_buf.actualcount);
9095 if (m_desc_buffer_ptr == NULL)
9096 {
9097 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
9098 return OMX_ErrorInsufficientResources;
9099 }
9100 }
9101
9102 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9103 if (m_desc_buffer_ptr[index].buf_addr == NULL)
9104 {
9105 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
9106 return OMX_ErrorInsufficientResources;
9107 }
9108
9109 return eRet;
9110}
9111
9112void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9113{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009114 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009115 if (m_demux_entries < 8192)
9116 {
9117 m_demux_offsets[m_demux_entries++] = address_offset;
9118 }
9119 return;
9120}
9121
9122void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9123{
9124 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9125 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9126 OMX_U32 index = 0;
9127
9128 m_demux_entries = 0;
9129
9130 while (index < bytes_to_parse)
9131 {
9132 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9133 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9134 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9135 (buf[index+2] == 0x01)) )
9136 {
9137 //Found start code, insert address offset
9138 insert_demux_addr_offset(index);
9139 if (buf[index+2] == 0x01) // 3 byte start code
9140 index += 3;
9141 else //4 byte start code
9142 index += 4;
9143 }
9144 else
9145 index++;
9146 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009147 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009148 return;
9149}
9150
9151OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9152{
9153 //fix this, handle 3 byte start code, vc1 terminator entry
9154 OMX_U8 *p_demux_data = NULL;
9155 OMX_U32 desc_data = 0;
9156 OMX_U32 start_addr = 0;
9157 OMX_U32 nal_size = 0;
9158 OMX_U32 suffix_byte = 0;
9159 OMX_U32 demux_index = 0;
9160 OMX_U32 buffer_index = 0;
9161
9162 if (m_desc_buffer_ptr == NULL)
9163 {
9164 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9165 return OMX_ErrorBadParameter;
9166 }
9167
9168 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9169 if (buffer_index > drv_ctx.ip_buf.actualcount)
9170 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08009171 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009172 return OMX_ErrorBadParameter;
9173 }
9174
9175 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9176
9177 if ( ((OMX_U8*)p_demux_data == NULL) ||
9178 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
9179 {
9180 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9181 return OMX_ErrorBadParameter;
9182 }
9183 else
9184 {
9185 for (; demux_index < m_demux_entries; demux_index++)
9186 {
9187 desc_data = 0;
9188 start_addr = m_demux_offsets[demux_index];
9189 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
9190 {
9191 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9192 }
9193 else
9194 {
9195 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9196 }
9197 if (demux_index < (m_demux_entries - 1))
9198 {
9199 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9200 }
9201 else
9202 {
9203 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9204 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009205 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9206 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07009207 suffix_byte,
9208 nal_size,
9209 demux_index);
9210 desc_data = (start_addr >> 3) << 1;
9211 desc_data |= (start_addr & 7) << 21;
9212 desc_data |= suffix_byte << 24;
9213
9214 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9215 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9216 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9217 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9218
9219 p_demux_data += 16;
9220 }
9221 if (codec_type_parse == CODEC_TYPE_VC1)
9222 {
9223 DEBUG_PRINT_LOW("VC1 terminator entry");
9224 desc_data = 0;
9225 desc_data = 0x82 << 24;
9226 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9227 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9228 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9229 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9230 p_demux_data += 16;
9231 m_demux_entries++;
9232 }
9233 //Add zero word to indicate end of descriptors
9234 memset(p_demux_data, 0, sizeof(OMX_U32));
9235
9236 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009237 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009238 }
9239 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9240 m_demux_entries = 0;
9241 DEBUG_PRINT_LOW("Demux table complete!");
9242 return OMX_ErrorNone;
9243}
9244
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009245OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009246{
9247 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009248 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07009249 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07009250 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9251 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009252 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009253 delete iDivXDrmDecrypt;
9254 iDivXDrmDecrypt = NULL;
9255 }
9256 }
9257 else {
9258 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009259 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009260 }
9261 return err;
9262}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009263
Vinay Kaliada4f4422013-01-09 10:45:03 -08009264omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9265{
9266 enabled = false;
9267 omx = NULL;
9268 init_members();
9269 ColorFormat = OMX_COLOR_FormatMax;
9270}
9271
9272void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9273{
9274 omx = reinterpret_cast<omx_vdec*>(client);
9275}
9276
9277void omx_vdec::allocate_color_convert_buf::init_members() {
9278 allocated_count = 0;
9279 buffer_size_req = 0;
9280 buffer_alignment_req = 0;
9281 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9282 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9283 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9284 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9285#ifdef USE_ION
9286 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9287#endif
9288 for (int i = 0; i < MAX_COUNT;i++)
9289 pmem_fd[i] = -1;
9290}
9291
9292omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
9293 c2d.destroy();
9294}
9295
9296bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9297{
9298 bool status = true;
9299 unsigned int src_size = 0, destination_size = 0;
9300 OMX_COLOR_FORMATTYPE drv_color_format;
9301 if (!omx){
9302 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9303 return false;
9304 }
9305 if (!enabled){
9306 DEBUG_PRINT_ERROR("\n No color conversion required");
9307 return status;
9308 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009309 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009310 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9311 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9312 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009313 status = false;
9314 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009315 }
9316 c2d.close();
9317 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9318 omx->drv_ctx.video_resolution.frame_width,
9319 NV12_128m,YCbCr420P);
9320 if (status) {
9321 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9322 if (status)
9323 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9324 }
9325 if (status) {
9326 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9327 !destination_size) {
9328 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9329 "driver size %d destination size %d",
9330 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9331 status = false;
9332 c2d.close();
9333 buffer_size_req = 0;
9334 } else {
9335 buffer_size_req = destination_size;
9336 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9337 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9338 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9339 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9340 }
9341 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009342fail_update_buf_req:
9343 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009344 return status;
9345}
9346
9347bool omx_vdec::allocate_color_convert_buf::set_color_format(
9348 OMX_COLOR_FORMATTYPE dest_color_format)
9349{
9350 bool status = true;
9351 OMX_COLOR_FORMATTYPE drv_color_format;
9352 if (!omx){
9353 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9354 return false;
9355 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009356 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009357 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9358 drv_color_format = (OMX_COLOR_FORMATTYPE)
9359 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9360 else {
9361 DEBUG_PRINT_ERROR("\n Incorrect color format");
9362 status = false;
9363 }
9364 if (status && (drv_color_format != dest_color_format)) {
9365 DEBUG_PRINT_LOW("Enabling C2D\n");
9366 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9367 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9368 status = false;
9369 } else {
9370 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9371 if (enabled)
9372 c2d.destroy();
9373 enabled = false;
9374 if (!c2d.init()) {
9375 DEBUG_PRINT_ERROR("\n open failed for c2d");
9376 status = false;
9377 } else
9378 enabled = true;
9379 }
9380 } else {
9381 if (enabled)
9382 c2d.destroy();
9383 enabled = false;
9384 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009385 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009386 return status;
9387}
9388
9389OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9390{
9391 if (!omx){
9392 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9393 return NULL;
9394 }
9395 if (!enabled)
9396 return omx->m_out_mem_ptr;
9397 return m_out_mem_ptr_client;
9398}
9399
9400OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9401 (OMX_BUFFERHEADERTYPE *bufadd)
9402{
9403 if (!omx){
9404 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9405 return NULL;
9406 }
9407 if (!enabled)
9408 return bufadd;
9409
9410 unsigned index = 0;
9411 index = bufadd - omx->m_out_mem_ptr;
9412 if (index < omx->drv_ctx.op_buf.actualcount) {
9413 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9414 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9415 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009416 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009417 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009418 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
Rajeshwar Kurapaty18ca33c2013-06-04 01:25:28 +05309419 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9420 pmem_baseaddress[index], pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009421 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009422 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9423 if (!status){
9424 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009425 m_out_mem_ptr_client[index].nFilledLen = 0;
9426 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009427 }
9428 } else
9429 m_out_mem_ptr_client[index].nFilledLen = 0;
9430 return &m_out_mem_ptr_client[index];
9431 }
9432 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9433 return NULL;
9434}
9435
9436OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9437 (OMX_BUFFERHEADERTYPE *bufadd)
9438{
9439 if (!omx){
9440 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9441 return NULL;
9442 }
9443 if (!enabled)
9444 return bufadd;
9445 unsigned index = 0;
9446 index = bufadd - m_out_mem_ptr_client;
9447 if (index < omx->drv_ctx.op_buf.actualcount) {
9448 return &omx->m_out_mem_ptr[index];
9449 }
9450 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9451 return NULL;
9452}
9453bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9454 (unsigned int &buffer_size)
9455{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009456 bool status = true;
9457 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009458 if (!enabled)
9459 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009460 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009461 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9462 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009463 status = false;
9464 goto fail_get_buffer_size;
9465 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009466 }
9467 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9468 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9469 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9470 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009471fail_get_buffer_size:
9472 pthread_mutex_unlock(&omx->c_lock);
9473 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009474}
9475OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9476 OMX_BUFFERHEADERTYPE *bufhdr) {
9477 unsigned int index = 0;
9478
9479 if (!enabled)
9480 return omx->free_output_buffer(bufhdr);
9481 if (enabled && omx->is_component_secure())
9482 return OMX_ErrorNone;
9483 if (!allocated_count || !bufhdr) {
9484 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9485 return OMX_ErrorBadParameter;
9486 }
9487 index = bufhdr - m_out_mem_ptr_client;
9488 if (index >= omx->drv_ctx.op_buf.actualcount){
9489 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9490 return OMX_ErrorBadParameter;
9491 }
9492 if (pmem_fd[index] > 0) {
9493 munmap(pmem_baseaddress[index], buffer_size_req);
9494 close(pmem_fd[index]);
9495 }
9496 pmem_fd[index] = -1;
9497#ifdef USE_ION
9498 omx->free_ion_memory(&op_buf_ion_info[index]);
9499#endif
9500 m_heap_ptr[index].video_heap_ptr = NULL;
9501 if (allocated_count > 0)
9502 allocated_count--;
9503 else
9504 allocated_count = 0;
9505 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009506 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009507 c2d.close();
9508 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009509 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009510 }
9511 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9512}
9513
9514OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9515 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9516{
9517 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9518 if (!enabled){
9519 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9520 return eRet;
9521 }
9522 if (enabled && omx->is_component_secure()) {
9523 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9524 omx->is_component_secure());
9525 return OMX_ErrorUnsupportedSetting;
9526 }
9527 if (!bufferHdr || bytes > buffer_size_req) {
9528 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009529 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009530 buffer_size_req,bytes);
9531 return OMX_ErrorBadParameter;
9532 }
9533 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9534 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9535 return OMX_ErrorInsufficientResources;
9536 }
9537 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9538 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9539 port,appData,omx->drv_ctx.op_buf.buffer_size);
9540 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9541 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9542 return eRet;
9543 }
9544 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9545 omx->drv_ctx.op_buf.actualcount) {
9546 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9547 (temp_bufferHdr - omx->m_out_mem_ptr));
9548 return OMX_ErrorUndefined;
9549 }
9550 unsigned int i = allocated_count;
9551#ifdef USE_ION
9552 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9553 buffer_size_req,buffer_alignment_req,
9554 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009555 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009556 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9557 if (op_buf_ion_info[i].ion_device_fd < 0) {
9558 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9559 return OMX_ErrorInsufficientResources;
9560 }
9561 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9562 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9563
9564 if (pmem_baseaddress[i] == MAP_FAILED) {
9565 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9566 close(pmem_fd[i]);
9567 omx->free_ion_memory(&op_buf_ion_info[i]);
9568 return OMX_ErrorInsufficientResources;
9569 }
9570 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9571 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9572 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9573#endif
9574 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9575 m_pmem_info_client[i].offset = 0;
9576 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9577 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9578 m_platform_list_client[i].nEntries = 1;
9579 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9580 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9581 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9582 m_out_mem_ptr_client[i].nFilledLen = 0;
9583 m_out_mem_ptr_client[i].nFlags = 0;
9584 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9585 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9586 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9587 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9588 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9589 m_out_mem_ptr_client[i].pAppPrivate = appData;
9590 *bufferHdr = &m_out_mem_ptr_client[i];
9591 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9592 allocated_count++;
9593 return eRet;
9594}
9595
9596bool omx_vdec::is_component_secure()
9597{
9598 return secure_mode;
9599}
9600
9601bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9602{
9603 bool status = true;
9604 if (!enabled) {
9605 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9606 dest_color_format = (OMX_COLOR_FORMATTYPE)
9607 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9608 else
9609 status = false;
9610 } else {
9611 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9612 status = false;
9613 } else
9614 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9615 }
9616 return status;
9617}