blob: ef3fd21c6fe753cc0e784c5434003456a39d7a8b [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),
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530540 m_profile(0),
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800541 h264_last_au_ts(LLONG_MAX),
542 h264_last_au_flags(0),
543 prev_ts(LLONG_MAX),
544 rst_prev_ts(true),
545 frm_int(0),
Praneeth Paladugud0881ef2013-04-23 23:02:55 -0700546 m_disp_hor_size(0),
547 m_disp_vert_size(0),
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800548 in_reconfig(false),
549 m_display_id(NULL),
550 h264_parser(NULL),
551 client_extradata(0),
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530552 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700553#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800554 m_enable_android_native_buffers(OMX_FALSE),
555 m_use_android_native_buffers(OMX_FALSE),
556 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700557#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800558 m_desc_buffer_ptr(NULL),
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -0700559 secure_mode(false),
560 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700561{
562 /* Assumption is that , to begin with , we have all the frames with decoder */
563 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
564#ifdef _ANDROID_
565 char property_value[PROPERTY_VALUE_MAX] = {0};
566 property_get("vidc.dec.debug.perf", property_value, "0");
567 perf_flag = atoi(property_value);
568 if (perf_flag)
569 {
570 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
571 dec_time.start();
572 proc_frms = latency = 0;
573 }
Vinay Kaliab9e98102013-04-02 19:31:43 -0700574 prev_n_filled_len = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -0800575 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700576 property_get("vidc.dec.debug.ts", property_value, "0");
577 m_debug_timestamp = atoi(property_value);
578 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
579 if (m_debug_timestamp)
580 {
581 time_stamp_dts.set_timestamp_reorder_mode(true);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800582 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700583 }
584
Shalaj Jain286b0062013-02-21 20:35:48 -0800585 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700586 property_get("vidc.dec.debug.concealedmb", property_value, "0");
587 m_debug_concealedmb = atoi(property_value);
588 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
589
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530590 property_value[0] = '\0';
591 property_get("vidc.dec.profile.check", property_value, "0");
592 m_reject_avc_1080p_mp = atoi(property_value);
593 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
594
Shalaj Jain273b3e02012-06-22 19:08:03 -0700595#endif
596 memset(&m_cmp,0,sizeof(m_cmp));
597 memset(&m_cb,0,sizeof(m_cb));
598 memset (&drv_ctx,0,sizeof(drv_ctx));
599 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
600 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700601 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
602 m_demux_entries = 0;
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700603 msg_thread_id = 0;
604 async_thread_id = 0;
605 msg_thread_created = false;
606 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700607#ifdef _ANDROID_ICS_
608 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
609#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700610 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700611 drv_ctx.timestamp_adjust = false;
612 drv_ctx.video_driver_fd = -1;
613 m_vendor_config.pData = NULL;
614 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800615 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700616 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800617 streaming[CAPTURE_PORT] =
618 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700619#ifdef _ANDROID_
620 char extradata_value[PROPERTY_VALUE_MAX] = {0};
621 property_get("vidc.dec.debug.extradata", extradata_value, "0");
622 m_debug_extradata = atoi(extradata_value);
623 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
624#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800625 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
626 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700627}
628
Vinay Kalia85793762012-06-14 19:12:34 -0700629static const int event_type[] = {
630 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
631 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
632 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700633 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
634 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700635};
636
637static OMX_ERRORTYPE subscribe_to_events(int fd)
638{
639 OMX_ERRORTYPE eRet = OMX_ErrorNone;
640 struct v4l2_event_subscription sub;
641 int array_sz = sizeof(event_type)/sizeof(int);
642 int i,rc;
643 if (fd < 0) {
644 printf("Invalid input: %d\n", fd);
645 return OMX_ErrorBadParameter;
646 }
647
648 for (i = 0; i < array_sz; ++i) {
649 memset(&sub, 0, sizeof(sub));
650 sub.type = event_type[i];
651 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
652 if (rc) {
653 printf("Failed to subscribe event: 0x%x\n", sub.type);
654 break;
655 }
656 }
657 if (i < array_sz) {
658 for (--i; i >=0 ; i--) {
659 memset(&sub, 0, sizeof(sub));
660 sub.type = event_type[i];
661 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
662 if (rc)
663 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
664 }
665 eRet = OMX_ErrorNotImplemented;
666 }
667 return eRet;
668}
669
670
671static OMX_ERRORTYPE unsubscribe_to_events(int fd)
672{
673 OMX_ERRORTYPE eRet = OMX_ErrorNone;
674 struct v4l2_event_subscription sub;
675 int array_sz = sizeof(event_type)/sizeof(int);
676 int i,rc;
677 if (fd < 0) {
678 printf("Invalid input: %d\n", fd);
679 return OMX_ErrorBadParameter;
680 }
681
682 for (i = 0; i < array_sz; ++i) {
683 memset(&sub, 0, sizeof(sub));
684 sub.type = event_type[i];
685 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
686 if (rc) {
687 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
688 break;
689 }
690 }
691 return eRet;
692}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700693
694/* ======================================================================
695FUNCTION
696 omx_vdec::~omx_vdec
697
698DESCRIPTION
699 Destructor
700
701PARAMETERS
702 None
703
704RETURN VALUE
705 None.
706========================================================================== */
707omx_vdec::~omx_vdec()
708{
709 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700710 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700711 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
712 if(m_pipe_in) close(m_pipe_in);
713 if(m_pipe_out) close(m_pipe_out);
714 m_pipe_in = -1;
715 m_pipe_out = -1;
716 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700717 if (msg_thread_created)
718 pthread_join(msg_thread_id,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700719 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700720 dec.cmd = V4L2_DEC_CMD_STOP;
Vinay Kaliadae8ad62013-04-26 20:42:10 -0700721 if (drv_ctx.video_driver_fd >=0 ) {
722 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
723 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700724 }
Vinay Kalia184cd0f2013-04-29 18:26:42 -0700725 if (async_thread_created)
726 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700727 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728 close(drv_ctx.video_driver_fd);
729 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800730 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700731 sem_destroy(&m_cmd_lock);
732 if (perf_flag)
733 {
734 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
735 dec_time.end();
736 }
737 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
738}
739
Vinay Kaliafeef7032012-09-25 19:23:33 -0700740int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
741 struct v4l2_requestbuffers bufreq;
742 int rc = 0;
743 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
744 bufreq.memory = V4L2_MEMORY_USERPTR;
745 bufreq.count = 0;
746 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
747 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
748 }
749 return rc;
750}
751
Shalaj Jain273b3e02012-06-22 19:08:03 -0700752/* ======================================================================
753FUNCTION
754 omx_vdec::OMXCntrlProcessMsgCb
755
756DESCRIPTION
757 IL Client callbacks are generated through this routine. The decoder
758 provides the thread context for this routine.
759
760PARAMETERS
761 ctxt -- Context information related to the self.
762 id -- Event identifier. This could be any of the following:
763 1. Command completion event
764 2. Buffer done callback event
765 3. Frame done callback event
766
767RETURN VALUE
768 None.
769
770========================================================================== */
771void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
772{
Shalaj Jain286b0062013-02-21 20:35:48 -0800773 signed p1; // Parameter - 1
774 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700775 unsigned ident;
776 unsigned qsize=0; // qsize
777 omx_vdec *pThis = (omx_vdec *) ctxt;
778
779 if(!pThis)
780 {
781 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
782 __func__);
783 return;
784 }
785
786 // Protect the shared queue data structure
787 do
788 {
789 /*Read the message id's from the queue*/
790 pthread_mutex_lock(&pThis->m_lock);
791 qsize = pThis->m_cmd_q.m_size;
792 if(qsize)
793 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800794 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700795 }
796
797 if (qsize == 0 && pThis->m_state != OMX_StatePause)
798 {
799 qsize = pThis->m_ftb_q.m_size;
800 if (qsize)
801 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800802 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803 }
804 }
805
806 if (qsize == 0 && pThis->m_state != OMX_StatePause)
807 {
808 qsize = pThis->m_etb_q.m_size;
809 if (qsize)
810 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800811 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700812 }
813 }
814 pthread_mutex_unlock(&pThis->m_lock);
815
816 /*process message if we have one*/
817 if(qsize > 0)
818 {
819 id = ident;
820 switch (id)
821 {
822 case OMX_COMPONENT_GENERATE_EVENT:
823 if (pThis->m_cb.EventHandler)
824 {
825 switch (p1)
826 {
827 case OMX_CommandStateSet:
828 pThis->m_state = (OMX_STATETYPE) p2;
829 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
830 pThis->m_state);
831 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
832 OMX_EventCmdComplete, p1, p2, NULL);
833 break;
834
835 case OMX_EventError:
836 if(p2 == OMX_StateInvalid)
837 {
838 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
839 pThis->m_state = (OMX_STATETYPE) p2;
840 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
841 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
842 }
843 else if (p2 == OMX_ErrorHardware)
844 {
845 pThis->omx_report_error();
846 }
847 else
848 {
849 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800850 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700851 }
852 break;
853
854 case OMX_CommandPortDisable:
855 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
856 if (BITMASK_PRESENT(&pThis->m_flags,
857 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
858 {
859 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
860 break;
861 }
Deva Ramasubramanian37651692013-05-09 20:24:10 -0700862 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700863 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700864 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700865 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700866 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
867 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
868 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700869 pThis->in_reconfig = false;
870 if(eRet != OMX_ErrorNone)
871 {
872 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
873 pThis->omx_report_error();
874 break;
875 }
876 }
877 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
878 OMX_EventCmdComplete, p1, p2, NULL );
879 break;
880 case OMX_CommandPortEnable:
881 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
882 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
883 OMX_EventCmdComplete, p1, p2, NULL );
884 break;
885
886 default:
887 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
888 OMX_EventCmdComplete, p1, p2, NULL );
889 break;
890
891 }
892 }
893 else
894 {
895 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
896 }
897 break;
898 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
899 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
900 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
901 {
902 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
903 pThis->omx_report_error ();
904 }
905 break;
906 case OMX_COMPONENT_GENERATE_ETB:
907 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
908 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
909 {
910 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
911 pThis->omx_report_error ();
912 }
913 break;
914
915 case OMX_COMPONENT_GENERATE_FTB:
916 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
917 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
918 {
919 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
920 pThis->omx_report_error ();
921 }
922 break;
923
924 case OMX_COMPONENT_GENERATE_COMMAND:
925 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
926 (OMX_U32)p2,(OMX_PTR)NULL);
927 break;
928
929 case OMX_COMPONENT_GENERATE_EBD:
930
931 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
932 {
933 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
934 pThis->omx_report_error ();
935 }
936 else
937 {
938 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
939 {
940 pThis->m_inp_err_count++;
941 pThis->time_stamp_dts.remove_time_stamp(
942 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
943 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
944 ?true:false);
945 }
946 else
947 {
948 pThis->m_inp_err_count = 0;
949 }
950 if ( pThis->empty_buffer_done(&pThis->m_cmp,
951 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
952 {
953 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
954 pThis->omx_report_error ();
955 }
956 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
957 {
958 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
959 pThis->omx_report_error ();
960 }
961 }
962 break;
963 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
964 {
965 int64_t *timestamp = (int64_t *)p1;
966 if (p1)
967 {
968 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
969 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
970 ?true:false);
971 free(timestamp);
972 }
973 }
974 break;
975 case OMX_COMPONENT_GENERATE_FBD:
976 if (p2 != VDEC_S_SUCCESS)
977 {
978 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
979 pThis->omx_report_error ();
980 }
981 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
982 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
983 {
984 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
985 pThis->omx_report_error ();
986 }
987 break;
988
989 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
990 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
991 if (!pThis->input_flush_progress)
992 {
993 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
994 }
995 else
996 {
997 pThis->execute_input_flush();
998 if (pThis->m_cb.EventHandler)
999 {
1000 if (p2 != VDEC_S_SUCCESS)
1001 {
1002 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
1003 pThis->omx_report_error ();
1004 }
1005 else
1006 {
1007 /*Check if we need generate event for Flush done*/
1008 if(BITMASK_PRESENT(&pThis->m_flags,
1009 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1010 {
1011 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1012 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1013 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1014 OMX_EventCmdComplete,OMX_CommandFlush,
1015 OMX_CORE_INPUT_PORT_INDEX,NULL );
1016 }
1017 if (BITMASK_PRESENT(&pThis->m_flags,
1018 OMX_COMPONENT_IDLE_PENDING))
1019 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001020 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001021 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1022 pThis->omx_report_error ();
1023 } else {
1024 pThis->streaming[OUTPUT_PORT] = false;
1025 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001026 if (!pThis->output_flush_progress)
1027 {
Vinay Kalia22046272012-09-28 20:16:05 -07001028 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001029 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001030 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001031 }
1032 }
1033 }
1034 }
1035 else
1036 {
1037 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1038 }
1039 }
1040 break;
1041
1042 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1043 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1044 if (!pThis->output_flush_progress)
1045 {
1046 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1047 }
1048 else
1049 {
1050 pThis->execute_output_flush();
1051 if (pThis->m_cb.EventHandler)
1052 {
1053 if (p2 != VDEC_S_SUCCESS)
1054 {
1055 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1056 pThis->omx_report_error ();
1057 }
1058 else
1059 {
1060 /*Check if we need generate event for Flush done*/
1061 if(BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1063 {
1064 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1065 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1066 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1067 OMX_EventCmdComplete,OMX_CommandFlush,
1068 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1069 }
1070 if(BITMASK_PRESENT(&pThis->m_flags,
1071 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1072 {
1073 DEBUG_PRINT_LOW("\n Internal flush complete");
1074 BITMASK_CLEAR (&pThis->m_flags,
1075 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1076 if (BITMASK_PRESENT(&pThis->m_flags,
1077 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1078 {
1079 pThis->post_event(OMX_CommandPortDisable,
1080 OMX_CORE_OUTPUT_PORT_INDEX,
1081 OMX_COMPONENT_GENERATE_EVENT);
1082 BITMASK_CLEAR (&pThis->m_flags,
1083 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1084
1085 }
1086 }
1087
1088 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1089 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001090 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001091 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1092 pThis->omx_report_error ();
1093 break;
1094 }
1095 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001096 if (!pThis->input_flush_progress)
1097 {
Vinay Kalia22046272012-09-28 20:16:05 -07001098 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001099 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001100 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001101 }
1102 }
1103 }
1104 }
1105 else
1106 {
1107 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1108 }
1109 }
1110 break;
1111
1112 case OMX_COMPONENT_GENERATE_START_DONE:
1113 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1114
1115 if (pThis->m_cb.EventHandler)
1116 {
1117 if (p2 != VDEC_S_SUCCESS)
1118 {
1119 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1120 pThis->omx_report_error ();
1121 }
1122 else
1123 {
1124 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1125 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1126 {
1127 DEBUG_PRINT_LOW("\n Move to executing");
1128 // Send the callback now
1129 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1130 pThis->m_state = OMX_StateExecuting;
1131 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1132 OMX_EventCmdComplete,OMX_CommandStateSet,
1133 OMX_StateExecuting, NULL);
1134 }
1135 else if (BITMASK_PRESENT(&pThis->m_flags,
1136 OMX_COMPONENT_PAUSE_PENDING))
1137 {
1138 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1139 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1140 {
1141 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1142 pThis->omx_report_error ();
1143 }
1144 }
1145 }
1146 }
1147 else
1148 {
1149 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1150 }
1151 break;
1152
1153 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1154 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1155 if (pThis->m_cb.EventHandler)
1156 {
1157 if (p2 != VDEC_S_SUCCESS)
1158 {
1159 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1160 pThis->omx_report_error ();
1161 }
1162 else
1163 {
1164 pThis->complete_pending_buffer_done_cbs();
1165 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1166 {
1167 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1168 //Send the callback now
1169 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1170 pThis->m_state = OMX_StatePause;
1171 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1172 OMX_EventCmdComplete,OMX_CommandStateSet,
1173 OMX_StatePause, NULL);
1174 }
1175 }
1176 }
1177 else
1178 {
1179 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1180 }
1181
1182 break;
1183
1184 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1185 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1186 if (pThis->m_cb.EventHandler)
1187 {
1188 if (p2 != VDEC_S_SUCCESS)
1189 {
1190 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1191 pThis->omx_report_error ();
1192 }
1193 else
1194 {
1195 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1196 {
1197 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1198 // Send the callback now
1199 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1200 pThis->m_state = OMX_StateExecuting;
1201 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1202 OMX_EventCmdComplete,OMX_CommandStateSet,
1203 OMX_StateExecuting,NULL);
1204 }
1205 }
1206 }
1207 else
1208 {
1209 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1210 }
1211
1212 break;
1213
1214 case OMX_COMPONENT_GENERATE_STOP_DONE:
1215 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1216 if (pThis->m_cb.EventHandler)
1217 {
1218 if (p2 != VDEC_S_SUCCESS)
1219 {
1220 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1221 pThis->omx_report_error ();
1222 }
1223 else
1224 {
1225 pThis->complete_pending_buffer_done_cbs();
1226 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1227 {
1228 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1229 // Send the callback now
1230 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1231 pThis->m_state = OMX_StateIdle;
1232 DEBUG_PRINT_LOW("\n Move to Idle State");
1233 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1234 OMX_EventCmdComplete,OMX_CommandStateSet,
1235 OMX_StateIdle,NULL);
1236 }
1237 }
1238 }
1239 else
1240 {
1241 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1242 }
1243
1244 break;
1245
1246 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1247 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001248
Vinay Kalia592e4b42012-12-19 15:55:47 -08001249 if (p2 == OMX_IndexParamPortDefinition) {
1250 pThis->in_reconfig = true;
1251 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001252 if (pThis->m_cb.EventHandler) {
1253 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001254 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001255 } else {
1256 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1257 }
1258
1259 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001260 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001261 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1262 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1263 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1264 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1265 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1266 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1267 else //unsupported interlace format; raise a error
1268 event = OMX_EventError;
1269 if (pThis->m_cb.EventHandler) {
1270 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1271 event, format, 0, NULL );
1272 } else {
1273 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001274 }
1275 }
1276 break;
1277
1278 case OMX_COMPONENT_GENERATE_EOS_DONE:
1279 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1280 if (pThis->m_cb.EventHandler) {
1281 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1282 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1283 } else {
1284 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1285 }
1286 pThis->prev_ts = LLONG_MAX;
1287 pThis->rst_prev_ts = true;
1288 break;
1289
1290 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1291 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1292 pThis->omx_report_error ();
1293 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001294
1295 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1296 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1297 pThis->omx_report_unsupported_setting();
1298 break;
1299
Shalaj Jain273b3e02012-06-22 19:08:03 -07001300 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1301 {
1302 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1303 if (pThis->m_cb.EventHandler) {
1304 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1305 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1306 } else {
1307 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1308 }
1309 }
1310 default:
1311 break;
1312 }
1313 }
1314 pthread_mutex_lock(&pThis->m_lock);
1315 qsize = pThis->m_cmd_q.m_size;
1316 if (pThis->m_state != OMX_StatePause)
1317 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1318 pthread_mutex_unlock(&pThis->m_lock);
1319 }
1320 while(qsize>0);
1321
1322}
1323
Vinay Kaliab9e98102013-04-02 19:31:43 -07001324int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001325{
Vinay Kaliab9e98102013-04-02 19:31:43 -07001326 int format_changed = 0;
1327 if ((height != drv_ctx.video_resolution.frame_height) ||
Vinay Kalia0321dc12013-04-08 20:45:54 -07001328 (width != drv_ctx.video_resolution.frame_width)) {
1329 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1330 width, drv_ctx.video_resolution.frame_width,
1331 height,drv_ctx.video_resolution.frame_height);
Vinay Kaliab9e98102013-04-02 19:31:43 -07001332 format_changed = 1;
Vinay Kalia0321dc12013-04-08 20:45:54 -07001333 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001334 drv_ctx.video_resolution.frame_height = height;
1335 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001336 drv_ctx.video_resolution.scan_lines = scan_lines;
1337 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001338 rectangle.nLeft = 0;
1339 rectangle.nTop = 0;
1340 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1341 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Vinay Kaliab9e98102013-04-02 19:31:43 -07001342 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001343}
1344
Arun Menon6836ba02013-02-19 20:37:40 -08001345OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1346{
Arun Menon888aa852013-05-30 11:24:42 -07001347 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +05301348 OMX_MAX_STRINGNAME_SIZE) &&
1349 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1350 m_decoder_capability.max_width = 1280;
1351 m_decoder_capability.max_height = 720;
1352 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
Arun Menon888aa852013-05-30 11:24:42 -07001353 }
Arun Menon888aa852013-05-30 11:24:42 -07001354
Arun Menonc10115b2013-04-26 17:56:34 -07001355 if ((drv_ctx.video_resolution.frame_width *
1356 drv_ctx.video_resolution.frame_height >
1357 m_decoder_capability.max_width *
1358 m_decoder_capability.max_height) ||
1359 (drv_ctx.video_resolution.frame_width*
1360 drv_ctx.video_resolution.frame_height <
1361 m_decoder_capability.min_width *
1362 m_decoder_capability.min_height))
1363 {
1364 DEBUG_PRINT_ERROR(
1365 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1366 drv_ctx.video_resolution.frame_width,
1367 drv_ctx.video_resolution.frame_height,
1368 m_decoder_capability.min_width,
1369 m_decoder_capability.min_height,
1370 m_decoder_capability.max_width,
1371 m_decoder_capability.max_height);
Arun Menon6836ba02013-02-19 20:37:40 -08001372 return OMX_ErrorUnsupportedSetting;
1373 }
1374 DEBUG_PRINT_HIGH("\n video session supported\n");
1375 return OMX_ErrorNone;
1376}
1377
Shalaj Jain273b3e02012-06-22 19:08:03 -07001378/* ======================================================================
1379FUNCTION
1380 omx_vdec::ComponentInit
1381
1382DESCRIPTION
1383 Initialize the component.
1384
1385PARAMETERS
1386 ctxt -- Context information related to the self.
1387 id -- Event identifier. This could be any of the following:
1388 1. Command completion event
1389 2. Buffer done callback event
1390 3. Frame done callback event
1391
1392RETURN VALUE
1393 None.
1394
1395========================================================================== */
1396OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1397{
1398
1399 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001400 struct v4l2_fmtdesc fdesc;
1401 struct v4l2_format fmt;
1402 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001403 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001404 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001405 unsigned int alignment = 0,buffer_size = 0;
1406 int fds[2];
1407 int r,ret=0;
1408 bool codec_ambiguous = false;
Sachin Shahc82a18f2013-03-29 14:45:38 -07001409 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
1410
1411#ifdef _ANDROID_
1412 char platform_name[64];
1413 property_get("ro.board.platform", platform_name, "0");
1414 if (!strncmp(platform_name, "msm8610", 7)) {
1415 device_name = (OMX_STRING)"/dev/video/q6_dec";
1416 }
1417#endif
1418
Vinay Kalia53fa6832012-10-11 17:55:30 -07001419 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1420 struct v4l2_control control;
1421 secure_mode = true;
1422 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001423 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001424 }
1425
Sachin Shahc82a18f2013-03-29 14:45:38 -07001426 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001427
1428 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1429 drv_ctx.video_driver_fd, errno);
1430
1431 if(drv_ctx.video_driver_fd == 0){
Vinay Kalia4d17ce32013-05-22 17:10:35 -07001432 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1433 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1434 close(0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001435 }
1436
1437 if(drv_ctx.video_driver_fd < 0)
1438 {
1439 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1440 return OMX_ErrorInsufficientResources;
1441 }
1442 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1443 drv_ctx.frame_rate.fps_denominator = 1;
1444
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001445 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001446 if (!ret) {
1447 async_thread_created = true;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001448 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001449 }
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001450 if(ret) {
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001451 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001452 async_thread_created = false;
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001453 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001455
1456#ifdef INPUT_BUFFER_LOG
1457 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1458#endif
1459#ifdef OUTPUT_BUFFER_LOG
1460 outputBufferFile1 = fopen (outputfilename, "ab");
1461#endif
1462#ifdef OUTPUT_EXTRADATA_LOG
1463 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1464#endif
1465
1466 // Copy the role information which provides the decoder kind
1467 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001468
Shalaj Jain273b3e02012-06-22 19:08:03 -07001469 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1470 OMX_MAX_STRINGNAME_SIZE))
1471 {
1472 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1473 OMX_MAX_STRINGNAME_SIZE);
1474 drv_ctx.timestamp_adjust = true;
1475 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1476 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001477 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001478 /*Initialize Start Code for MPEG4*/
1479 codec_type_parse = CODEC_TYPE_MPEG4;
1480 m_frame_parser.init_start_codes (codec_type_parse);
1481#ifdef INPUT_BUFFER_LOG
1482 strcat(inputfilename, "m4v");
1483#endif
1484 }
1485 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1486 OMX_MAX_STRINGNAME_SIZE))
1487 {
1488 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1489 OMX_MAX_STRINGNAME_SIZE);
1490 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001491 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001492 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1493 /*Initialize Start Code for MPEG2*/
1494 codec_type_parse = CODEC_TYPE_MPEG2;
1495 m_frame_parser.init_start_codes (codec_type_parse);
1496#ifdef INPUT_BUFFER_LOG
1497 strcat(inputfilename, "mpg");
1498#endif
1499 }
1500 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1501 OMX_MAX_STRINGNAME_SIZE))
1502 {
1503 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1504 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1505 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1506 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001507 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001508 codec_type_parse = CODEC_TYPE_H263;
1509 m_frame_parser.init_start_codes (codec_type_parse);
1510#ifdef INPUT_BUFFER_LOG
1511 strcat(inputfilename, "263");
1512#endif
1513 }
1514 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1515 OMX_MAX_STRINGNAME_SIZE))
1516 {
1517 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1518 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1519 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1520 output_capability = V4L2_PIX_FMT_DIVX_311;
1521 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1522 codec_type_parse = CODEC_TYPE_DIVX;
1523 m_frame_parser.init_start_codes (codec_type_parse);
1524
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001525 eRet = createDivxDrmContext();
1526 if (eRet != OMX_ErrorNone) {
1527 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1528 return eRet;
1529 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001530 }
1531 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1532 OMX_MAX_STRINGNAME_SIZE))
1533 {
1534 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1535 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1536 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1537 output_capability = V4L2_PIX_FMT_DIVX;
1538 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1539 codec_type_parse = CODEC_TYPE_DIVX;
1540 codec_ambiguous = true;
1541 m_frame_parser.init_start_codes (codec_type_parse);
1542
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001543 eRet = createDivxDrmContext();
1544 if (eRet != OMX_ErrorNone) {
1545 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1546 return eRet;
1547 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001548 }
1549 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1550 OMX_MAX_STRINGNAME_SIZE))
1551 {
1552 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1553 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1554 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1555 output_capability = V4L2_PIX_FMT_DIVX;
1556 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1557 codec_type_parse = CODEC_TYPE_DIVX;
1558 codec_ambiguous = true;
1559 m_frame_parser.init_start_codes (codec_type_parse);
1560
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001561 eRet = createDivxDrmContext();
1562 if (eRet != OMX_ErrorNone) {
1563 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1564 return eRet;
1565 }
1566
Shalaj Jain273b3e02012-06-22 19:08:03 -07001567 }
1568 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1569 OMX_MAX_STRINGNAME_SIZE))
1570 {
1571 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1572 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1573 output_capability=V4L2_PIX_FMT_H264;
1574 eCompressionFormat = OMX_VIDEO_CodingAVC;
1575 codec_type_parse = CODEC_TYPE_H264;
1576 m_frame_parser.init_start_codes (codec_type_parse);
1577 m_frame_parser.init_nal_length(nal_length);
1578#ifdef INPUT_BUFFER_LOG
1579 strcat(inputfilename, "264");
1580#endif
1581 }
1582 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1583 OMX_MAX_STRINGNAME_SIZE))
1584 {
1585 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1586 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1587 eCompressionFormat = OMX_VIDEO_CodingWMV;
1588 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001589 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001590 m_frame_parser.init_start_codes (codec_type_parse);
1591#ifdef INPUT_BUFFER_LOG
1592 strcat(inputfilename, "vc1");
1593#endif
1594 }
1595 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1596 OMX_MAX_STRINGNAME_SIZE))
1597 {
1598 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1599 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1600 eCompressionFormat = OMX_VIDEO_CodingWMV;
1601 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001602 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001603 m_frame_parser.init_start_codes (codec_type_parse);
1604#ifdef INPUT_BUFFER_LOG
1605 strcat(inputfilename, "vc1");
1606#endif
1607 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001608 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1609 OMX_MAX_STRINGNAME_SIZE))
1610 {
1611 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1612 output_capability=V4L2_PIX_FMT_VP8;
1613 eCompressionFormat = OMX_VIDEO_CodingVPX;
1614 codec_type_parse = CODEC_TYPE_VP8;
1615 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001616#ifdef INPUT_BUFFER_LOG
1617 strcat(inputfilename, "ivf");
1618#endif
1619
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001621 else
1622 {
1623 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1624 eRet = OMX_ErrorInvalidComponentName;
1625 }
1626#ifdef INPUT_BUFFER_LOG
1627 inputBufferFile1 = fopen (inputfilename, "ab");
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001628 if (output_capability == V4L2_PIX_FMT_VP8) {
1629 struct ivf_file_header
1630 {
1631 OMX_U8 signature[4]; //='DKIF';
1632 OMX_U8 version ; //= 0;
1633 OMX_U8 headersize ; //= 32;
1634 OMX_U32 FourCC;
1635 OMX_U8 width;
1636 OMX_U8 height;
1637 OMX_U32 rate;
1638 OMX_U32 scale;
1639 OMX_U32 length;
1640 OMX_U8 unused[4];
1641 } file_header;
1642 memset((void *)&file_header,0,sizeof(file_header));
1643 file_header.signature[0] = 'D';
1644 file_header.signature[1] = 'K';
1645 file_header.signature[2] = 'I';
1646 file_header.signature[3] = 'F';
1647 file_header.version = 0;
1648 file_header.headersize = 32;
1649 file_header.FourCC = 0x30385056;
1650 if (inputBufferFile1)
1651 {
1652 fwrite((const char *)&file_header,
1653 sizeof(file_header),1,inputBufferFile1);
1654 }
1655 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001656#endif
1657 if (eRet == OMX_ErrorNone)
1658 {
1659
Vinay Kaliada4f4422013-01-09 10:45:03 -08001660 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1661 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1662 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1663 if (!client_buffers.set_color_format(dest_color_format)) {
1664 DEBUG_PRINT_ERROR("\n Setting color format failed");
1665 eRet = OMX_ErrorInsufficientResources;
1666 }
1667
Shalaj Jain273b3e02012-06-22 19:08:03 -07001668 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001669
1670 struct v4l2_capability cap;
1671 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1672 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001673 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jainaa459962013-05-23 19:12:00 -07001674 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001675 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001676 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001677 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1678 cap.bus_info, cap.version, cap.capabilities);
1679 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001680 ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001681 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1682 fdesc.index=0;
1683 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001684 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001685 fdesc.pixelformat, fdesc.flags);
1686 fdesc.index++;
1687 }
1688 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1689 fdesc.index=0;
1690 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1691
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001692 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693 fdesc.pixelformat, fdesc.flags);
1694 fdesc.index++;
1695 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001696 update_resolution(320, 240, 320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001697 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1698 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1699 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1700 fmt.fmt.pix_mp.pixelformat = output_capability;
1701 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1702 if (ret) {
1703 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001704 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Praneeth Paladugub227af72013-05-08 01:33:06 -07001705 return OMX_ErrorInsufficientResources;
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001706 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001707 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001708 if (codec_ambiguous) {
1709 if (output_capability == V4L2_PIX_FMT_DIVX) {
1710 struct v4l2_control divx_ctrl;
1711
1712 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001713 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001714 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001715 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001716 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001717 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001718 }
1719
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001720 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001721 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001722 if (ret) {
1723 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1724 }
1725 } else {
1726 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1727 }
1728 }
1729
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001730 //Get the hardware capabilities
1731 memset((void *)&frmsize,0,sizeof(frmsize));
1732 frmsize.index = 0;
1733 frmsize.pixel_format = output_capability;
1734 ret = ioctl(drv_ctx.video_driver_fd,
1735 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1736 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1737 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1738 return OMX_ErrorHardware;
1739 }
1740
1741 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1742 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1743 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1744 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1745 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1746 }
1747
Shalaj Jain273b3e02012-06-22 19:08:03 -07001748 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1749 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1750 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001751 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001752 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1753 if (ret) {
1754 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001755 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001756 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001757 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001758 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001759 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1760 control.value = 1;
1761 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1762 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1763 if (ret) {
1764 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001765 return OMX_ErrorInsufficientResources;
1766 }
1767 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001768
1769 /*Get the Buffer requirements for input and output ports*/
1770 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1771 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001772 if (secure_mode) {
1773 drv_ctx.op_buf.alignment=SZ_1M;
1774 drv_ctx.ip_buf.alignment=SZ_1M;
1775 } else {
1776 drv_ctx.op_buf.alignment=SZ_4K;
1777 drv_ctx.ip_buf.alignment=SZ_4K;
1778 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001779 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1780 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001781 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1782 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1783 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1784 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001785 drv_ctx.idr_only_decoding = 0;
1786
Vinay Kalia5713bb32013-01-16 18:39:59 -08001787 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001788#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001789 if (eRet == OMX_ErrorNone && !secure_mode)
1790 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001791#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001792 eRet=get_buffer_req(&drv_ctx.ip_buf);
1793 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1794 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001795 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1796 {
1797 if (m_frame_parser.mutils == NULL)
1798 {
1799 m_frame_parser.mutils = new H264_Utils();
1800
1801 if (m_frame_parser.mutils == NULL)
1802 {
1803 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1804 eRet = OMX_ErrorInsufficientResources;
1805 }
1806 else
1807 {
1808 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1809 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1810 h264_scratch.nFilledLen = 0;
1811 h264_scratch.nOffset = 0;
1812
1813 if (h264_scratch.pBuffer == NULL)
1814 {
1815 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1816 return OMX_ErrorInsufficientResources;
1817 }
1818 m_frame_parser.mutils->initialize_frame_checking_environment();
1819 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1820 }
1821 }
1822
1823 h264_parser = new h264_stream_parser();
1824 if (!h264_parser)
1825 {
1826 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1827 eRet = OMX_ErrorInsufficientResources;
1828 }
1829 }
1830
1831 if(pipe(fds))
1832 {
1833 DEBUG_PRINT_ERROR("pipe creation failed\n");
1834 eRet = OMX_ErrorInsufficientResources;
1835 }
1836 else
1837 {
1838 int temp1[2];
1839 if(fds[0] == 0 || fds[1] == 0)
1840 {
1841 if (pipe (temp1))
1842 {
1843 DEBUG_PRINT_ERROR("pipe creation failed\n");
1844 return OMX_ErrorInsufficientResources;
1845 }
1846 //close (fds[0]);
1847 //close (fds[1]);
1848 fds[0] = temp1 [0];
1849 fds[1] = temp1 [1];
1850 }
1851 m_pipe_in = fds[0];
1852 m_pipe_out = fds[1];
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001853 msg_thread_created = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854 r = pthread_create(&msg_thread_id,0,message_thread,this);
1855
1856 if(r < 0)
1857 {
1858 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001859 msg_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001860 eRet = OMX_ErrorInsufficientResources;
1861 }
1862 }
1863 }
1864
1865 if (eRet != OMX_ErrorNone)
1866 {
1867 DEBUG_PRINT_ERROR("\n Component Init Failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001868 }
1869 else
1870 {
1871 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1872 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001873 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1874 return eRet;
1875}
1876
1877/* ======================================================================
1878FUNCTION
1879 omx_vdec::GetComponentVersion
1880
1881DESCRIPTION
1882 Returns the component version.
1883
1884PARAMETERS
1885 TBD.
1886
1887RETURN VALUE
1888 OMX_ErrorNone.
1889
1890========================================================================== */
1891OMX_ERRORTYPE omx_vdec::get_component_version
1892 (
1893 OMX_IN OMX_HANDLETYPE hComp,
1894 OMX_OUT OMX_STRING componentName,
1895 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1896 OMX_OUT OMX_VERSIONTYPE* specVersion,
1897 OMX_OUT OMX_UUIDTYPE* componentUUID
1898 )
1899{
1900 if(m_state == OMX_StateInvalid)
1901 {
1902 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1903 return OMX_ErrorInvalidState;
1904 }
1905 /* TBD -- Return the proper version */
1906 if (specVersion)
1907 {
1908 specVersion->nVersion = OMX_SPEC_VERSION;
1909 }
1910 return OMX_ErrorNone;
1911}
1912/* ======================================================================
1913FUNCTION
1914 omx_vdec::SendCommand
1915
1916DESCRIPTION
1917 Returns zero if all the buffers released..
1918
1919PARAMETERS
1920 None.
1921
1922RETURN VALUE
1923 true/false
1924
1925========================================================================== */
1926OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1927 OMX_IN OMX_COMMANDTYPE cmd,
1928 OMX_IN OMX_U32 param1,
1929 OMX_IN OMX_PTR cmdData
1930 )
1931{
1932 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1933 if(m_state == OMX_StateInvalid)
1934 {
1935 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1936 return OMX_ErrorInvalidState;
1937 }
1938 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1939 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1940 {
1941 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001942 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001943 return OMX_ErrorBadPortIndex;
1944 }
1945 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1946 sem_wait(&m_cmd_lock);
1947 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1948 return OMX_ErrorNone;
1949}
1950
1951/* ======================================================================
1952FUNCTION
1953 omx_vdec::SendCommand
1954
1955DESCRIPTION
1956 Returns zero if all the buffers released..
1957
1958PARAMETERS
1959 None.
1960
1961RETURN VALUE
1962 true/false
1963
1964========================================================================== */
1965OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1966 OMX_IN OMX_COMMANDTYPE cmd,
1967 OMX_IN OMX_U32 param1,
1968 OMX_IN OMX_PTR cmdData
1969 )
1970{
1971 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1972 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1973 int bFlag = 1,sem_posted = 0,ret=0;
1974
1975 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1976 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1977 m_state, eState);
1978
1979 if(cmd == OMX_CommandStateSet)
1980 {
1981 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1982 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1983 /***************************/
1984 /* Current State is Loaded */
1985 /***************************/
1986 if(m_state == OMX_StateLoaded)
1987 {
1988 if(eState == OMX_StateIdle)
1989 {
1990 //if all buffers are allocated or all ports disabled
1991 if(allocate_done() ||
1992 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1993 {
1994 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1995 }
1996 else
1997 {
1998 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1999 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2000 // Skip the event notification
2001 bFlag = 0;
2002 }
2003 }
2004 /* Requesting transition from Loaded to Loaded */
2005 else if(eState == OMX_StateLoaded)
2006 {
2007 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
2008 post_event(OMX_EventError,OMX_ErrorSameState,\
2009 OMX_COMPONENT_GENERATE_EVENT);
2010 eRet = OMX_ErrorSameState;
2011 }
2012 /* Requesting transition from Loaded to WaitForResources */
2013 else if(eState == OMX_StateWaitForResources)
2014 {
2015 /* Since error is None , we will post an event
2016 at the end of this function definition */
2017 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
2018 }
2019 /* Requesting transition from Loaded to Executing */
2020 else if(eState == OMX_StateExecuting)
2021 {
2022 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
2023 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2024 OMX_COMPONENT_GENERATE_EVENT);
2025 eRet = OMX_ErrorIncorrectStateTransition;
2026 }
2027 /* Requesting transition from Loaded to Pause */
2028 else if(eState == OMX_StatePause)
2029 {
2030 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
2031 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2032 OMX_COMPONENT_GENERATE_EVENT);
2033 eRet = OMX_ErrorIncorrectStateTransition;
2034 }
2035 /* Requesting transition from Loaded to Invalid */
2036 else if(eState == OMX_StateInvalid)
2037 {
2038 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
2039 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2040 eRet = OMX_ErrorInvalidState;
2041 }
2042 else
2043 {
2044 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
2045 eState);
2046 eRet = OMX_ErrorBadParameter;
2047 }
2048 }
2049
2050 /***************************/
2051 /* Current State is IDLE */
2052 /***************************/
2053 else if(m_state == OMX_StateIdle)
2054 {
2055 if(eState == OMX_StateLoaded)
2056 {
2057 if(release_done())
2058 {
2059 /*
2060 Since error is None , we will post an event at the end
2061 of this function definition
2062 */
2063 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
2064 }
2065 else
2066 {
2067 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2068 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2069 // Skip the event notification
2070 bFlag = 0;
2071 }
2072 }
2073 /* Requesting transition from Idle to Executing */
2074 else if(eState == OMX_StateExecuting)
2075 {
2076 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2077 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2078 bFlag = 1;
2079 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2080 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002081 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002082 }
2083 /* Requesting transition from Idle to Idle */
2084 else if(eState == OMX_StateIdle)
2085 {
2086 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2087 post_event(OMX_EventError,OMX_ErrorSameState,\
2088 OMX_COMPONENT_GENERATE_EVENT);
2089 eRet = OMX_ErrorSameState;
2090 }
2091 /* Requesting transition from Idle to WaitForResources */
2092 else if(eState == OMX_StateWaitForResources)
2093 {
2094 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2095 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2096 OMX_COMPONENT_GENERATE_EVENT);
2097 eRet = OMX_ErrorIncorrectStateTransition;
2098 }
2099 /* Requesting transition from Idle to Pause */
2100 else if(eState == OMX_StatePause)
2101 {
2102 /*To pause the Video core we need to start the driver*/
2103 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2104 NULL) < */0)
2105 {
2106 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2107 omx_report_error ();
2108 eRet = OMX_ErrorHardware;
2109 }
2110 else
2111 {
2112 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2113 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2114 bFlag = 0;
2115 }
2116 }
2117 /* Requesting transition from Idle to Invalid */
2118 else if(eState == OMX_StateInvalid)
2119 {
2120 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2121 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2122 eRet = OMX_ErrorInvalidState;
2123 }
2124 else
2125 {
2126 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2127 eRet = OMX_ErrorBadParameter;
2128 }
2129 }
2130
2131 /******************************/
2132 /* Current State is Executing */
2133 /******************************/
2134 else if(m_state == OMX_StateExecuting)
2135 {
2136 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2137 /* Requesting transition from Executing to Idle */
2138 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002139 {
2140 /* Since error is None , we will post an event
2141 at the end of this function definition
2142 */
2143 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002144 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002145 if(!sem_posted)
2146 {
2147 sem_posted = 1;
2148 sem_post (&m_cmd_lock);
2149 execute_omx_flush(OMX_ALL);
2150 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002151 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002152 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002153 /* Requesting transition from Executing to Paused */
2154 else if(eState == OMX_StatePause)
2155 {
2156 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002157 m_state = OMX_StatePause;
2158 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002159 }
2160 /* Requesting transition from Executing to Loaded */
2161 else if(eState == OMX_StateLoaded)
2162 {
2163 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2164 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2165 OMX_COMPONENT_GENERATE_EVENT);
2166 eRet = OMX_ErrorIncorrectStateTransition;
2167 }
2168 /* Requesting transition from Executing to WaitForResources */
2169 else if(eState == OMX_StateWaitForResources)
2170 {
2171 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2172 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2173 OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorIncorrectStateTransition;
2175 }
2176 /* Requesting transition from Executing to Executing */
2177 else if(eState == OMX_StateExecuting)
2178 {
2179 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2180 post_event(OMX_EventError,OMX_ErrorSameState,\
2181 OMX_COMPONENT_GENERATE_EVENT);
2182 eRet = OMX_ErrorSameState;
2183 }
2184 /* Requesting transition from Executing to Invalid */
2185 else if(eState == OMX_StateInvalid)
2186 {
2187 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2188 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2189 eRet = OMX_ErrorInvalidState;
2190 }
2191 else
2192 {
2193 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2194 eRet = OMX_ErrorBadParameter;
2195 }
2196 }
2197 /***************************/
2198 /* Current State is Pause */
2199 /***************************/
2200 else if(m_state == OMX_StatePause)
2201 {
2202 /* Requesting transition from Pause to Executing */
2203 if(eState == OMX_StateExecuting)
2204 {
2205 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002206 m_state = OMX_StateExecuting;
2207 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002208 }
2209 /* Requesting transition from Pause to Idle */
2210 else if(eState == OMX_StateIdle)
2211 {
2212 /* Since error is None , we will post an event
2213 at the end of this function definition */
2214 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2215 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2216 if(!sem_posted)
2217 {
2218 sem_posted = 1;
2219 sem_post (&m_cmd_lock);
2220 execute_omx_flush(OMX_ALL);
2221 }
2222 bFlag = 0;
2223 }
2224 /* Requesting transition from Pause to loaded */
2225 else if(eState == OMX_StateLoaded)
2226 {
2227 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2228 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2229 OMX_COMPONENT_GENERATE_EVENT);
2230 eRet = OMX_ErrorIncorrectStateTransition;
2231 }
2232 /* Requesting transition from Pause to WaitForResources */
2233 else if(eState == OMX_StateWaitForResources)
2234 {
2235 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2236 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2237 OMX_COMPONENT_GENERATE_EVENT);
2238 eRet = OMX_ErrorIncorrectStateTransition;
2239 }
2240 /* Requesting transition from Pause to Pause */
2241 else if(eState == OMX_StatePause)
2242 {
2243 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2244 post_event(OMX_EventError,OMX_ErrorSameState,\
2245 OMX_COMPONENT_GENERATE_EVENT);
2246 eRet = OMX_ErrorSameState;
2247 }
2248 /* Requesting transition from Pause to Invalid */
2249 else if(eState == OMX_StateInvalid)
2250 {
2251 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2252 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2253 eRet = OMX_ErrorInvalidState;
2254 }
2255 else
2256 {
2257 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2258 eRet = OMX_ErrorBadParameter;
2259 }
2260 }
2261 /***************************/
2262 /* Current State is WaitForResources */
2263 /***************************/
2264 else if(m_state == OMX_StateWaitForResources)
2265 {
2266 /* Requesting transition from WaitForResources to Loaded */
2267 if(eState == OMX_StateLoaded)
2268 {
2269 /* Since error is None , we will post an event
2270 at the end of this function definition */
2271 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2272 }
2273 /* Requesting transition from WaitForResources to WaitForResources */
2274 else if (eState == OMX_StateWaitForResources)
2275 {
2276 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2277 post_event(OMX_EventError,OMX_ErrorSameState,
2278 OMX_COMPONENT_GENERATE_EVENT);
2279 eRet = OMX_ErrorSameState;
2280 }
2281 /* Requesting transition from WaitForResources to Executing */
2282 else if(eState == OMX_StateExecuting)
2283 {
2284 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2285 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2286 OMX_COMPONENT_GENERATE_EVENT);
2287 eRet = OMX_ErrorIncorrectStateTransition;
2288 }
2289 /* Requesting transition from WaitForResources to Pause */
2290 else if(eState == OMX_StatePause)
2291 {
2292 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2293 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2294 OMX_COMPONENT_GENERATE_EVENT);
2295 eRet = OMX_ErrorIncorrectStateTransition;
2296 }
2297 /* Requesting transition from WaitForResources to Invalid */
2298 else if(eState == OMX_StateInvalid)
2299 {
2300 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2301 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2302 eRet = OMX_ErrorInvalidState;
2303 }
2304 /* Requesting transition from WaitForResources to Loaded -
2305 is NOT tested by Khronos TS */
2306
2307 }
2308 else
2309 {
2310 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2311 eRet = OMX_ErrorBadParameter;
2312 }
2313 }
2314 /********************************/
2315 /* Current State is Invalid */
2316 /*******************************/
2317 else if(m_state == OMX_StateInvalid)
2318 {
2319 /* State Transition from Inavlid to any state */
2320 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2321 || OMX_StateIdle || OMX_StateExecuting
2322 || OMX_StatePause || OMX_StateInvalid))
2323 {
2324 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2325 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2326 OMX_COMPONENT_GENERATE_EVENT);
2327 eRet = OMX_ErrorInvalidState;
2328 }
2329 }
2330 else if (cmd == OMX_CommandFlush)
2331 {
2332 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002333 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002334 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2335 {
2336 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2337 }
2338 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2339 {
2340 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2341 }
2342 if (!sem_posted){
2343 sem_posted = 1;
2344 DEBUG_PRINT_LOW("\n Set the Semaphore");
2345 sem_post (&m_cmd_lock);
2346 execute_omx_flush(param1);
2347 }
2348 bFlag = 0;
2349 }
2350 else if ( cmd == OMX_CommandPortEnable)
2351 {
2352 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002353 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002354 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2355 {
2356 m_inp_bEnabled = OMX_TRUE;
2357
2358 if( (m_state == OMX_StateLoaded &&
2359 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2360 || allocate_input_done())
2361 {
2362 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2363 OMX_COMPONENT_GENERATE_EVENT);
2364 }
2365 else
2366 {
2367 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2368 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2369 // Skip the event notification
2370 bFlag = 0;
2371 }
2372 }
2373 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2374 {
2375 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2376 m_out_bEnabled = OMX_TRUE;
2377
2378 if( (m_state == OMX_StateLoaded &&
2379 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2380 || (allocate_output_done()))
2381 {
2382 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2383 OMX_COMPONENT_GENERATE_EVENT);
2384
2385 }
2386 else
2387 {
2388 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2389 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2390 // Skip the event notification
2391 bFlag = 0;
2392 }
2393 }
2394 }
2395 else if (cmd == OMX_CommandPortDisable)
2396 {
2397 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002398 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002399 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2400 {
2401 m_inp_bEnabled = OMX_FALSE;
2402 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2403 && release_input_done())
2404 {
2405 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2406 OMX_COMPONENT_GENERATE_EVENT);
2407 }
2408 else
2409 {
2410 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2411 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2412 {
2413 if(!sem_posted)
2414 {
2415 sem_posted = 1;
2416 sem_post (&m_cmd_lock);
2417 }
2418 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2419 }
2420
2421 // Skip the event notification
2422 bFlag = 0;
2423 }
2424 }
2425 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2426 {
2427 m_out_bEnabled = OMX_FALSE;
2428 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2429 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2430 && release_output_done())
2431 {
2432 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2433 OMX_COMPONENT_GENERATE_EVENT);
2434 }
2435 else
2436 {
2437 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2438 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2439 {
2440 if (!sem_posted)
2441 {
2442 sem_posted = 1;
2443 sem_post (&m_cmd_lock);
2444 }
2445 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2446 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2447 }
2448 // Skip the event notification
2449 bFlag = 0;
2450
2451 }
2452 }
2453 }
2454 else
2455 {
2456 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2457 eRet = OMX_ErrorNotImplemented;
2458 }
2459 if(eRet == OMX_ErrorNone && bFlag)
2460 {
2461 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2462 }
2463 if(!sem_posted)
2464 {
2465 sem_post(&m_cmd_lock);
2466 }
2467
2468 return eRet;
2469}
2470
2471/* ======================================================================
2472FUNCTION
2473 omx_vdec::ExecuteOmxFlush
2474
2475DESCRIPTION
2476 Executes the OMX flush.
2477
2478PARAMETERS
2479 flushtype - input flush(1)/output flush(0)/ both.
2480
2481RETURN VALUE
2482 true/false
2483
2484========================================================================== */
2485bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2486{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002488 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002489 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002490 struct v4l2_decoder_cmd dec;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002491 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002492 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002493 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002494
2495 DEBUG_PRINT_ERROR("in %s: reconfig? %d", __func__, in_reconfig);
2496
2497 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002498 {
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002499 output_flush_progress = true;
2500 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2501 }
2502 else
2503 {
2504 /* XXX: The driver/hardware does not support flushing of individual ports
2505 * in all states. So we pretty much need to flush both ports internally,
2506 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2507 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2508 * we automatically omit sending the FLUSH done for the "opposite" port. */
2509 input_flush_progress = true;
2510 output_flush_progress = true;
2511 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002512 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002513
2514 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002515 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002516 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002517 bRet = false;
2518 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002519
Shalaj Jain273b3e02012-06-22 19:08:03 -07002520 return bRet;
2521}
2522/*=========================================================================
2523FUNCTION : execute_output_flush
2524
2525DESCRIPTION
2526 Executes the OMX flush at OUTPUT PORT.
2527
2528PARAMETERS
2529 None.
2530
2531RETURN VALUE
2532 true/false
2533==========================================================================*/
2534bool omx_vdec::execute_output_flush()
2535{
2536 unsigned p1 = 0; // Parameter - 1
2537 unsigned p2 = 0; // Parameter - 2
2538 unsigned ident = 0;
2539 bool bRet = true;
2540
2541 /*Generate FBD for all Buffers in the FTBq*/
2542 pthread_mutex_lock(&m_lock);
2543 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2544 while (m_ftb_q.m_size)
2545 {
2546 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2547 m_ftb_q.m_size,pending_output_buffers);
2548 m_ftb_q.pop_entry(&p1,&p2,&ident);
2549 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002550 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002551 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002552 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002553 }
2554 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2555 {
2556 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2557 }
2558 }
2559 pthread_mutex_unlock(&m_lock);
2560 output_flush_progress = false;
2561
2562 if (arbitrary_bytes)
2563 {
2564 prev_ts = LLONG_MAX;
2565 rst_prev_ts = true;
2566 }
2567 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2568 return bRet;
2569}
2570/*=========================================================================
2571FUNCTION : execute_input_flush
2572
2573DESCRIPTION
2574 Executes the OMX flush at INPUT PORT.
2575
2576PARAMETERS
2577 None.
2578
2579RETURN VALUE
2580 true/false
2581==========================================================================*/
2582bool omx_vdec::execute_input_flush()
2583{
2584 unsigned i =0;
2585 unsigned p1 = 0; // Parameter - 1
2586 unsigned p2 = 0; // Parameter - 2
2587 unsigned ident = 0;
2588 bool bRet = true;
2589
2590 /*Generate EBD for all Buffers in the ETBq*/
2591 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2592
2593 pthread_mutex_lock(&m_lock);
2594 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2595 while (m_etb_q.m_size)
2596 {
2597 m_etb_q.pop_entry(&p1,&p2,&ident);
2598
2599 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2600 {
2601 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2602 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2603 }
2604 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2605 {
2606 pending_input_buffers++;
2607 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2608 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2609 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2610 }
2611 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2612 {
2613 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2614 (OMX_BUFFERHEADERTYPE *)p1);
2615 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2616 }
2617 }
2618 time_stamp_dts.flush_timestamp();
2619 /*Check if Heap Buffers are to be flushed*/
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07002620 if (arbitrary_bytes && !(codec_config_flag))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002621 {
2622 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2623 h264_scratch.nFilledLen = 0;
2624 nal_count = 0;
2625 look_ahead_nal = false;
2626 frame_count = 0;
2627 h264_last_au_ts = LLONG_MAX;
2628 h264_last_au_flags = 0;
2629 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2630 m_demux_entries = 0;
2631 DEBUG_PRINT_LOW("\n Initialize parser");
2632 if (m_frame_parser.mutils)
2633 {
2634 m_frame_parser.mutils->initialize_frame_checking_environment();
2635 }
2636
2637 while (m_input_pending_q.m_size)
2638 {
2639 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2640 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2641 }
2642
2643 if (psource_frame)
2644 {
2645 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2646 psource_frame = NULL;
2647 }
2648
2649 if (pdest_frame)
2650 {
2651 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002652 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2653 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002654 pdest_frame = NULL;
2655 }
2656 m_frame_parser.flush();
2657 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07002658 else if (codec_config_flag)
2659 {
2660 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2661 "is not sent to the driver yet");
2662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002663 pthread_mutex_unlock(&m_lock);
2664 input_flush_progress = false;
2665 if (!arbitrary_bytes)
2666 {
2667 prev_ts = LLONG_MAX;
2668 rst_prev_ts = true;
2669 }
2670#ifdef _ANDROID_
2671 if (m_debug_timestamp)
2672 {
2673 m_timestamp_list.reset_ts_list();
2674 }
2675#endif
2676 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2677 return bRet;
2678}
2679
2680
2681/* ======================================================================
2682FUNCTION
2683 omx_vdec::SendCommandEvent
2684
2685DESCRIPTION
2686 Send the event to decoder pipe. This is needed to generate the callbacks
2687 in decoder thread context.
2688
2689PARAMETERS
2690 None.
2691
2692RETURN VALUE
2693 true/false
2694
2695========================================================================== */
2696bool omx_vdec::post_event(unsigned int p1,
2697 unsigned int p2,
2698 unsigned int id)
2699{
2700 bool bRet = false;
2701
2702
2703 pthread_mutex_lock(&m_lock);
2704
Vinay Kaliada4f4422013-01-09 10:45:03 -08002705 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002706 id == OMX_COMPONENT_GENERATE_FBD)
2707 {
2708 m_ftb_q.insert_entry(p1,p2,id);
2709 }
2710 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2711 id == OMX_COMPONENT_GENERATE_EBD ||
2712 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2713 {
2714 m_etb_q.insert_entry(p1,p2,id);
2715 }
2716 else
2717 {
2718 m_cmd_q.insert_entry(p1,p2,id);
2719 }
2720
2721 bRet = true;
2722 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2723 post_message(this, id);
2724
2725 pthread_mutex_unlock(&m_lock);
2726
2727 return bRet;
2728}
2729
2730OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2731{
Vinay Kalia586d0242013-04-29 11:39:00 -07002732 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002733 if(!profileLevelType)
2734 return OMX_ErrorBadParameter;
2735
2736 if(profileLevelType->nPortIndex == 0) {
2737 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2738 {
2739 if (profileLevelType->nProfileIndex == 0)
2740 {
2741 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2742 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2743
2744 }
2745 else if (profileLevelType->nProfileIndex == 1)
2746 {
2747 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2748 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2749 }
2750 else if(profileLevelType->nProfileIndex == 2)
2751 {
2752 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2753 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2754 }
2755 else
2756 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07002757 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002758 profileLevelType->nProfileIndex);
2759 eRet = OMX_ErrorNoMore;
2760 }
2761 }
2762 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2763 {
2764 if (profileLevelType->nProfileIndex == 0)
2765 {
2766 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2767 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2768 }
2769 else
2770 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002771 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002772 eRet = OMX_ErrorNoMore;
2773 }
2774 }
2775 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2776 {
2777 if (profileLevelType->nProfileIndex == 0)
2778 {
2779 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2780 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2781 }
2782 else if(profileLevelType->nProfileIndex == 1)
2783 {
2784 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2785 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2786 }
2787 else
2788 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002789 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002790 eRet = OMX_ErrorNoMore;
2791 }
2792 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002793 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2794 {
2795 eRet = OMX_ErrorNoMore;
2796 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002797 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2798 {
2799 if (profileLevelType->nProfileIndex == 0)
2800 {
2801 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2802 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2803 }
2804 else if(profileLevelType->nProfileIndex == 1)
2805 {
2806 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2807 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2808 }
2809 else
2810 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002811 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002812 eRet = OMX_ErrorNoMore;
2813 }
2814 }
Eric (Quic613bc1f2012-12-18 11:02:07 -08002815 else
2816 {
2817 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2818 eRet = OMX_ErrorNoMore;
2819 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002820 }
2821 else
2822 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002823 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 -07002824 eRet = OMX_ErrorBadPortIndex;
2825 }
2826 return eRet;
2827}
2828
2829/* ======================================================================
2830FUNCTION
2831 omx_vdec::GetParameter
2832
2833DESCRIPTION
2834 OMX Get Parameter method implementation
2835
2836PARAMETERS
2837 <TBD>.
2838
2839RETURN VALUE
2840 Error None if successful.
2841
2842========================================================================== */
2843OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2844 OMX_IN OMX_INDEXTYPE paramIndex,
2845 OMX_INOUT OMX_PTR paramData)
2846{
2847 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2848
2849 DEBUG_PRINT_LOW("get_parameter: \n");
2850 if(m_state == OMX_StateInvalid)
2851 {
2852 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2853 return OMX_ErrorInvalidState;
2854 }
2855 if(paramData == NULL)
2856 {
2857 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2858 return OMX_ErrorBadParameter;
2859 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002860 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002861 {
2862 case OMX_IndexParamPortDefinition:
2863 {
2864 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2865 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2866 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2867 eRet = update_portdef(portDefn);
2868 if (eRet == OMX_ErrorNone)
2869 m_port_def = *portDefn;
2870 break;
2871 }
2872 case OMX_IndexParamVideoInit:
2873 {
2874 OMX_PORT_PARAM_TYPE *portParamType =
2875 (OMX_PORT_PARAM_TYPE *) paramData;
2876 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2877
2878 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2879 portParamType->nSize = sizeof(portParamType);
2880 portParamType->nPorts = 2;
2881 portParamType->nStartPortNumber = 0;
2882 break;
2883 }
2884 case OMX_IndexParamVideoPortFormat:
2885 {
2886 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2887 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2888 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2889
2890 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2891 portFmt->nSize = sizeof(portFmt);
2892
2893 if (0 == portFmt->nPortIndex)
2894 {
2895 if (0 == portFmt->nIndex)
2896 {
2897 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2898 portFmt->eCompressionFormat = eCompressionFormat;
2899 }
2900 else
2901 {
2902 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2903 " NoMore compression formats\n");
2904 eRet = OMX_ErrorNoMore;
2905 }
2906 }
2907 else if (1 == portFmt->nPortIndex)
2908 {
2909 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2910
2911 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002912 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2913 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2914 else if (1 == portFmt->nIndex)
2915 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002916 else
2917 {
2918 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2919 " NoMore Color formats\n");
2920 eRet = OMX_ErrorNoMore;
2921 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002922 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002923 }
2924 else
2925 {
2926 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2927 (int)portFmt->nPortIndex);
2928 eRet = OMX_ErrorBadPortIndex;
2929 }
2930 break;
2931 }
2932 /*Component should support this port definition*/
2933 case OMX_IndexParamAudioInit:
2934 {
2935 OMX_PORT_PARAM_TYPE *audioPortParamType =
2936 (OMX_PORT_PARAM_TYPE *) paramData;
2937 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2938 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2939 audioPortParamType->nSize = sizeof(audioPortParamType);
2940 audioPortParamType->nPorts = 0;
2941 audioPortParamType->nStartPortNumber = 0;
2942 break;
2943 }
2944 /*Component should support this port definition*/
2945 case OMX_IndexParamImageInit:
2946 {
2947 OMX_PORT_PARAM_TYPE *imagePortParamType =
2948 (OMX_PORT_PARAM_TYPE *) paramData;
2949 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2950 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2951 imagePortParamType->nSize = sizeof(imagePortParamType);
2952 imagePortParamType->nPorts = 0;
2953 imagePortParamType->nStartPortNumber = 0;
2954 break;
2955
2956 }
2957 /*Component should support this port definition*/
2958 case OMX_IndexParamOtherInit:
2959 {
2960 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2961 paramIndex);
2962 eRet =OMX_ErrorUnsupportedIndex;
2963 break;
2964 }
2965 case OMX_IndexParamStandardComponentRole:
2966 {
2967 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2968 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2969 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2970 comp_role->nSize = sizeof(*comp_role);
2971
2972 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2973 paramIndex);
2974 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2975 OMX_MAX_STRINGNAME_SIZE);
2976 break;
2977 }
2978 /* Added for parameter test */
2979 case OMX_IndexParamPriorityMgmt:
2980 {
2981
2982 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2983 (OMX_PRIORITYMGMTTYPE *) paramData;
2984 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2985 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2986 priorityMgmType->nSize = sizeof(priorityMgmType);
2987
2988 break;
2989 }
2990 /* Added for parameter test */
2991 case OMX_IndexParamCompBufferSupplier:
2992 {
2993 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2994 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2995 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2996
2997 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2998 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2999 if(0 == bufferSupplierType->nPortIndex)
3000 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3001 else if (1 == bufferSupplierType->nPortIndex)
3002 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3003 else
3004 eRet = OMX_ErrorBadPortIndex;
3005
3006
3007 break;
3008 }
3009 case OMX_IndexParamVideoAvc:
3010 {
3011 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
3012 paramIndex);
3013 break;
3014 }
3015 case OMX_IndexParamVideoH263:
3016 {
3017 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
3018 paramIndex);
3019 break;
3020 }
3021 case OMX_IndexParamVideoMpeg4:
3022 {
3023 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
3024 paramIndex);
3025 break;
3026 }
3027 case OMX_IndexParamVideoMpeg2:
3028 {
3029 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
3030 paramIndex);
3031 break;
3032 }
3033 case OMX_IndexParamVideoProfileLevelQuerySupported:
3034 {
3035 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
3036 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3037 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3038 eRet = get_supported_profile_level_for_1080p(profileLevelType);
3039 break;
3040 }
3041#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3042 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
3043 {
3044 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
3045 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3046 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3047
3048 if(secure_mode) {
3049 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05303050 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003051 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08003052 nativeBuffersUsage->nUsage =
3053 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
3054 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003055 }
3056 } else {
3057 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
3058 eRet = OMX_ErrorBadParameter;
3059 }
3060 }
3061 break;
3062#endif
3063
3064 default:
3065 {
3066 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
3067 eRet =OMX_ErrorUnsupportedIndex;
3068 }
3069
3070 }
3071
3072 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
3073 drv_ctx.video_resolution.frame_width,
3074 drv_ctx.video_resolution.frame_height,
3075 drv_ctx.video_resolution.stride,
3076 drv_ctx.video_resolution.scan_lines);
3077
3078 return eRet;
3079}
3080
3081#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3082OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3083{
3084 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3085 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3086 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3087
3088 if((params == NULL) ||
3089 (params->nativeBuffer == NULL) ||
3090 (params->nativeBuffer->handle == NULL) ||
3091 !m_enable_android_native_buffers)
3092 return OMX_ErrorBadParameter;
3093 m_use_android_native_buffers = OMX_TRUE;
3094 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3095 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3096 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3097 OMX_U8 *buffer = NULL;
3098 if(!secure_mode) {
3099 buffer = (OMX_U8*)mmap(0, handle->size,
3100 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3101 if(buffer == MAP_FAILED) {
3102 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3103 return OMX_ErrorInsufficientResources;
3104 }
3105 }
3106 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3107 } else {
3108 eRet = OMX_ErrorBadParameter;
3109 }
3110 return eRet;
3111}
3112#endif
3113/* ======================================================================
3114FUNCTION
3115 omx_vdec::Setparameter
3116
3117DESCRIPTION
3118 OMX Set Parameter method implementation.
3119
3120PARAMETERS
3121 <TBD>.
3122
3123RETURN VALUE
3124 OMX Error None if successful.
3125
3126========================================================================== */
3127OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3128 OMX_IN OMX_INDEXTYPE paramIndex,
3129 OMX_IN OMX_PTR paramData)
3130{
3131 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003132 int ret=0;
3133 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003134 if(m_state == OMX_StateInvalid)
3135 {
3136 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3137 return OMX_ErrorInvalidState;
3138 }
3139 if(paramData == NULL)
3140 {
3141 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3142 return OMX_ErrorBadParameter;
3143 }
3144 if((m_state != OMX_StateLoaded) &&
3145 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3146 (m_out_bEnabled == OMX_TRUE) &&
3147 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3148 (m_inp_bEnabled == OMX_TRUE)) {
3149 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3150 return OMX_ErrorIncorrectStateOperation;
3151 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003152 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003153 {
3154 case OMX_IndexParamPortDefinition:
3155 {
3156 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3157 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3158 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3159 //been called.
3160 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3161 (int)portDefn->format.video.nFrameHeight,
3162 (int)portDefn->format.video.nFrameWidth);
3163 if(OMX_DirOutput == portDefn->eDir)
3164 {
3165 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3166 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003167 unsigned int buffer_size;
3168 if (!client_buffers.get_buffer_req(buffer_size)) {
3169 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003170 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003171 } else {
3172 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3173 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3174 {
3175 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3176 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
Arun Menonefe1a8e2013-04-22 10:49:26 -07003177 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3178 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3179 drv_ctx.extradata_info.buffer_size;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003180 eRet = set_buffer_req(&drv_ctx.op_buf);
3181 if (eRet == OMX_ErrorNone)
3182 m_port_def = *portDefn;
3183 }
3184 else
3185 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003186 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003187 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3188 portDefn->nBufferCountActual, portDefn->nBufferSize);
3189 eRet = OMX_ErrorBadParameter;
3190 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003191 }
3192 }
3193 else if(OMX_DirInput == portDefn->eDir)
3194 {
3195 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3196 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3197 {
3198 // Frame rate only should be set if this is a "known value" or to
3199 // activate ts prediction logic (arbitrary mode only) sending input
3200 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003201 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003202 portDefn->format.video.xFramerate >> 16);
3203 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3204 drv_ctx.frame_rate.fps_denominator);
3205 if(!drv_ctx.frame_rate.fps_numerator)
3206 {
3207 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3208 drv_ctx.frame_rate.fps_numerator = 30;
3209 }
3210 if(drv_ctx.frame_rate.fps_denominator)
3211 drv_ctx.frame_rate.fps_numerator = (int)
3212 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3213 drv_ctx.frame_rate.fps_denominator = 1;
3214 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3215 drv_ctx.frame_rate.fps_numerator;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003216 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003217 frm_int, drv_ctx.frame_rate.fps_numerator /
3218 (float)drv_ctx.frame_rate.fps_denominator);
3219 }
3220 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3221 if(drv_ctx.video_resolution.frame_height !=
3222 portDefn->format.video.nFrameHeight ||
3223 drv_ctx.video_resolution.frame_width !=
3224 portDefn->format.video.nFrameWidth)
3225 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07003226 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003227 portDefn->format.video.nFrameWidth,
3228 portDefn->format.video.nFrameHeight);
3229 if (portDefn->format.video.nFrameHeight != 0x0 &&
3230 portDefn->format.video.nFrameWidth != 0x0)
3231 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003232 update_resolution(portDefn->format.video.nFrameWidth,
Vinay Kalia21649b32013-03-18 17:28:07 -07003233 portDefn->format.video.nFrameHeight,
3234 portDefn->format.video.nFrameWidth,
3235 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003236 eRet = is_video_session_supported();
3237 if (eRet)
3238 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003239 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3240 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3241 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3242 fmt.fmt.pix_mp.pixelformat = output_capability;
3243 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);
3244 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003245 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003246 {
3247 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3248 eRet = OMX_ErrorUnsupportedSetting;
3249 }
3250 else
3251 eRet = get_buffer_req(&drv_ctx.op_buf);
3252 }
3253 }
3254 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003255 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003256 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003257 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003258 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003259 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3260 (~(buffer_prop->alignment - 1));
3261 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003262 }
3263 else
3264 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003265 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003266 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3267 portDefn->nBufferCountActual, portDefn->nBufferSize);
3268 eRet = OMX_ErrorBadParameter;
3269 }
3270 }
3271 else if (portDefn->eDir == OMX_DirMax)
3272 {
3273 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3274 (int)portDefn->nPortIndex);
3275 eRet = OMX_ErrorBadPortIndex;
3276 }
3277 }
3278 break;
3279 case OMX_IndexParamVideoPortFormat:
3280 {
3281 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3282 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3283 int ret=0;
3284 struct v4l2_format fmt;
3285 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3286 portFmt->eColorFormat);
3287
3288 if(1 == portFmt->nPortIndex)
3289 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003290 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3291 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3292 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3293 fmt.fmt.pix_mp.pixelformat = capture_capability;
3294 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003295 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3296 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003297 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003298 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003299 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003300 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003301 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3302 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3303 else
3304 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003305
Vinay Kaliada4f4422013-01-09 10:45:03 -08003306 if(eRet == OMX_ErrorNone)
3307 {
3308 drv_ctx.output_format = op_format;
3309 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3310 if(ret)
3311 {
3312 DEBUG_PRINT_ERROR("\n Set output format failed");
3313 eRet = OMX_ErrorUnsupportedSetting;
3314 /*TODO: How to handle this case */
3315 }
3316 else
3317 {
3318 eRet = get_buffer_req(&drv_ctx.op_buf);
3319 }
3320 }
3321 if (eRet == OMX_ErrorNone){
3322 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3323 DEBUG_PRINT_ERROR("\n Set color format failed");
3324 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003325 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003326 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003327 }
3328 }
3329 break;
3330
3331 case OMX_QcomIndexPortDefn:
3332 {
3333 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3334 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003335 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003336 portFmt->nFramePackingFormat);
3337
3338 /* Input port */
3339 if (portFmt->nPortIndex == 0)
3340 {
3341 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3342 {
3343 if(secure_mode) {
3344 arbitrary_bytes = false;
3345 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3346 eRet = OMX_ErrorUnsupportedSetting;
3347 } else {
3348 arbitrary_bytes = true;
3349 }
3350 }
3351 else if (portFmt->nFramePackingFormat ==
3352 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3353 {
3354 arbitrary_bytes = false;
3355 }
3356 else
3357 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003358 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003359 portFmt->nFramePackingFormat);
3360 eRet = OMX_ErrorUnsupportedSetting;
3361 }
3362 }
3363 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3364 {
3365 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3366 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3367 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3368 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3369 {
3370 m_out_mem_region_smi = OMX_TRUE;
3371 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3372 {
3373 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3374 m_use_output_pmem = OMX_TRUE;
3375 }
3376 }
3377 }
3378 }
3379 break;
3380
3381 case OMX_IndexParamStandardComponentRole:
3382 {
3383 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3384 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3385 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3386 comp_role->cRole);
3387
3388 if((m_state == OMX_StateLoaded)&&
3389 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3390 {
3391 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3392 }
3393 else
3394 {
3395 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3396 return OMX_ErrorIncorrectStateOperation;
3397 }
3398
3399 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3400 {
3401 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3402 {
3403 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3404 }
3405 else
3406 {
3407 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3408 eRet =OMX_ErrorUnsupportedSetting;
3409 }
3410 }
3411 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3412 {
3413 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3414 {
3415 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3416 }
3417 else
3418 {
3419 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3420 eRet = OMX_ErrorUnsupportedSetting;
3421 }
3422 }
3423 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3424 {
3425 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3426 {
3427 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3428 }
3429 else
3430 {
3431 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3432 eRet =OMX_ErrorUnsupportedSetting;
3433 }
3434 }
3435 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3436 {
3437 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3438 {
3439 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3440 }
3441 else
3442 {
3443 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3444 eRet = OMX_ErrorUnsupportedSetting;
3445 }
3446 }
3447 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3448 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3449 )
3450 {
3451 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3452 {
3453 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3454 }
3455 else
3456 {
3457 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3458 eRet =OMX_ErrorUnsupportedSetting;
3459 }
3460 }
3461 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3462 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3463 )
3464 {
3465 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3466 {
3467 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3468 }
3469 else
3470 {
3471 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3472 eRet =OMX_ErrorUnsupportedSetting;
3473 }
3474 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003475 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3476 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003477 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3478 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003479 {
3480 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3481 }
3482 else
3483 {
3484 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3485 eRet = OMX_ErrorUnsupportedSetting;
3486 }
3487 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003488 else
3489 {
3490 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3491 eRet = OMX_ErrorInvalidComponentName;
3492 }
3493 break;
3494 }
3495
3496 case OMX_IndexParamPriorityMgmt:
3497 {
3498 if(m_state != OMX_StateLoaded)
3499 {
3500 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3501 return OMX_ErrorIncorrectStateOperation;
3502 }
3503 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Shalaj Jainaf08f302013-03-18 13:15:35 -07003504 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003505 priorityMgmtype->nGroupID);
3506
Shalaj Jainaf08f302013-03-18 13:15:35 -07003507 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003508 priorityMgmtype->nGroupPriority);
3509
3510 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3511 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3512
3513 break;
3514 }
3515
3516 case OMX_IndexParamCompBufferSupplier:
3517 {
3518 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3519 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3520 bufferSupplierType->eBufferSupplier);
3521 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3522 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3523
3524 else
3525
3526 eRet = OMX_ErrorBadPortIndex;
3527
3528 break;
3529
3530 }
3531 case OMX_IndexParamVideoAvc:
3532 {
3533 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3534 paramIndex);
3535 break;
3536 }
3537 case OMX_IndexParamVideoH263:
3538 {
3539 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3540 paramIndex);
3541 break;
3542 }
3543 case OMX_IndexParamVideoMpeg4:
3544 {
3545 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3546 paramIndex);
3547 break;
3548 }
3549 case OMX_IndexParamVideoMpeg2:
3550 {
3551 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3552 paramIndex);
3553 break;
3554 }
3555 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3556 {
3557 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3558 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003559 struct v4l2_control control;
3560 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003561 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3562 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003563 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3564 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3565 }
3566 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3567 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003568 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003569 }
3570 else
3571 eRet = OMX_ErrorBadParameter;
3572 if (eRet == OMX_ErrorNone)
3573 {
3574 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3575 control.value = pic_order;
3576 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3577 if(rc)
3578 {
3579 DEBUG_PRINT_ERROR("\n Set picture order failed");
3580 eRet = OMX_ErrorUnsupportedSetting;
3581 }
3582 }
3583 break;
3584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003585 case OMX_QcomIndexParamConcealMBMapExtraData:
3586 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003587 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003588 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3589 else {
3590 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3591 eRet = OMX_ErrorUnsupportedSetting;
3592 }
3593 break;
3594 case OMX_QcomIndexParamFrameInfoExtraData:
3595 {
3596 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003597 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003598 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3599 else {
3600 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3601 eRet = OMX_ErrorUnsupportedSetting;
3602 }
3603 break;
3604 }
3605 case OMX_QcomIndexParamInterlaceExtraData:
3606 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003607 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003608 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3609 else {
3610 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3611 eRet = OMX_ErrorUnsupportedSetting;
3612 }
3613 break;
3614 case OMX_QcomIndexParamH264TimeInfo:
3615 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003616 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003617 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3618 else {
3619 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3620 eRet = OMX_ErrorUnsupportedSetting;
3621 }
3622 break;
3623 case OMX_QcomIndexParamVideoDivx:
3624 {
3625 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003626 }
3627 break;
3628 case OMX_QcomIndexPlatformPvt:
3629 {
3630 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3631 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3632 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3633 {
3634 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3635 eRet = OMX_ErrorUnsupportedSetting;
3636 }
3637 else
3638 {
3639 m_out_pvt_entry_pmem = OMX_TRUE;
3640 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3641 {
3642 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3643 m_use_output_pmem = OMX_TRUE;
3644 }
3645 }
3646
3647 }
3648 break;
3649 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3650 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003651 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3652 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3653 struct v4l2_control control;
3654 int rc;
3655 drv_ctx.idr_only_decoding = 1;
3656 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3657 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3658 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3659 if(rc)
3660 {
3661 DEBUG_PRINT_ERROR("\n Set picture order failed");
3662 eRet = OMX_ErrorUnsupportedSetting;
3663 } else {
3664 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3665 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3666 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3667 if(rc)
3668 {
3669 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3670 eRet = OMX_ErrorUnsupportedSetting;
3671 }
Vinay Kaliac8900182013-07-02 12:53:10 -07003672 /*Setting sync frame decoding on driver might change buffer
3673 * requirements so update them here*/
3674 if (get_buffer_req(&drv_ctx.ip_buf)) {
Srinu Gorle676b7862013-07-18 18:24:42 +05303675 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3676 eRet = OMX_ErrorUnsupportedSetting;
3677 }
3678 if (get_buffer_req(&drv_ctx.op_buf)) {
3679 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
Vinay Kaliac8900182013-07-02 12:53:10 -07003680 eRet = OMX_ErrorUnsupportedSetting;
3681 }
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003682 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003683 }
3684 break;
3685
3686 case OMX_QcomIndexParamIndexExtraDataType:
3687 {
3688 if(!secure_mode) {
3689 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3690 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3691 (extradataIndexType->bEnabled == OMX_TRUE) &&
3692 (extradataIndexType->nPortIndex == 1))
3693 {
3694 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003695 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003696
Shalaj Jain273b3e02012-06-22 19:08:03 -07003697 }
3698 }
3699 }
3700 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003701 case OMX_QcomIndexParamEnableSmoothStreaming:
3702 {
Arun Menonc821d8a2013-06-15 10:03:29 -07003703#ifndef SMOOTH_STREAMING_DISABLED
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003704 struct v4l2_control control;
3705 struct v4l2_format fmt;
3706 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3707 control.value = 1;
3708 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3709 if(rc < 0) {
3710 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3711 eRet = OMX_ErrorHardware;
3712 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003713#else
3714 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003715#endif
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003716 }
3717 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003718#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3719 /* Need to allow following two set_parameters even in Idle
3720 * state. This is ANDROID architecture which is not in sync
3721 * with openmax standard. */
3722 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3723 {
3724 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3725 if(enableNativeBuffers) {
3726 m_enable_android_native_buffers = enableNativeBuffers->enable;
3727 }
3728 }
3729 break;
3730 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3731 {
3732 eRet = use_android_native_buffer(hComp, paramData);
3733 }
3734 break;
3735#endif
3736 case OMX_QcomIndexParamEnableTimeStampReorder:
3737 {
3738 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003739 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003740 if (reorder->bEnable == OMX_TRUE) {
3741 frm_int =0;
3742 time_stamp_dts.set_timestamp_reorder_mode(true);
3743 }
3744 else
3745 time_stamp_dts.set_timestamp_reorder_mode(false);
3746 } else {
3747 time_stamp_dts.set_timestamp_reorder_mode(false);
3748 if (reorder->bEnable == OMX_TRUE)
3749 {
3750 eRet = OMX_ErrorUnsupportedSetting;
3751 }
3752 }
3753 }
3754 break;
Arun Menon888aa852013-05-30 11:24:42 -07003755 case OMX_IndexParamVideoProfileLevelCurrent:
3756 {
3757 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3758 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3759 if (pParam) {
3760 m_profile_lvl.eProfile = pParam->eProfile;
3761 m_profile_lvl.eLevel = pParam->eLevel;
3762 }
3763 break;
3764
3765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003766 default:
3767 {
3768 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3769 eRet = OMX_ErrorUnsupportedIndex;
3770 }
3771 }
3772 return eRet;
3773}
3774
3775/* ======================================================================
3776FUNCTION
3777 omx_vdec::GetConfig
3778
3779DESCRIPTION
3780 OMX Get Config Method implementation.
3781
3782PARAMETERS
3783 <TBD>.
3784
3785RETURN VALUE
3786 OMX Error None if successful.
3787
3788========================================================================== */
3789OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3790 OMX_IN OMX_INDEXTYPE configIndex,
3791 OMX_INOUT OMX_PTR configData)
3792{
3793 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3794
3795 if (m_state == OMX_StateInvalid)
3796 {
3797 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3798 return OMX_ErrorInvalidState;
3799 }
3800
Shalaj Jain286b0062013-02-21 20:35:48 -08003801 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003802 {
3803 case OMX_QcomIndexConfigInterlaced:
3804 {
3805 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3806 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3807 if (configFmt->nPortIndex == 1)
3808 {
3809 if (configFmt->nIndex == 0)
3810 {
3811 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3812 }
3813 else if (configFmt->nIndex == 1)
3814 {
3815 configFmt->eInterlaceType =
3816 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3817 }
3818 else if (configFmt->nIndex == 2)
3819 {
3820 configFmt->eInterlaceType =
3821 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3822 }
3823 else
3824 {
3825 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3826 " NoMore Interlaced formats\n");
3827 eRet = OMX_ErrorNoMore;
3828 }
3829
3830 }
3831 else
3832 {
3833 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3834 (int)configFmt->nPortIndex);
3835 eRet = OMX_ErrorBadPortIndex;
3836 }
3837 break;
3838 }
3839 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3840 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003841 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3842 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003843 decoderinstances->nNumOfInstances = 16;
3844 /*TODO: How to handle this case */
3845 break;
3846 }
3847 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3848 {
3849 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3850 {
3851 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3852 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3853 h264_parser->get_frame_pack_data(configFmt);
3854 }
3855 else
3856 {
3857 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3858 }
3859 break;
3860 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07003861 case OMX_IndexConfigCommonOutputCrop:
Vinay Kalia592e4b42012-12-19 15:55:47 -08003862 {
3863 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3864 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3865 break;
3866 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07003867 default:
Shalaj Jain273b3e02012-06-22 19:08:03 -07003868 {
3869 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3870 eRet = OMX_ErrorBadParameter;
3871 }
3872
3873 }
3874
3875 return eRet;
3876}
3877
3878/* ======================================================================
3879FUNCTION
3880 omx_vdec::SetConfig
3881
3882DESCRIPTION
3883 OMX Set Config method implementation
3884
3885PARAMETERS
3886 <TBD>.
3887
3888RETURN VALUE
3889 OMX Error None if successful.
3890========================================================================== */
3891OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3892 OMX_IN OMX_INDEXTYPE configIndex,
3893 OMX_IN OMX_PTR configData)
3894{
3895 if(m_state == OMX_StateInvalid)
3896 {
3897 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3898 return OMX_ErrorInvalidState;
3899 }
3900
3901 OMX_ERRORTYPE ret = OMX_ErrorNone;
3902 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3903
3904 DEBUG_PRINT_LOW("\n Set Config Called");
3905
Shalaj Jain286b0062013-02-21 20:35:48 -08003906 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003907 {
3908 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3909 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3910 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3911 {
3912 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3913 OMX_U32 extra_size;
3914 // Parsing done here for the AVC atom is definitely not generic
3915 // Currently this piece of code is working, but certainly
3916 // not tested with all .mp4 files.
3917 // Incase of failure, we might need to revisit this
3918 // for a generic piece of code.
3919
3920 // Retrieve size of NAL length field
3921 // byte #4 contains the size of NAL lenght field
3922 nal_length = (config->pData[4] & 0x03) + 1;
3923
3924 extra_size = 0;
3925 if (nal_length > 2)
3926 {
3927 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3928 extra_size = (nal_length - 2) * 2;
3929 }
3930
3931 // SPS starts from byte #6
3932 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3933 OMX_U8 *pDestBuf;
3934 m_vendor_config.nPortIndex = config->nPortIndex;
3935
3936 // minus 6 --> SPS starts from byte #6
3937 // minus 1 --> picture param set byte to be ignored from avcatom
3938 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3939 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3940 OMX_U32 len;
3941 OMX_U8 index = 0;
3942 // case where SPS+PPS is sent as part of set_config
3943 pDestBuf = m_vendor_config.pData;
3944
Shalaj Jainaf08f302013-03-18 13:15:35 -07003945 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003946 m_vendor_config.nPortIndex,
3947 m_vendor_config.nDataSize,
3948 m_vendor_config.pData);
3949 while (index < 2)
3950 {
3951 uint8 *psize;
3952 len = *pSrcBuf;
3953 len = len << 8;
3954 len |= *(pSrcBuf + 1);
3955 psize = (uint8 *) & len;
3956 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003957 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003958 {
3959 pDestBuf[i] = psize[nal_length - 1 - i];
3960 }
3961 //memcpy(pDestBuf,pSrcBuf,(len+2));
3962 pDestBuf += len + nal_length;
3963 pSrcBuf += len + 2;
3964 index++;
3965 pSrcBuf++; // skip picture param set
3966 len = 0;
3967 }
3968 }
3969 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3970 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3971 {
3972 m_vendor_config.nPortIndex = config->nPortIndex;
3973 m_vendor_config.nDataSize = config->nDataSize;
3974 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3975 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3976 }
3977 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3978 {
3979 if(m_vendor_config.pData)
3980 {
3981 free(m_vendor_config.pData);
3982 m_vendor_config.pData = NULL;
3983 m_vendor_config.nDataSize = 0;
3984 }
3985
3986 if (((*((OMX_U32 *) config->pData)) &
3987 VC1_SP_MP_START_CODE_MASK) ==
3988 VC1_SP_MP_START_CODE)
3989 {
3990 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3991 m_vendor_config.nPortIndex = config->nPortIndex;
3992 m_vendor_config.nDataSize = config->nDataSize;
3993 m_vendor_config.pData =
3994 (OMX_U8 *) malloc(config->nDataSize);
3995 memcpy(m_vendor_config.pData, config->pData,
3996 config->nDataSize);
3997 m_vc1_profile = VC1_SP_MP_RCV;
3998 }
3999 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
4000 {
4001 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
4002 m_vendor_config.nPortIndex = config->nPortIndex;
4003 m_vendor_config.nDataSize = config->nDataSize;
4004 m_vendor_config.pData =
4005 (OMX_U8 *) malloc((config->nDataSize));
4006 memcpy(m_vendor_config.pData, config->pData,
4007 config->nDataSize);
4008 m_vc1_profile = VC1_AP;
4009 }
4010 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
4011 {
4012 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
4013 m_vendor_config.nPortIndex = config->nPortIndex;
4014 m_vendor_config.nDataSize = config->nDataSize;
4015 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
4016 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
4017 m_vc1_profile = VC1_SP_MP_RCV;
4018 }
4019 else
4020 {
4021 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
4022 }
4023 }
4024 return ret;
4025 }
4026 else if (configIndex == OMX_IndexConfigVideoNalSize)
4027 {
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07004028 struct v4l2_control temp;
4029 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004030
4031 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07004032 switch (pNal->nNaluBytes) {
4033 case 0:
4034 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
4035 break;
4036 case 2:
4037 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4038 break;
4039 case 4:
4040 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4041 break;
4042 default:
4043 return OMX_ErrorUnsupportedSetting;
4044 }
4045
4046 if (!arbitrary_bytes) {
4047 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4048 * with start code, so only need to notify driver in frame by frame mode */
4049 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp))
4050 {
4051 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4052 return OMX_ErrorHardware;
4053 }
4054 }
4055
Shalaj Jain273b3e02012-06-22 19:08:03 -07004056 nal_length = pNal->nNaluBytes;
4057 m_frame_parser.init_nal_length(nal_length);
Deva Ramasubramaniand6995bb2013-05-14 14:42:30 -07004058
4059 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004060 return ret;
4061 }
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07004062 else if (configIndex == OMX_IndexVendorVideoFrameRate)
4063 {
4064 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
4065 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
4066
4067 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
4068 {
4069 if (config->bEnabled)
4070 {
4071 if ((config->nFps >> 16) > 0)
4072 {
4073 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
4074 config->nFps >> 16);
4075 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4076 drv_ctx.frame_rate.fps_denominator);
4077
4078 if (!drv_ctx.frame_rate.fps_numerator)
4079 {
4080 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4081 drv_ctx.frame_rate.fps_numerator = 30;
4082 }
4083
4084 if (drv_ctx.frame_rate.fps_denominator)
4085 {
4086 drv_ctx.frame_rate.fps_numerator = (int)
4087 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4088 }
4089
4090 drv_ctx.frame_rate.fps_denominator = 1;
4091 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4092 drv_ctx.frame_rate.fps_numerator;
4093
4094 struct v4l2_outputparm oparm;
4095 /*XXX: we're providing timing info as seconds per frame rather than frames
4096 * per second.*/
4097 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4098 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4099
4100 struct v4l2_streamparm sparm;
4101 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4102 sparm.parm.output = oparm;
4103 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm))
4104 {
4105 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4106 performance might be affected");
4107 ret = OMX_ErrorHardware;
4108 }
4109 client_set_fps = true;
4110 }
4111 else
4112 {
4113 DEBUG_PRINT_ERROR("Frame rate not supported.");
4114 ret = OMX_ErrorUnsupportedSetting;
4115 }
4116 }
4117 else
4118 {
4119 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4120 client_set_fps = false;
4121 }
4122 }
4123 else
4124 {
4125 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4126 (int)config->nPortIndex);
4127 ret = OMX_ErrorBadPortIndex;
4128 }
4129
4130 return ret;
4131 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004132
4133 return OMX_ErrorNotImplemented;
4134}
4135
4136/* ======================================================================
4137FUNCTION
4138 omx_vdec::GetExtensionIndex
4139
4140DESCRIPTION
4141 OMX GetExtensionIndex method implementaion. <TBD>
4142
4143PARAMETERS
4144 <TBD>.
4145
4146RETURN VALUE
4147 OMX Error None if everything successful.
4148
4149========================================================================== */
4150OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4151 OMX_IN OMX_STRING paramName,
4152 OMX_OUT OMX_INDEXTYPE* indexType)
4153{
4154 if(m_state == OMX_StateInvalid)
4155 {
4156 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
4157 return OMX_ErrorInvalidState;
4158 }
4159 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
4160 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
4161 }
4162 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
4163 {
4164 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
4165 }
4166#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4167 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
4168 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
4169 }
4170 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
4171 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
4172 }
4173 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
4174 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
4175 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
4176 }
4177 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
4178 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4179 }
4180#endif
4181 else {
4182 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
4183 return OMX_ErrorNotImplemented;
4184 }
4185 return OMX_ErrorNone;
4186}
4187
4188/* ======================================================================
4189FUNCTION
4190 omx_vdec::GetState
4191
4192DESCRIPTION
4193 Returns the state information back to the caller.<TBD>
4194
4195PARAMETERS
4196 <TBD>.
4197
4198RETURN VALUE
4199 Error None if everything is successful.
4200========================================================================== */
4201OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4202 OMX_OUT OMX_STATETYPE* state)
4203{
4204 *state = m_state;
4205 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4206 return OMX_ErrorNone;
4207}
4208
4209/* ======================================================================
4210FUNCTION
4211 omx_vdec::ComponentTunnelRequest
4212
4213DESCRIPTION
4214 OMX Component Tunnel Request method implementation. <TBD>
4215
4216PARAMETERS
4217 None.
4218
4219RETURN VALUE
4220 OMX Error None if everything successful.
4221
4222========================================================================== */
4223OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4224 OMX_IN OMX_U32 port,
4225 OMX_IN OMX_HANDLETYPE peerComponent,
4226 OMX_IN OMX_U32 peerPort,
4227 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4228{
4229 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4230 return OMX_ErrorNotImplemented;
4231}
4232
4233/* ======================================================================
4234FUNCTION
4235 omx_vdec::UseOutputBuffer
4236
4237DESCRIPTION
4238 Helper function for Use buffer in the input pin
4239
4240PARAMETERS
4241 None.
4242
4243RETURN VALUE
4244 true/false
4245
4246========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004247OMX_ERRORTYPE omx_vdec::allocate_extradata()
4248{
4249#ifdef USE_ION
4250 if (drv_ctx.extradata_info.buffer_size) {
4251 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4252 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4253 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4254 free_ion_memory(&drv_ctx.extradata_info.ion);
4255 }
4256 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4257 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
Arun Menonefe1a8e2013-04-22 10:49:26 -07004258 drv_ctx.extradata_info.size, 4096,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004259 &drv_ctx.extradata_info.ion.ion_alloc_data,
4260 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4261 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4262 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4263 return OMX_ErrorInsufficientResources;
4264 }
4265 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4266 drv_ctx.extradata_info.size,
4267 PROT_READ|PROT_WRITE, MAP_SHARED,
4268 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4269 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4270 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4271 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4272 free_ion_memory(&drv_ctx.extradata_info.ion);
4273 return OMX_ErrorInsufficientResources;
4274 }
4275 }
4276#endif
4277 return OMX_ErrorNone;
4278}
4279
4280void omx_vdec::free_extradata() {
4281#ifdef USE_ION
4282 if (drv_ctx.extradata_info.uaddr) {
4283 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4284 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4285 free_ion_memory(&drv_ctx.extradata_info.ion);
4286 }
4287 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4288#endif
4289}
4290
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291OMX_ERRORTYPE omx_vdec::use_output_buffer(
4292 OMX_IN OMX_HANDLETYPE hComp,
4293 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4294 OMX_IN OMX_U32 port,
4295 OMX_IN OMX_PTR appData,
4296 OMX_IN OMX_U32 bytes,
4297 OMX_IN OMX_U8* buffer)
4298{
4299 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4300 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4301 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004302 struct vdec_setbuffer_cmd setbuffers;
4303 OMX_PTR privateAppData = NULL;
4304 private_handle_t *handle = NULL;
4305 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004306 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004307 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4308 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004309
Shalaj Jain273b3e02012-06-22 19:08:03 -07004310 if (!m_out_mem_ptr) {
4311 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4312 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004313 if (eRet == OMX_ErrorNone)
4314 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004315 }
4316
4317 if (eRet == OMX_ErrorNone) {
4318 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4319 if(BITMASK_ABSENT(&m_out_bm_count,i))
4320 {
4321 break;
4322 }
4323 }
4324 }
4325
4326 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004327 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328 eRet = OMX_ErrorInsufficientResources;
4329 }
4330
4331 if (eRet == OMX_ErrorNone) {
4332#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4333 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004334 if (m_use_android_native_buffers) {
4335 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4336 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4337 handle = (private_handle_t *)nBuf->handle;
4338 privateAppData = params->pAppPrivate;
4339 } else {
4340 handle = (private_handle_t *)buff;
4341 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004342 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004343
4344 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4345 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4346 " expected %u, got %lu",
4347 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4348 return OMX_ErrorBadParameter;
4349 }
4350
4351 if (!m_use_android_native_buffers) {
4352 if (!secure_mode) {
4353 buff = (OMX_U8*)mmap(0, handle->size,
4354 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4355 if (buff == MAP_FAILED) {
4356 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4357 return OMX_ErrorInsufficientResources;
4358 }
4359 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004360 }
4361#if defined(_ANDROID_ICS_)
4362 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004363 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004364#endif
4365 if(!handle) {
4366 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4367 return OMX_ErrorBadParameter;
4368 }
4369 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4370 drv_ctx.ptr_outputbuffer[i].offset = 0;
4371 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
Vinay Kaliaac837f72013-05-28 17:29:30 -07004372 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4373 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004374 } else
4375#endif
4376
4377 if (!ouput_egl_buffers && !m_use_output_pmem) {
4378#ifdef USE_ION
4379 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4380 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4381 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004382 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004384 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 -07004385 return OMX_ErrorInsufficientResources;
4386 }
4387 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4388 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4389#else
4390 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4391 open (MEM_DEVICE,O_RDWR);
4392
4393 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004394 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 -07004395 return OMX_ErrorInsufficientResources;
4396 }
4397
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004398 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4400 {
4401 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4402 open (MEM_DEVICE,O_RDWR);
4403 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004404 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 -07004405 return OMX_ErrorInsufficientResources;
4406 }
4407 }
4408
4409 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4410 drv_ctx.op_buf.buffer_size,
4411 drv_ctx.op_buf.alignment))
4412 {
4413 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4414 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4415 return OMX_ErrorInsufficientResources;
4416 }
4417#endif
4418 if(!secure_mode) {
4419 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4420 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4421 PROT_READ|PROT_WRITE, MAP_SHARED,
4422 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4423 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4424 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4425#ifdef USE_ION
4426 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4427#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004428 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004429 return OMX_ErrorInsufficientResources;
4430 }
4431 }
4432 drv_ctx.ptr_outputbuffer[i].offset = 0;
4433 privateAppData = appData;
4434 }
4435 else {
4436
4437 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4438 if (!appData || !bytes ) {
4439 if(!secure_mode && !buffer) {
4440 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4441 return OMX_ErrorBadParameter;
4442 }
4443 }
4444
4445 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4446 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4447 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4448 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4449 !pmem_list->nEntries ||
4450 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4451 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4452 return OMX_ErrorBadParameter;
4453 }
4454 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4455 pmem_list->entryList->entry;
Shalaj Jainaf08f302013-03-18 13:15:35 -07004456 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004457 pmem_info->pmem_fd);
4458 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4459 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4460 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4461 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4462 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4463 privateAppData = appData;
4464 }
4465 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4466 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4467
4468 *bufferHdr = (m_out_mem_ptr + i );
4469 if(secure_mode)
4470 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4471 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4472 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4473 sizeof (vdec_bufferpayload));
4474
Shalaj Jain286b0062013-02-21 20:35:48 -08004475 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4476 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4477 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004478
4479 buf.index = i;
4480 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4481 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004482 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004483 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4484 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004485 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4486 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4487 plane[0].data_offset = 0;
4488 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4489 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4490 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4491 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4492#ifdef USE_ION
4493 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4494#endif
4495 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4496 plane[extra_idx].data_offset = 0;
4497 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4498 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4499 return OMX_ErrorBadParameter;
4500 }
4501 buf.m.planes = plane;
4502 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004503
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004504 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4505 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4506 /*TODO: How to handle this case */
4507 return OMX_ErrorInsufficientResources;
4508 }
4509
4510 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4511 enum v4l2_buf_type buf_type;
4512 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4513 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4514 return OMX_ErrorInsufficientResources;
4515 } else {
4516 streaming[CAPTURE_PORT] = true;
4517 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4518 }
4519 }
4520
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004522 if (m_enable_android_native_buffers) {
4523 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4524 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4525 } else {
4526 (*bufferHdr)->pBuffer = buff;
4527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004528 (*bufferHdr)->pAppPrivate = privateAppData;
4529 BITMASK_SET(&m_out_bm_count,i);
4530 }
4531 return eRet;
4532}
4533
4534/* ======================================================================
4535FUNCTION
4536 omx_vdec::use_input_heap_buffers
4537
4538DESCRIPTION
4539 OMX Use Buffer Heap allocation method implementation.
4540
4541PARAMETERS
4542 <TBD>.
4543
4544RETURN VALUE
4545 OMX Error None , if everything successful.
4546
4547========================================================================== */
4548OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4549 OMX_IN OMX_HANDLETYPE hComp,
4550 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4551 OMX_IN OMX_U32 port,
4552 OMX_IN OMX_PTR appData,
4553 OMX_IN OMX_U32 bytes,
4554 OMX_IN OMX_U8* buffer)
4555{
4556 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4557 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4558 if(!m_inp_heap_ptr)
4559 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4560 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4561 drv_ctx.ip_buf.actualcount);
4562 if(!m_phdr_pmem_ptr)
4563 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4564 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4565 drv_ctx.ip_buf.actualcount);
4566 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4567 {
4568 DEBUG_PRINT_ERROR("Insufficent memory");
4569 eRet = OMX_ErrorInsufficientResources;
4570 }
4571 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4572 {
4573 input_use_buffer = true;
4574 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4575 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4576 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4577 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4578 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4579 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4580 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4581 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4582 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 -08004583 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4584 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585 {
4586 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4587 return OMX_ErrorInsufficientResources;
4588 }
4589 m_in_alloc_cnt++;
4590 }
4591 else
4592 {
4593 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4594 eRet = OMX_ErrorInsufficientResources;
4595 }
4596 return eRet;
4597}
4598
4599/* ======================================================================
4600FUNCTION
4601 omx_vdec::UseBuffer
4602
4603DESCRIPTION
4604 OMX Use Buffer method implementation.
4605
4606PARAMETERS
4607 <TBD>.
4608
4609RETURN VALUE
4610 OMX Error None , if everything successful.
4611
4612========================================================================== */
4613OMX_ERRORTYPE omx_vdec::use_buffer(
4614 OMX_IN OMX_HANDLETYPE hComp,
4615 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4616 OMX_IN OMX_U32 port,
4617 OMX_IN OMX_PTR appData,
4618 OMX_IN OMX_U32 bytes,
4619 OMX_IN OMX_U8* buffer)
4620{
4621 OMX_ERRORTYPE error = OMX_ErrorNone;
4622 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004623
4624 if (bufferHdr == NULL || bytes == 0)
4625 {
4626 if(!secure_mode && buffer == NULL) {
4627 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4628 return OMX_ErrorBadParameter;
4629 }
4630 }
4631 if(m_state == OMX_StateInvalid)
4632 {
4633 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4634 return OMX_ErrorInvalidState;
4635 }
4636 if(port == OMX_CORE_INPUT_PORT_INDEX)
4637 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4638 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4639 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4640 else
4641 {
4642 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4643 error = OMX_ErrorBadPortIndex;
4644 }
Shalaj Jainaf08f302013-03-18 13:15:35 -07004645 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004646 if(error == OMX_ErrorNone)
4647 {
4648 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4649 {
4650 // Send the callback now
4651 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4652 post_event(OMX_CommandStateSet,OMX_StateIdle,
4653 OMX_COMPONENT_GENERATE_EVENT);
4654 }
4655 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4656 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4657 {
4658 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4659 post_event(OMX_CommandPortEnable,
4660 OMX_CORE_INPUT_PORT_INDEX,
4661 OMX_COMPONENT_GENERATE_EVENT);
4662 }
4663 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4664 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4665 {
4666 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4667 post_event(OMX_CommandPortEnable,
4668 OMX_CORE_OUTPUT_PORT_INDEX,
4669 OMX_COMPONENT_GENERATE_EVENT);
4670 }
4671 }
4672 return error;
4673}
4674
4675OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4676 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4677{
4678 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4679 {
4680 if(m_inp_heap_ptr[bufferindex].pBuffer)
4681 free(m_inp_heap_ptr[bufferindex].pBuffer);
4682 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4683 }
4684 if (pmem_bufferHdr)
4685 free_input_buffer(pmem_bufferHdr);
4686 return OMX_ErrorNone;
4687}
4688
4689OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4690{
4691 unsigned int index = 0;
4692 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4693 {
4694 return OMX_ErrorBadParameter;
4695 }
4696
4697 index = bufferHdr - m_inp_mem_ptr;
4698 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4699
4700 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4701 {
4702 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4703 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4704 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705 struct vdec_setbuffer_cmd setbuffers;
4706 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4707 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4708 sizeof (vdec_bufferpayload));
Praveen Chavan212671f2013-04-05 20:00:42 -07004709 if(!secure_mode) {
4710 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4711 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4712 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4713 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4714 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4715 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4716 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4717 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004718 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4719 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4720 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4721 {
4722 free(m_desc_buffer_ptr[index].buf_addr);
4723 m_desc_buffer_ptr[index].buf_addr = NULL;
4724 m_desc_buffer_ptr[index].desc_data_size = 0;
4725 }
4726#ifdef USE_ION
4727 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4728#endif
4729 }
4730 }
4731
4732 return OMX_ErrorNone;
4733}
4734
4735OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4736{
4737 unsigned int index = 0;
4738
4739 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4740 {
4741 return OMX_ErrorBadParameter;
4742 }
4743
4744 index = bufferHdr - m_out_mem_ptr;
4745 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4746
4747 if (index < drv_ctx.op_buf.actualcount
4748 && drv_ctx.ptr_outputbuffer)
4749 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004750 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004751 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4752
Shalaj Jain273b3e02012-06-22 19:08:03 -07004753 struct vdec_setbuffer_cmd setbuffers;
4754 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4755 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4756 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004757#ifdef _ANDROID_
4758 if(m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004759 if (!secure_mode) {
4760 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4761 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4762 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004764 }
4765 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4766 } else {
4767#endif
4768 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4769 {
Praveen Chavan212671f2013-04-05 20:00:42 -07004770 if (!secure_mode) {
4771 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4772 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4773 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4774 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4775 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4776 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4777 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4778 }
4779 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4780 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004781#ifdef USE_ION
Praveen Chavan212671f2013-04-05 20:00:42 -07004782 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004783#endif
4784 }
4785#ifdef _ANDROID_
4786 }
4787#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004788 if (release_output_done()) {
4789 free_extradata();
4790 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004791 }
4792
4793 return OMX_ErrorNone;
4794
4795}
4796
4797OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4798 OMX_BUFFERHEADERTYPE **bufferHdr,
4799 OMX_U32 port,
4800 OMX_PTR appData,
4801 OMX_U32 bytes)
4802{
4803 OMX_BUFFERHEADERTYPE *input = NULL;
4804 unsigned char *buf_addr = NULL;
4805 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4806 unsigned i = 0;
4807
4808 /* Sanity Check*/
4809 if (bufferHdr == NULL)
4810 {
4811 return OMX_ErrorBadParameter;
4812 }
4813
4814 if (m_inp_heap_ptr == NULL)
4815 {
4816 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4817 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4818 drv_ctx.ip_buf.actualcount);
4819 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4820 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4821 drv_ctx.ip_buf.actualcount);
4822
4823 if (m_inp_heap_ptr == NULL)
4824 {
4825 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4826 return OMX_ErrorInsufficientResources;
4827 }
4828 }
4829
4830 /*Find a Free index*/
4831 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4832 {
4833 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4834 {
4835 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4836 break;
4837 }
4838 }
4839
4840 if (i < drv_ctx.ip_buf.actualcount)
4841 {
4842 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4843
4844 if (buf_addr == NULL)
4845 {
4846 return OMX_ErrorInsufficientResources;
4847 }
4848
4849 *bufferHdr = (m_inp_heap_ptr + i);
4850 input = *bufferHdr;
4851 BITMASK_SET(&m_heap_inp_bm_count,i);
4852
4853 input->pBuffer = (OMX_U8 *)buf_addr;
4854 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4855 input->nVersion.nVersion = OMX_SPEC_VERSION;
4856 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4857 input->pAppPrivate = appData;
4858 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4859 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4860 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004861 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004862 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004863 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4864 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004865 {
4866 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4867 return OMX_ErrorInsufficientResources;
4868 }
4869 }
4870 else
4871 {
4872 return OMX_ErrorBadParameter;
4873 }
4874
4875 return eRet;
4876
4877}
4878
4879
4880/* ======================================================================
4881FUNCTION
4882 omx_vdec::AllocateInputBuffer
4883
4884DESCRIPTION
4885 Helper function for allocate buffer in the input pin
4886
4887PARAMETERS
4888 None.
4889
4890RETURN VALUE
4891 true/false
4892
4893========================================================================== */
4894OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4895 OMX_IN OMX_HANDLETYPE hComp,
4896 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4897 OMX_IN OMX_U32 port,
4898 OMX_IN OMX_PTR appData,
4899 OMX_IN OMX_U32 bytes)
4900{
4901
4902 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4903 struct vdec_setbuffer_cmd setbuffers;
4904 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004905 unsigned i = 0;
4906 unsigned char *buf_addr = NULL;
4907 int pmem_fd = -1;
4908
4909 if(bytes != drv_ctx.ip_buf.buffer_size)
4910 {
Shalaj Jainaf08f302013-03-18 13:15:35 -07004911 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07004912 bytes, drv_ctx.ip_buf.buffer_size);
4913 return OMX_ErrorBadParameter;
4914 }
4915
4916 if(!m_inp_mem_ptr)
4917 {
4918 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4919 drv_ctx.ip_buf.actualcount,
4920 drv_ctx.ip_buf.buffer_size);
4921
4922 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4923 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4924
4925 if (m_inp_mem_ptr == NULL)
4926 {
4927 return OMX_ErrorInsufficientResources;
4928 }
4929
4930 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4931 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4932
4933 if (drv_ctx.ptr_inputbuffer == NULL)
4934 {
4935 return OMX_ErrorInsufficientResources;
4936 }
4937#ifdef USE_ION
4938 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4939 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4940
4941 if (drv_ctx.ip_buf_ion_info == NULL)
4942 {
4943 return OMX_ErrorInsufficientResources;
4944 }
4945#endif
4946
4947 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4948 {
4949 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4950#ifdef USE_ION
4951 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4952#endif
4953 }
4954 }
4955
4956 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4957 {
4958 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4959 {
4960 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4961 break;
4962 }
4963 }
4964
4965 if(i < drv_ctx.ip_buf.actualcount)
4966 {
4967 struct v4l2_buffer buf;
4968 struct v4l2_plane plane;
4969 int rc;
4970 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4971#ifdef USE_ION
4972 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4973 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4974 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004975 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4977 return OMX_ErrorInsufficientResources;
4978 }
4979 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4980#else
4981 pmem_fd = open (MEM_DEVICE,O_RDWR);
4982
4983 if (pmem_fd < 0)
4984 {
4985 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4986 return OMX_ErrorInsufficientResources;
4987 }
4988
4989 if (pmem_fd == 0)
4990 {
4991 pmem_fd = open (MEM_DEVICE,O_RDWR);
4992
4993 if (pmem_fd < 0)
4994 {
4995 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4996 return OMX_ErrorInsufficientResources;
4997 }
4998 }
4999
5000 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5001 drv_ctx.ip_buf.alignment))
5002 {
5003 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5004 close(pmem_fd);
5005 return OMX_ErrorInsufficientResources;
5006 }
5007#endif
5008 if (!secure_mode) {
5009 buf_addr = (unsigned char *)mmap(NULL,
5010 drv_ctx.ip_buf.buffer_size,
5011 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5012
5013 if (buf_addr == MAP_FAILED)
5014 {
5015 close(pmem_fd);
5016#ifdef USE_ION
5017 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5018#endif
5019 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
5020 return OMX_ErrorInsufficientResources;
5021 }
5022 }
5023 *bufferHdr = (m_inp_mem_ptr + i);
5024 if (secure_mode)
5025 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5026 else
5027 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5028 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5029 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5030 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5031 drv_ctx.ptr_inputbuffer [i].offset = 0;
5032
5033
5034 buf.index = i;
5035 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5036 buf.memory = V4L2_MEMORY_USERPTR;
5037 plane.bytesused = 0;
5038 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5039 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5040 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5041 plane.reserved[1] = 0;
5042 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5043 buf.m.planes = &plane;
5044 buf.length = 1;
5045
Shalaj Jainaf08f302013-03-18 13:15:35 -07005046 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
5047 drv_ctx.ptr_inputbuffer[i].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005048
5049 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5050
5051 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005052 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005053 /*TODO: How to handle this case */
5054 return OMX_ErrorInsufficientResources;
5055 }
5056
5057 input = *bufferHdr;
5058 BITMASK_SET(&m_inp_bm_count,i);
5059 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
5060 if (secure_mode)
5061 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5062 else
5063 input->pBuffer = (OMX_U8 *)buf_addr;
5064 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5065 input->nVersion.nVersion = OMX_SPEC_VERSION;
5066 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5067 input->pAppPrivate = appData;
5068 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5069 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5070
5071 if (drv_ctx.disable_dmx)
5072 {
5073 eRet = allocate_desc_buffer(i);
5074 }
5075 }
5076 else
5077 {
5078 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
5079 eRet = OMX_ErrorInsufficientResources;
5080 }
5081 return eRet;
5082}
5083
5084
5085/* ======================================================================
5086FUNCTION
5087 omx_vdec::AllocateOutputBuffer
5088
5089DESCRIPTION
5090 Helper fn for AllocateBuffer in the output pin
5091
5092PARAMETERS
5093 <TBD>.
5094
5095RETURN VALUE
5096 OMX Error None if everything went well.
5097
5098========================================================================== */
5099OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
5100 OMX_IN OMX_HANDLETYPE hComp,
5101 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5102 OMX_IN OMX_U32 port,
5103 OMX_IN OMX_PTR appData,
5104 OMX_IN OMX_U32 bytes)
5105{
5106 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5107 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5108 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07005109 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005110 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005111#ifdef USE_ION
5112 int ion_device_fd =-1;
5113 struct ion_allocation_data ion_alloc_data;
5114 struct ion_fd_data fd_ion_data;
5115#endif
5116 if(!m_out_mem_ptr)
5117 {
5118 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
5119 drv_ctx.op_buf.actualcount,
5120 drv_ctx.op_buf.buffer_size);
5121 int nBufHdrSize = 0;
5122 int nPlatformEntrySize = 0;
5123 int nPlatformListSize = 0;
5124 int nPMEMInfoSize = 0;
5125 int pmem_fd = -1;
5126 unsigned char *pmem_baseaddress = NULL;
5127
5128 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5129 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5130 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
5131
5132 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
5133 drv_ctx.op_buf.actualcount);
5134 nBufHdrSize = drv_ctx.op_buf.actualcount *
5135 sizeof(OMX_BUFFERHEADERTYPE);
5136
5137 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5138 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5139 nPlatformListSize = drv_ctx.op_buf.actualcount *
5140 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5141 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5142 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
5143
5144 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
5145 sizeof(OMX_BUFFERHEADERTYPE),
5146 nPMEMInfoSize,
5147 nPlatformListSize);
5148 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
5149 drv_ctx.op_buf.actualcount);
5150#ifdef USE_ION
5151 ion_device_fd = alloc_map_ion_memory(
5152 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5153 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07005154 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005155 if (ion_device_fd < 0) {
5156 return OMX_ErrorInsufficientResources;
5157 }
5158 pmem_fd = fd_ion_data.fd;
5159#else
5160 pmem_fd = open (MEM_DEVICE,O_RDWR);
5161
5162 if (pmem_fd < 0)
5163 {
5164 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5165 drv_ctx.op_buf.buffer_size);
5166 return OMX_ErrorInsufficientResources;
5167 }
5168
5169 if(pmem_fd == 0)
5170 {
5171 pmem_fd = open (MEM_DEVICE,O_RDWR);
5172
5173 if (pmem_fd < 0)
5174 {
5175 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
5176 drv_ctx.op_buf.buffer_size);
5177 return OMX_ErrorInsufficientResources;
5178 }
5179 }
5180
5181 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5182 drv_ctx.op_buf.actualcount,
5183 drv_ctx.op_buf.alignment))
5184 {
5185 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
5186 close(pmem_fd);
5187 return OMX_ErrorInsufficientResources;
5188 }
5189#endif
5190 if (!secure_mode) {
5191 pmem_baseaddress = (unsigned char *)mmap(NULL,
5192 (drv_ctx.op_buf.buffer_size *
5193 drv_ctx.op_buf.actualcount),
5194 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5195 if (pmem_baseaddress == MAP_FAILED)
5196 {
5197 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5198 drv_ctx.op_buf.buffer_size);
5199 close(pmem_fd);
5200#ifdef USE_ION
5201 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5202#endif
5203 return OMX_ErrorInsufficientResources;
5204 }
5205 }
5206 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5207 // Alloc mem for platform specific info
5208 char *pPtr=NULL;
5209 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5210 nPMEMInfoSize,1);
5211 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5212 calloc (sizeof(struct vdec_bufferpayload),
5213 drv_ctx.op_buf.actualcount);
5214 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5215 calloc (sizeof (struct vdec_output_frameinfo),
5216 drv_ctx.op_buf.actualcount);
5217#ifdef USE_ION
5218 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5219 calloc (sizeof(struct vdec_ion),
5220 drv_ctx.op_buf.actualcount);
5221#endif
5222
5223 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5224 && drv_ctx.ptr_respbuffer)
5225 {
5226 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5227 (drv_ctx.op_buf.buffer_size *
5228 drv_ctx.op_buf.actualcount);
5229 bufHdr = m_out_mem_ptr;
5230 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5231 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5232 (((char *) m_platform_list) + nPlatformListSize);
5233 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5234 (((char *) m_platform_entry) + nPlatformEntrySize);
5235 pPlatformList = m_platform_list;
5236 pPlatformEntry = m_platform_entry;
5237 pPMEMInfo = m_pmem_info;
5238
5239 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5240
5241 // Settting the entire storage nicely
5242 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5243 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5244 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5245 {
5246 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5247 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5248 // Set the values when we determine the right HxW param
5249 bufHdr->nAllocLen = bytes;
5250 bufHdr->nFilledLen = 0;
5251 bufHdr->pAppPrivate = appData;
5252 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5253 // Platform specific PMEM Information
5254 // Initialize the Platform Entry
5255 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5256 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5257 pPlatformEntry->entry = pPMEMInfo;
5258 // Initialize the Platform List
5259 pPlatformList->nEntries = 1;
5260 pPlatformList->entryList = pPlatformEntry;
5261 // Keep pBuffer NULL till vdec is opened
5262 bufHdr->pBuffer = NULL;
5263 bufHdr->nOffset = 0;
5264
5265 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5266 pPMEMInfo->pmem_fd = 0;
5267 bufHdr->pPlatformPrivate = pPlatformList;
5268
5269 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005270 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005271#ifdef USE_ION
5272 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5273 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5274 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5275#endif
5276
5277 /*Create a mapping between buffers*/
5278 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5279 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5280 &drv_ctx.ptr_outputbuffer[i];
5281 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5282 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5283 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5284
5285 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5286 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5287 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5288 // Move the buffer and buffer header pointers
5289 bufHdr++;
5290 pPMEMInfo++;
5291 pPlatformEntry++;
5292 pPlatformList++;
5293 }
5294 }
5295 else
5296 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005297 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298 m_out_mem_ptr, pPtr);
5299 if(m_out_mem_ptr)
5300 {
5301 free(m_out_mem_ptr);
5302 m_out_mem_ptr = NULL;
5303 }
5304 if(pPtr)
5305 {
5306 free(pPtr);
5307 pPtr = NULL;
5308 }
5309 if(drv_ctx.ptr_outputbuffer)
5310 {
5311 free(drv_ctx.ptr_outputbuffer);
5312 drv_ctx.ptr_outputbuffer = NULL;
5313 }
5314 if(drv_ctx.ptr_respbuffer)
5315 {
5316 free(drv_ctx.ptr_respbuffer);
5317 drv_ctx.ptr_respbuffer = NULL;
5318 }
5319#ifdef USE_ION
5320 if (drv_ctx.op_buf_ion_info) {
5321 DEBUG_PRINT_LOW("\n Free o/p ion context");
5322 free(drv_ctx.op_buf_ion_info);
5323 drv_ctx.op_buf_ion_info = NULL;
5324 }
5325#endif
5326 eRet = OMX_ErrorInsufficientResources;
5327 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005328 if (eRet == OMX_ErrorNone)
5329 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005330 }
5331
5332 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5333 {
5334 if(BITMASK_ABSENT(&m_out_bm_count,i))
5335 {
5336 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5337 break;
5338 }
5339 }
5340
5341 if (eRet == OMX_ErrorNone)
5342 {
5343 if(i < drv_ctx.op_buf.actualcount)
5344 {
5345 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005346 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005347 int rc;
5348 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5349
5350 drv_ctx.ptr_outputbuffer[i].buffer_len =
5351 drv_ctx.op_buf.buffer_size;
5352
5353 *bufferHdr = (m_out_mem_ptr + i );
5354 if (secure_mode) {
5355 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5356 }
5357 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5358
5359 buf.index = i;
5360 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5361 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005362 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005363 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5364 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005366 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005367#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005368 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5369 plane[0].data_offset = 0;
5370 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5371 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5372 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5373 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5374#ifdef USE_ION
5375 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5376#endif
5377 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5378 plane[extra_idx].data_offset = 0;
5379 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5380 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5381 return OMX_ErrorBadParameter;
5382 }
5383 buf.m.planes = plane;
5384 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005385 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 -07005386 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5387 if (rc) {
5388 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005389 return OMX_ErrorInsufficientResources;
5390 }
5391
5392 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5393 enum v4l2_buf_type buf_type;
5394 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5395 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5396 if (rc) {
5397 return OMX_ErrorInsufficientResources;
5398 } else {
5399 streaming[CAPTURE_PORT] = true;
5400 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5401 }
5402 }
5403
5404 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5405 (*bufferHdr)->pAppPrivate = appData;
5406 BITMASK_SET(&m_out_bm_count,i);
5407 }
5408 else
5409 {
5410 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5411 eRet = OMX_ErrorInsufficientResources;
5412 }
5413 }
5414
5415 return eRet;
5416}
5417
5418
5419// AllocateBuffer -- API Call
5420/* ======================================================================
5421FUNCTION
5422 omx_vdec::AllocateBuffer
5423
5424DESCRIPTION
5425 Returns zero if all the buffers released..
5426
5427PARAMETERS
5428 None.
5429
5430RETURN VALUE
5431 true/false
5432
5433========================================================================== */
5434OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5435 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5436 OMX_IN OMX_U32 port,
5437 OMX_IN OMX_PTR appData,
5438 OMX_IN OMX_U32 bytes)
5439{
5440 unsigned i = 0;
5441 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5442
5443 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5444 if(m_state == OMX_StateInvalid)
5445 {
5446 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5447 return OMX_ErrorInvalidState;
5448 }
5449
5450 if(port == OMX_CORE_INPUT_PORT_INDEX)
5451 {
5452 if (arbitrary_bytes)
5453 {
5454 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5455 }
5456 else
5457 {
5458 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5459 }
5460 }
5461 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5462 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005463 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5464 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465 }
5466 else
5467 {
5468 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5469 eRet = OMX_ErrorBadPortIndex;
5470 }
5471 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5472 if(eRet == OMX_ErrorNone)
5473 {
5474 if(allocate_done()){
5475 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5476 {
5477 // Send the callback now
5478 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5479 post_event(OMX_CommandStateSet,OMX_StateIdle,
5480 OMX_COMPONENT_GENERATE_EVENT);
5481 }
5482 }
5483 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5484 {
5485 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5486 {
5487 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5488 post_event(OMX_CommandPortEnable,
5489 OMX_CORE_INPUT_PORT_INDEX,
5490 OMX_COMPONENT_GENERATE_EVENT);
5491 }
5492 }
5493 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5494 {
5495 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5496 {
5497 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5498 post_event(OMX_CommandPortEnable,
5499 OMX_CORE_OUTPUT_PORT_INDEX,
5500 OMX_COMPONENT_GENERATE_EVENT);
5501 }
5502 }
5503 }
5504 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5505 return eRet;
5506}
5507
5508// Free Buffer - API call
5509/* ======================================================================
5510FUNCTION
5511 omx_vdec::FreeBuffer
5512
5513DESCRIPTION
5514
5515PARAMETERS
5516 None.
5517
5518RETURN VALUE
5519 true/false
5520
5521========================================================================== */
5522OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5523 OMX_IN OMX_U32 port,
5524 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5525{
5526 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5527 unsigned int nPortIndex;
5528 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5529
5530 if(m_state == OMX_StateIdle &&
5531 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5532 {
5533 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5534 }
5535 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5536 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5537 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005538 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005539 }
Arun Menon9f098152013-05-08 13:53:54 -07005540 else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5541 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5542 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5543 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)))
5544 {
5545 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
5546 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005547 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5548 {
5549 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5550 post_event(OMX_EventError,
5551 OMX_ErrorPortUnpopulated,
5552 OMX_COMPONENT_GENERATE_EVENT);
5553
5554 return OMX_ErrorIncorrectStateOperation;
5555 }
5556 else if (m_state != OMX_StateInvalid)
5557 {
5558 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5559 post_event(OMX_EventError,
5560 OMX_ErrorPortUnpopulated,
5561 OMX_COMPONENT_GENERATE_EVENT);
5562 }
5563
5564 if(port == OMX_CORE_INPUT_PORT_INDEX)
5565 {
5566 /*Check if arbitrary bytes*/
5567 if(!arbitrary_bytes && !input_use_buffer)
5568 nPortIndex = buffer - m_inp_mem_ptr;
5569 else
5570 nPortIndex = buffer - m_inp_heap_ptr;
5571
5572 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5573 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5574 {
5575 // Clear the bit associated with it.
5576 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5577 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5578 if (input_use_buffer == true)
5579 {
5580
5581 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5582 if(m_phdr_pmem_ptr)
5583 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5584 }
5585 else
5586 {
5587 if (arbitrary_bytes)
5588 {
5589 if(m_phdr_pmem_ptr)
5590 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5591 else
5592 free_input_buffer(nPortIndex,NULL);
5593 }
5594 else
5595 free_input_buffer(buffer);
5596 }
5597 m_inp_bPopulated = OMX_FALSE;
5598 /*Free the Buffer Header*/
5599 if (release_input_done())
5600 {
5601 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5602 free_input_buffer_header();
5603 }
5604 }
5605 else
5606 {
5607 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5608 eRet = OMX_ErrorBadPortIndex;
5609 }
5610
5611 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5612 && release_input_done())
5613 {
5614 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5615 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5616 post_event(OMX_CommandPortDisable,
5617 OMX_CORE_INPUT_PORT_INDEX,
5618 OMX_COMPONENT_GENERATE_EVENT);
5619 }
5620 }
5621 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5622 {
5623 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005624 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005625 if(nPortIndex < drv_ctx.op_buf.actualcount)
5626 {
5627 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5628 // Clear the bit associated with it.
5629 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5630 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005631 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632
5633 if (release_output_done())
5634 {
5635 free_output_buffer_header();
5636 }
5637 }
5638 else
5639 {
5640 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5641 eRet = OMX_ErrorBadPortIndex;
5642 }
5643 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5644 && release_output_done())
5645 {
5646 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5647
5648 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5649 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5650#ifdef _ANDROID_ICS_
5651 if (m_enable_android_native_buffers)
5652 {
5653 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5654 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5655 }
5656#endif
5657
5658 post_event(OMX_CommandPortDisable,
5659 OMX_CORE_OUTPUT_PORT_INDEX,
5660 OMX_COMPONENT_GENERATE_EVENT);
5661 }
5662 }
5663 else
5664 {
5665 eRet = OMX_ErrorBadPortIndex;
5666 }
5667 if((eRet == OMX_ErrorNone) &&
5668 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5669 {
5670 if(release_done())
5671 {
5672 // Send the callback now
5673 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5674 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5675 OMX_COMPONENT_GENERATE_EVENT);
5676 }
5677 }
5678 return eRet;
5679}
5680
5681
5682/* ======================================================================
5683FUNCTION
5684 omx_vdec::EmptyThisBuffer
5685
5686DESCRIPTION
5687 This routine is used to push the encoded video frames to
5688 the video decoder.
5689
5690PARAMETERS
5691 None.
5692
5693RETURN VALUE
5694 OMX Error None if everything went successful.
5695
5696========================================================================== */
5697OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5698 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5699{
5700 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5701 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5702
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005703 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
5704 {
5705 codec_config_flag = true;
5706 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5707 }
5708 else
5709 {
5710 codec_config_flag = false;
5711 }
5712
Shalaj Jain273b3e02012-06-22 19:08:03 -07005713 if(m_state == OMX_StateInvalid)
5714 {
5715 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5716 return OMX_ErrorInvalidState;
5717 }
5718
5719 if (buffer == NULL)
5720 {
5721 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5722 return OMX_ErrorBadParameter;
5723 }
5724
5725 if (!m_inp_bEnabled)
5726 {
5727 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5728 return OMX_ErrorIncorrectStateOperation;
5729 }
5730
5731 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5732 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005733 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005734 return OMX_ErrorBadPortIndex;
5735 }
5736
5737#ifdef _ANDROID_
5738 if(iDivXDrmDecrypt)
5739 {
5740 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5741 if(drmErr != OMX_ErrorNone) {
5742 // this error can be ignored
5743 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5744 }
5745 }
5746#endif //_ANDROID_
5747 if (perf_flag)
5748 {
5749 if (!latency)
5750 {
5751 dec_time.stop();
5752 latency = dec_time.processing_time_us();
5753 dec_time.start();
5754 }
5755 }
5756
5757 if (arbitrary_bytes)
5758 {
5759 nBufferIndex = buffer - m_inp_heap_ptr;
5760 }
5761 else
5762 {
5763 if (input_use_buffer == true)
5764 {
5765 nBufferIndex = buffer - m_inp_heap_ptr;
5766 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5767 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5768 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5769 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005770 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 -07005771 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5772 }
5773 else{
5774 nBufferIndex = buffer - m_inp_mem_ptr;
5775 }
5776 }
5777
5778 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5779 {
5780 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5781 return OMX_ErrorBadParameter;
5782 }
5783
5784 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5785 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5786 if (arbitrary_bytes)
5787 {
5788 post_event ((unsigned)hComp,(unsigned)buffer,
5789 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5790 }
5791 else
5792 {
5793 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5794 set_frame_rate(buffer->nTimeStamp);
5795 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5796 }
5797 return OMX_ErrorNone;
5798}
5799
5800/* ======================================================================
5801FUNCTION
5802 omx_vdec::empty_this_buffer_proxy
5803
5804DESCRIPTION
5805 This routine is used to push the encoded video frames to
5806 the video decoder.
5807
5808PARAMETERS
5809 None.
5810
5811RETURN VALUE
5812 OMX Error None if everything went successful.
5813
5814========================================================================== */
5815OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5816 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5817{
5818 int push_cnt = 0,i=0;
5819 unsigned nPortIndex = 0;
5820 OMX_ERRORTYPE ret = OMX_ErrorNone;
5821 struct vdec_input_frameinfo frameinfo;
5822 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005823 struct vdec_seqheader seq_header;
5824 bool port_setting_changed = true;
5825 bool not_coded_vop = false;
5826
5827 /*Should we generate a Aync error event*/
5828 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5829 {
5830 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5831 return OMX_ErrorBadParameter;
5832 }
5833
5834 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5835
5836 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5837 {
5838 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5839 nPortIndex);
5840 return OMX_ErrorBadParameter;
5841 }
5842
5843 pending_input_buffers++;
5844
5845 /* return zero length and not an EOS buffer */
5846 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5847 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5848 {
5849 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5850 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5851 OMX_COMPONENT_GENERATE_EBD);
5852 return OMX_ErrorNone;
5853 }
5854
5855
5856 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5857 mp4StreamType psBits;
5858 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5859 psBits.numBytes = buffer->nFilledLen;
5860 mp4_headerparser.parseHeader(&psBits);
5861 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5862 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5863 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005864 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005865 buffer->nFilledLen,frame_count);
5866 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5867 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5868 not_coded_vop = false;
5869 buffer->nFilledLen = 0;
5870 }
5871 }
5872 }
5873
5874 if(input_flush_progress == true
5875
5876 || not_coded_vop
5877
5878 )
5879 {
5880 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5881 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5882 OMX_COMPONENT_GENERATE_EBD);
5883 return OMX_ErrorNone;
5884 }
5885
5886 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5887
5888 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5889 {
5890 return OMX_ErrorBadParameter;
5891 }
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +05305892 /* If its first frame, H264 codec and reject is true, then parse the nal
5893 and get the profile. Based on this, reject the clip playback */
5894 if(first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5895 m_reject_avc_1080p_mp)
5896 {
5897 first_frame = 1;
5898 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5899 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5900 NALU_TYPE_SPS);
5901 m_profile = h264_parser->get_profile();
5902 ret = is_video_session_supported();
5903 if (ret)
5904 {
5905 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5906 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5907 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5908 m_state = OMX_StateInvalid;
5909 return OMX_ErrorNone;
5910 }
5911 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912
5913 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5914 /*for use buffer we need to memcpy the data*/
5915 temp_buffer->buffer_len = buffer->nFilledLen;
5916
5917 if (input_use_buffer)
5918 {
5919 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5920 {
5921 if(arbitrary_bytes)
5922 {
5923 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5924 }
5925 else
5926 {
5927 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5928 buffer->nFilledLen);
5929 }
5930 }
5931 else
5932 {
5933 return OMX_ErrorBadParameter;
5934 }
5935
5936 }
5937
5938 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5939 frameinfo.client_data = (void *) buffer;
5940 frameinfo.datalen = temp_buffer->buffer_len;
5941 frameinfo.flags = 0;
5942 frameinfo.offset = buffer->nOffset;
5943 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5944 frameinfo.pmem_offset = temp_buffer->offset;
5945 frameinfo.timestamp = buffer->nTimeStamp;
5946 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5947 {
5948 DEBUG_PRINT_LOW("ETB: dmx enabled");
5949 if (m_demux_entries == 0)
5950 {
5951 extract_demux_addr_offsets(buffer);
5952 }
5953
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005954 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005955 handle_demux_data(buffer);
5956 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5957 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5958 }
5959 else
5960 {
5961 frameinfo.desc_addr = NULL;
5962 frameinfo.desc_size = 0;
5963 }
5964 if(!arbitrary_bytes)
5965 {
5966 frameinfo.flags |= buffer->nFlags;
5967 }
5968
5969#ifdef _ANDROID_
5970 if (m_debug_timestamp)
5971 {
5972 if(arbitrary_bytes)
5973 {
5974 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5975 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5976 }
5977 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5978 {
5979 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5980 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5981 }
5982 }
5983#endif
5984
5985#ifdef INPUT_BUFFER_LOG
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07005986 if (output_capability == V4L2_PIX_FMT_VP8) {
5987 struct vp8_ivf_frame_header{
5988 OMX_U32 framesize;
5989 OMX_U32 timestamp_lo;
5990 OMX_U32 timestamp_hi;
5991 } vp8_frame_header;
5992 vp8_frame_header.framesize = temp_buffer->buffer_len;
5993 /* Currently FW doesn't use timestamp values */
5994 vp8_frame_header.timestamp_lo = 0;
5995 vp8_frame_header.timestamp_hi = 0;
5996 if (inputBufferFile1)
5997 {
5998 fwrite((const char *)&vp8_frame_header,
5999 sizeof(vp8_frame_header),1,inputBufferFile1);
6000 fwrite((const char *)temp_buffer->bufferaddr,
6001 temp_buffer->buffer_len,1,inputBufferFile1);
6002 }
6003 } else {
6004 if (inputBufferFile1)
6005 {
6006 fwrite((const char *)temp_buffer->bufferaddr,
6007 temp_buffer->buffer_len,1,inputBufferFile1);
6008 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006009 }
6010#endif
6011
6012 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
6013 {
6014 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6015 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6016 }
6017
6018 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
6019 {
6020 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
6021 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
6022 h264_scratch.nFilledLen = 0;
6023 nal_count = 0;
6024 look_ahead_nal = false;
6025 frame_count = 0;
6026 if (m_frame_parser.mutils)
6027 m_frame_parser.mutils->initialize_frame_checking_environment();
6028 m_frame_parser.flush();
6029 h264_last_au_ts = LLONG_MAX;
6030 h264_last_au_flags = 0;
6031 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
6032 m_demux_entries = 0;
6033 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08006034 struct v4l2_buffer buf;
6035 struct v4l2_plane plane;
6036 memset( (void *)&buf, 0, sizeof(buf));
6037 memset( (void *)&plane, 0, sizeof(plane));
6038 int rc;
6039 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006040 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
6041 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07006042 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043 }
6044 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6045 buf.index = nPortIndex;
6046 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6047 buf.memory = V4L2_MEMORY_USERPTR;
6048 plane.bytesused = temp_buffer->buffer_len;
6049 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08006050 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
6051 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006052 plane.reserved[0] = temp_buffer->pmem_fd;
6053 plane.reserved[1] = temp_buffer->offset;
6054 plane.data_offset = 0;
6055 buf.m.planes = &plane;
6056 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08006057 if (frameinfo.timestamp >= LLONG_MAX) {
6058 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
6059 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006060 //assumption is that timestamp is in milliseconds
6061 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
6062 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07006063 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
Praneeth Paladugua63cfa62013-06-28 11:29:49 -07006064 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07006065
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07006067 if(rc)
6068 {
6069 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
6070 return OMX_ErrorHardware;
6071 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072 if(!streaming[OUTPUT_PORT])
6073 {
6074 enum v4l2_buf_type buf_type;
6075 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07006076
Shalaj Jain273b3e02012-06-22 19:08:03 -07006077 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6078 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
6079 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
6080 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07006081 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006082 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083 } else{
Ashray Kulkarni46373df2012-06-05 20:11:31 -07006084 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Arun Menon4d7d3b52013-05-23 11:43:50 -07006085 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
6086 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
Praneeth Paladugub227af72013-05-08 01:33:06 -07006087 OMX_COMPONENT_GENERATE_EBD);
Praneeth Paladugub227af72013-05-08 01:33:06 -07006088 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006089 }
6090}
6091 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
6092 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
6093 time_stamp_dts.insert_timestamp(buffer);
6094
6095 return ret;
6096}
6097
6098/* ======================================================================
6099FUNCTION
6100 omx_vdec::FillThisBuffer
6101
6102DESCRIPTION
6103 IL client uses this method to release the frame buffer
6104 after displaying them.
6105
6106PARAMETERS
6107 None.
6108
6109RETURN VALUE
6110 true/false
6111
6112========================================================================== */
6113OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
6114 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
6115{
6116
6117 if(m_state == OMX_StateInvalid)
6118 {
6119 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
6120 return OMX_ErrorInvalidState;
6121 }
6122
6123 if (!m_out_bEnabled)
6124 {
6125 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
6126 return OMX_ErrorIncorrectStateOperation;
6127 }
6128
Vinay Kaliada4f4422013-01-09 10:45:03 -08006129 if (buffer == NULL ||
6130 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006131 {
6132 return OMX_ErrorBadParameter;
6133 }
6134
6135 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
6136 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08006137 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006138 return OMX_ErrorBadPortIndex;
6139 }
6140
6141 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08006142 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006143 return OMX_ErrorNone;
6144}
6145/* ======================================================================
6146FUNCTION
6147 omx_vdec::fill_this_buffer_proxy
6148
6149DESCRIPTION
6150 IL client uses this method to release the frame buffer
6151 after displaying them.
6152
6153PARAMETERS
6154 None.
6155
6156RETURN VALUE
6157 true/false
6158
6159========================================================================== */
6160OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
6161 OMX_IN OMX_HANDLETYPE hComp,
6162 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
6163{
6164 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6166 unsigned nPortIndex = 0;
6167 struct vdec_fillbuffer_cmd fillbuffer;
6168 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6169 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
6170
Vinay Kaliada4f4422013-01-09 10:45:03 -08006171 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006172
Vinay Kaliada4f4422013-01-09 10:45:03 -08006173 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174 return OMX_ErrorBadParameter;
6175
6176 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
6177 bufferAdd, bufferAdd->pBuffer);
6178 /*Return back the output buffer to client*/
6179 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
6180 {
6181 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
6182 buffer->nFilledLen = 0;
6183 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6184 return OMX_ErrorNone;
6185 }
6186 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006187 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006188 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6189 if (ptr_respbuffer)
6190 {
6191 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6192 }
6193
6194 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
6195 {
6196 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6197 buffer->nFilledLen = 0;
6198 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6199 pending_output_buffers--;
6200 return OMX_ErrorBadParameter;
6201 }
6202
Shalaj Jain286b0062013-02-21 20:35:48 -08006203 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07006204 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08006205 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07006206
6207#ifdef _ANDROID_ICS_
6208 if (m_enable_android_native_buffers)
6209 {
6210 // Acquire a write lock on this buffer.
6211 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
6212 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
6213 DEBUG_PRINT_ERROR("Failed to acquire genlock");
6214 buffer->nFilledLen = 0;
6215 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6216 pending_output_buffers--;
6217 return OMX_ErrorInsufficientResources;
6218 } else {
6219 native_buffer[buffer - m_out_mem_ptr].inuse = true;
6220 }
6221 }
6222#endif
6223 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08006224 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006225 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08006226 memset( (void *)&buf, 0, sizeof(buf));
6227 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006228 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006230 buf.index = nPortIndex;
6231 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6232 buf.memory = V4L2_MEMORY_USERPTR;
6233 plane[0].bytesused = buffer->nFilledLen;
6234 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08006235 plane[0].m.userptr =
6236 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6237 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006238 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6239 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6240 plane[0].data_offset = 0;
6241 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6242 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6243 plane[extra_idx].bytesused = 0;
6244 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6245 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
6246#ifdef USE_ION
6247 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
6248#endif
6249 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6250 plane[extra_idx].data_offset = 0;
6251 } else if (extra_idx >= VIDEO_MAX_PLANES) {
6252 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
6253 return OMX_ErrorBadParameter;
6254 }
6255 buf.m.planes = plane;
6256 buf.length = drv_ctx.num_planes;
6257 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6258 if (rc) {
6259 /*TODO: How to handle this case */
6260 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6261 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006262//#ifdef _ANDROID_ICS_
6263 // if (m_enable_android_native_buffers)
6264 // {
6265 // Unlock the buffer
6266 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6267 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6268 // return OMX_ErrorInsufficientResources;
6269 /// } else {
6270 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6271 // }
6272 // }
6273//#endif
6274 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6275 // pending_output_buffers--;
6276 // return OMX_ErrorBadParameter;
6277 //}
6278 return OMX_ErrorNone;
6279}
6280
6281/* ======================================================================
6282FUNCTION
6283 omx_vdec::SetCallbacks
6284
6285DESCRIPTION
6286 Set the callbacks.
6287
6288PARAMETERS
6289 None.
6290
6291RETURN VALUE
6292 OMX Error None if everything successful.
6293
6294========================================================================== */
6295OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6296 OMX_IN OMX_CALLBACKTYPE* callbacks,
6297 OMX_IN OMX_PTR appData)
6298{
6299
6300 m_cb = *callbacks;
6301 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6302 m_cb.EventHandler,m_cb.FillBufferDone);
6303 m_app_data = appData;
6304 return OMX_ErrorNotImplemented;
6305}
6306
6307/* ======================================================================
6308FUNCTION
6309 omx_vdec::ComponentDeInit
6310
6311DESCRIPTION
6312 Destroys the component and release memory allocated to the heap.
6313
6314PARAMETERS
6315 <TBD>.
6316
6317RETURN VALUE
6318 OMX Error None if everything successful.
6319
6320========================================================================== */
6321OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6322{
6323#ifdef _ANDROID_
6324 if(iDivXDrmDecrypt)
6325 {
6326 delete iDivXDrmDecrypt;
6327 iDivXDrmDecrypt=NULL;
6328 }
6329#endif //_ANDROID_
6330
Shalaj Jain286b0062013-02-21 20:35:48 -08006331 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006332 if (OMX_StateLoaded != m_state)
6333 {
6334 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6335 m_state);
6336 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6337 }
6338 else
6339 {
6340 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6341 }
6342
6343 /*Check if the output buffers have to be cleaned up*/
6344 if(m_out_mem_ptr)
6345 {
6346 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006347 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006348 {
6349 free_output_buffer (&m_out_mem_ptr[i]);
6350#ifdef _ANDROID_ICS_
6351 if (m_enable_android_native_buffers)
6352 {
6353 if (native_buffer[i].inuse)
6354 {
6355 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6356 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6357 }
6358 native_buffer[i].inuse = false;
6359 }
6360 }
6361#endif
6362 }
6363#ifdef _ANDROID_ICS_
6364 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6365#endif
6366 }
6367
6368 /*Check if the input buffers have to be cleaned up*/
6369 if(m_inp_mem_ptr || m_inp_heap_ptr)
6370 {
6371 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006372 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006373 {
6374 if (m_inp_mem_ptr)
6375 free_input_buffer (i,&m_inp_mem_ptr[i]);
6376 else
6377 free_input_buffer (i,NULL);
6378 }
6379 }
6380 free_input_buffer_header();
6381 free_output_buffer_header();
6382 if(h264_scratch.pBuffer)
6383 {
6384 free(h264_scratch.pBuffer);
6385 h264_scratch.pBuffer = NULL;
6386 }
6387
6388 if (h264_parser)
6389 {
6390 delete h264_parser;
6391 h264_parser = NULL;
6392 }
6393
6394 if(m_platform_list)
6395 {
6396 free(m_platform_list);
6397 m_platform_list = NULL;
6398 }
6399 if(m_vendor_config.pData)
6400 {
6401 free(m_vendor_config.pData);
6402 m_vendor_config.pData = NULL;
6403 }
6404
6405 // Reset counters in mesg queues
6406 m_ftb_q.m_size=0;
6407 m_cmd_q.m_size=0;
6408 m_etb_q.m_size=0;
6409 m_ftb_q.m_read = m_ftb_q.m_write =0;
6410 m_cmd_q.m_read = m_cmd_q.m_write =0;
6411 m_etb_q.m_read = m_etb_q.m_write =0;
6412#ifdef _ANDROID_
6413 if (m_debug_timestamp)
6414 {
6415 m_timestamp_list.reset_ts_list();
6416 }
6417#endif
6418
6419 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6420 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6421 // NULL);
6422 DEBUG_PRINT_HIGH("\n Close the driver instance");
6423
6424#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006425 if (inputBufferFile1)
6426 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006427#endif
6428#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006429 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07006430 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006431#endif
6432#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006433 if (outputExtradataFile)
6434 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006435#endif
6436 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6437 return OMX_ErrorNone;
6438}
6439
6440/* ======================================================================
6441FUNCTION
6442 omx_vdec::UseEGLImage
6443
6444DESCRIPTION
6445 OMX Use EGL Image method implementation <TBD>.
6446
6447PARAMETERS
6448 <TBD>.
6449
6450RETURN VALUE
6451 Not Implemented error.
6452
6453========================================================================== */
6454OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6455 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6456 OMX_IN OMX_U32 port,
6457 OMX_IN OMX_PTR appData,
6458 OMX_IN void* eglImage)
6459{
6460 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6461 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6462 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6463
6464#ifdef USE_EGL_IMAGE_GPU
6465 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6466 EGLint fd = -1, offset = 0,pmemPtr = 0;
6467#else
6468 int fd = -1, offset = 0;
6469#endif
6470 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6471 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6472 DEBUG_PRINT_ERROR("\n ");
6473 }
6474#ifdef USE_EGL_IMAGE_GPU
6475 if(m_display_id == NULL) {
6476 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6477 return OMX_ErrorInsufficientResources;
6478 }
6479 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6480 eglGetProcAddress("eglQueryImageKHR");
6481 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6482 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6483 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6484#else //with OMX test app
6485 struct temp_egl {
6486 int pmem_fd;
6487 int offset;
6488 };
6489 struct temp_egl *temp_egl_id = NULL;
6490 void * pmemPtr = (void *) eglImage;
6491 temp_egl_id = (struct temp_egl *)eglImage;
6492 if (temp_egl_id != NULL)
6493 {
6494 fd = temp_egl_id->pmem_fd;
6495 offset = temp_egl_id->offset;
6496 }
6497#endif
6498 if (fd < 0) {
6499 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6500 return OMX_ErrorInsufficientResources;
6501 }
6502 pmem_info.pmem_fd = (OMX_U32) fd;
6503 pmem_info.offset = (OMX_U32) offset;
6504 pmem_entry.entry = (void *) &pmem_info;
6505 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6506 pmem_list.entryList = &pmem_entry;
6507 pmem_list.nEntries = 1;
6508 ouput_egl_buffers = true;
6509 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6510 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6511 (OMX_U8 *)pmemPtr)) {
6512 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6513 return OMX_ErrorInsufficientResources;
6514 }
6515 return OMX_ErrorNone;
6516}
6517
6518/* ======================================================================
6519FUNCTION
6520 omx_vdec::ComponentRoleEnum
6521
6522DESCRIPTION
6523 OMX Component Role Enum method implementation.
6524
6525PARAMETERS
6526 <TBD>.
6527
6528RETURN VALUE
6529 OMX Error None if everything is successful.
6530========================================================================== */
6531OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6532 OMX_OUT OMX_U8* role,
6533 OMX_IN OMX_U32 index)
6534{
6535 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6536
6537 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6538 {
6539 if((0 == index) && role)
6540 {
6541 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6542 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6543 }
6544 else
6545 {
6546 eRet = OMX_ErrorNoMore;
6547 }
6548 }
6549 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6550 {
6551 if((0 == index) && role)
6552 {
6553 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6554 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6555 }
6556 else
6557 {
6558 eRet = OMX_ErrorNoMore;
6559 }
6560 }
6561 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6562 {
6563 if((0 == index) && role)
6564 {
6565 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6566 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6567 }
6568 else
6569 {
6570 DEBUG_PRINT_LOW("\n No more roles \n");
6571 eRet = OMX_ErrorNoMore;
6572 }
6573 }
6574
6575 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6576 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6577 )
6578
6579 {
6580 if((0 == index) && role)
6581 {
6582 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6583 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6584 }
6585 else
6586 {
6587 DEBUG_PRINT_LOW("\n No more roles \n");
6588 eRet = OMX_ErrorNoMore;
6589 }
6590 }
6591 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6592 {
6593 if((0 == index) && role)
6594 {
6595 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6596 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6597 }
6598 else
6599 {
6600 DEBUG_PRINT_LOW("\n No more roles \n");
6601 eRet = OMX_ErrorNoMore;
6602 }
6603 }
6604 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6605 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6606 )
6607 {
6608 if((0 == index) && role)
6609 {
6610 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6611 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6612 }
6613 else
6614 {
6615 DEBUG_PRINT_LOW("\n No more roles \n");
6616 eRet = OMX_ErrorNoMore;
6617 }
6618 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006619 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6620 {
6621 if((0 == index) && role)
6622 {
6623 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6624 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6625 }
6626 else
6627 {
6628 DEBUG_PRINT_LOW("\n No more roles \n");
6629 eRet = OMX_ErrorNoMore;
6630 }
6631 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632 else
6633 {
6634 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6635 eRet = OMX_ErrorInvalidComponentName;
6636 }
6637 return eRet;
6638}
6639
6640
6641
6642
6643/* ======================================================================
6644FUNCTION
6645 omx_vdec::AllocateDone
6646
6647DESCRIPTION
6648 Checks if entire buffer pool is allocated by IL Client or not.
6649 Need this to move to IDLE state.
6650
6651PARAMETERS
6652 None.
6653
6654RETURN VALUE
6655 true/false.
6656
6657========================================================================== */
6658bool omx_vdec::allocate_done(void)
6659{
6660 bool bRet = false;
6661 bool bRet_In = false;
6662 bool bRet_Out = false;
6663
6664 bRet_In = allocate_input_done();
6665 bRet_Out = allocate_output_done();
6666
6667 if(bRet_In && bRet_Out)
6668 {
6669 bRet = true;
6670 }
6671
6672 return bRet;
6673}
6674/* ======================================================================
6675FUNCTION
6676 omx_vdec::AllocateInputDone
6677
6678DESCRIPTION
6679 Checks if I/P buffer pool is allocated by IL Client or not.
6680
6681PARAMETERS
6682 None.
6683
6684RETURN VALUE
6685 true/false.
6686
6687========================================================================== */
6688bool omx_vdec::allocate_input_done(void)
6689{
6690 bool bRet = false;
6691 unsigned i=0;
6692
6693 if (m_inp_mem_ptr == NULL)
6694 {
6695 return bRet;
6696 }
6697 if(m_inp_mem_ptr )
6698 {
6699 for(;i<drv_ctx.ip_buf.actualcount;i++)
6700 {
6701 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6702 {
6703 break;
6704 }
6705 }
6706 }
6707 if(i == drv_ctx.ip_buf.actualcount)
6708 {
6709 bRet = true;
6710 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6711 }
6712 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6713 {
6714 m_inp_bPopulated = OMX_TRUE;
6715 }
6716 return bRet;
6717}
6718/* ======================================================================
6719FUNCTION
6720 omx_vdec::AllocateOutputDone
6721
6722DESCRIPTION
6723 Checks if entire O/P buffer pool is allocated by IL Client or not.
6724
6725PARAMETERS
6726 None.
6727
6728RETURN VALUE
6729 true/false.
6730
6731========================================================================== */
6732bool omx_vdec::allocate_output_done(void)
6733{
6734 bool bRet = false;
6735 unsigned j=0;
6736
6737 if (m_out_mem_ptr == NULL)
6738 {
6739 return bRet;
6740 }
6741
6742 if (m_out_mem_ptr)
6743 {
6744 for(;j < drv_ctx.op_buf.actualcount;j++)
6745 {
6746 if(BITMASK_ABSENT(&m_out_bm_count,j))
6747 {
6748 break;
6749 }
6750 }
6751 }
6752
6753 if(j == drv_ctx.op_buf.actualcount)
6754 {
6755 bRet = true;
6756 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6757 if(m_out_bEnabled)
6758 m_out_bPopulated = OMX_TRUE;
6759 }
6760
6761 return bRet;
6762}
6763
6764/* ======================================================================
6765FUNCTION
6766 omx_vdec::ReleaseDone
6767
6768DESCRIPTION
6769 Checks if IL client has released all the buffers.
6770
6771PARAMETERS
6772 None.
6773
6774RETURN VALUE
6775 true/false
6776
6777========================================================================== */
6778bool omx_vdec::release_done(void)
6779{
6780 bool bRet = false;
6781
6782 if(release_input_done())
6783 {
6784 if(release_output_done())
6785 {
6786 bRet = true;
6787 }
6788 }
6789 return bRet;
6790}
6791
6792
6793/* ======================================================================
6794FUNCTION
6795 omx_vdec::ReleaseOutputDone
6796
6797DESCRIPTION
6798 Checks if IL client has released all the buffers.
6799
6800PARAMETERS
6801 None.
6802
6803RETURN VALUE
6804 true/false
6805
6806========================================================================== */
6807bool omx_vdec::release_output_done(void)
6808{
6809 bool bRet = false;
6810 unsigned i=0,j=0;
6811
6812 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6813 if(m_out_mem_ptr)
6814 {
6815 for(;j < drv_ctx.op_buf.actualcount ; j++)
6816 {
6817 if(BITMASK_PRESENT(&m_out_bm_count,j))
6818 {
6819 break;
6820 }
6821 }
6822 if(j == drv_ctx.op_buf.actualcount)
6823 {
6824 m_out_bm_count = 0;
6825 bRet = true;
6826 }
6827 }
6828 else
6829 {
6830 m_out_bm_count = 0;
6831 bRet = true;
6832 }
6833 return bRet;
6834}
6835/* ======================================================================
6836FUNCTION
6837 omx_vdec::ReleaseInputDone
6838
6839DESCRIPTION
6840 Checks if IL client has released all the buffers.
6841
6842PARAMETERS
6843 None.
6844
6845RETURN VALUE
6846 true/false
6847
6848========================================================================== */
6849bool omx_vdec::release_input_done(void)
6850{
6851 bool bRet = false;
6852 unsigned i=0,j=0;
6853
6854 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6855 if(m_inp_mem_ptr)
6856 {
6857 for(;j<drv_ctx.ip_buf.actualcount;j++)
6858 {
6859 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6860 {
6861 break;
6862 }
6863 }
6864 if(j==drv_ctx.ip_buf.actualcount)
6865 {
6866 bRet = true;
6867 }
6868 }
6869 else
6870 {
6871 bRet = true;
6872 }
6873 return bRet;
6874}
6875
6876OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6877 OMX_BUFFERHEADERTYPE * buffer)
6878{
6879 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6880 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6881 {
6882 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6883 return OMX_ErrorBadParameter;
6884 }
6885 else if (output_flush_progress)
6886 {
6887 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6888 buffer->nFilledLen = 0;
6889 buffer->nTimeStamp = 0;
6890 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6891 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6892 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6893 }
6894
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006895 if (m_debug_extradata)
6896 {
6897 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
6898 {
6899 DEBUG_PRINT_HIGH("\n");
6900 DEBUG_PRINT_HIGH("***************************************************\n");
6901 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6902 DEBUG_PRINT_HIGH("***************************************************\n");
6903 }
6904
6905 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT)
6906 {
6907 DEBUG_PRINT_HIGH("\n");
6908 DEBUG_PRINT_HIGH("***************************************************\n");
6909 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6910 DEBUG_PRINT_HIGH("***************************************************\n");
6911 }
6912 }
6913
6914
Shalaj Jain273b3e02012-06-22 19:08:03 -07006915 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6916 buffer, buffer->pBuffer);
6917 pending_output_buffers --;
6918
6919 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6920 {
6921 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6922 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006923 post_event((unsigned)NULL, (unsigned)NULL,
6924 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006925
6926 if (psource_frame)
6927 {
6928 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6929 psource_frame = NULL;
6930 }
6931 if (pdest_frame)
6932 {
6933 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006934 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6935 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006936 pdest_frame = NULL;
6937 }
6938 }
6939
6940 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6941#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006942 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006943 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006944 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006945 int stride = drv_ctx.video_resolution.stride;
6946 int scanlines = drv_ctx.video_resolution.scan_lines;
6947 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Shalaj Jainaf08f302013-03-18 13:15:35 -07006948 unsigned i;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006949 int bytes_written = 0;
6950 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6951 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6952 temp += stride;
6953 }
6954 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006955 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006956 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6957 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6958 temp += stride_c;
6959 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006960 }
6961#endif
6962
6963 /* For use buffer we need to copy the data */
6964 if (!output_flush_progress)
6965 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006966 /* This is the error check for non-recoverable errros */
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006967 bool is_duplicate_ts_valid = true;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006968 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
6969
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006970 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
Arun Menonc67b40d2013-07-08 10:31:23 -07006971 output_capability == V4L2_PIX_FMT_MPEG2 ||
Praneeth Paladugu7ea099f2013-03-28 10:22:00 -07006972 output_capability == V4L2_PIX_FMT_DIVX ||
6973 output_capability == V4L2_PIX_FMT_DIVX_311)
6974 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006975
Arun Menon5cf24e92013-06-17 15:07:04 -07006976 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6977 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6978 if (mbaff) {
6979 is_interlaced = false;
6980 }
6981 }
6982
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006983 if (buffer->nFilledLen > 0) {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006984 time_stamp_dts.get_next_timestamp(buffer,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006985 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306986 if (m_debug_timestamp)
6987 {
6988 {
6989 OMX_TICKS expected_ts = 0;
6990 m_timestamp_list.pop_min_ts(expected_ts);
6991 if (is_interlaced && is_duplicate_ts_valid) {
6992 m_timestamp_list.pop_min_ts(expected_ts);
6993 }
6994 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6995 buffer->nTimeStamp, expected_ts);
6996
6997 if (buffer->nTimeStamp != expected_ts) {
6998 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6999 }
7000 }
7001 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007002 } else {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07007003 m_inp_err_count++;
7004 time_stamp_dts.remove_time_stamp(
7005 buffer->nTimeStamp,
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007006 is_interlaced && is_duplicate_ts_valid);
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07007007 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007008
Praneeth Paladugu451eec92013-01-31 22:45:45 -08007009
Shalaj Jain273b3e02012-06-22 19:08:03 -07007010 }
7011 if (m_cb.FillBufferDone)
7012 {
7013 if (buffer->nFilledLen > 0)
7014 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007015 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007016 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007017 set_frame_rate(buffer->nTimeStamp);
7018 else if (arbitrary_bytes)
7019 adjust_timestamp(buffer->nTimeStamp);
7020 if (perf_flag)
7021 {
7022 if (!proc_frms)
7023 {
7024 dec_time.stop();
7025 latency = dec_time.processing_time_us() - latency;
7026 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
7027 dec_time.start();
7028 fps_metrics.start();
7029 }
7030 proc_frms++;
7031 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
7032 {
7033 OMX_U64 proc_time = 0;
7034 fps_metrics.stop();
7035 proc_time = fps_metrics.processing_time_us();
7036 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
7037 proc_frms, (float)proc_time / 1e6,
7038 (float)(1e6 * proc_frms) / proc_time);
7039 proc_frms = 0;
7040 }
7041 }
7042
7043#ifdef OUTPUT_EXTRADATA_LOG
7044 if (outputExtradataFile)
7045 {
7046
7047 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
7048 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7049 ((unsigned)(buffer->pBuffer + buffer->nOffset +
7050 buffer->nFilledLen + 3)&(~3));
7051 while(p_extra &&
7052 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
7053 {
7054 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
7055 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
7056 if (p_extra->eType == OMX_ExtraDataNone)
7057 {
7058 break;
7059 }
7060 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7061 }
7062 }
7063#endif
7064 }
7065 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
7066 prev_ts = LLONG_MAX;
7067 rst_prev_ts = true;
7068 }
7069
7070 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7071 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
7072 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007073 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007074#ifdef _ANDROID_ICS_
7075 if (m_enable_android_native_buffers)
7076 {
7077 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
7078 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
7079 DEBUG_PRINT_ERROR("Unlocking genlock failed");
7080 return OMX_ErrorInsufficientResources;
7081 }
7082 else {
7083 native_buffer[buffer - m_out_mem_ptr].inuse = false;
7084 }
7085 }
7086 }
7087#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08007088 OMX_BUFFERHEADERTYPE *il_buffer;
7089 il_buffer = client_buffers.get_il_buf_hdr(buffer);
7090 if (il_buffer)
7091 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
7092 else {
7093 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
7094 return OMX_ErrorBadParameter;
7095 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007096 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007097 }
7098 else
7099 {
7100 return OMX_ErrorBadParameter;
7101 }
7102
7103 return OMX_ErrorNone;
7104}
7105
7106OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
7107 OMX_BUFFERHEADERTYPE* buffer)
7108{
7109
7110 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
7111 {
7112 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
7113 return OMX_ErrorBadParameter;
7114 }
7115
7116 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
7117 buffer, buffer->pBuffer);
7118 pending_input_buffers--;
7119
7120 if (arbitrary_bytes)
7121 {
7122 if (pdest_frame == NULL && input_flush_progress == false)
7123 {
7124 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
7125 pdest_frame = buffer;
7126 buffer->nFilledLen = 0;
7127 buffer->nTimeStamp = LLONG_MAX;
7128 push_input_buffer (hComp);
7129 }
7130 else
7131 {
7132 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
7133 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08007134 if (!m_input_free_q.insert_entry((unsigned)buffer,
7135 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007136 {
7137 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
7138 }
7139 }
7140 }
7141 else if(m_cb.EmptyBufferDone)
7142 {
7143 buffer->nFilledLen = 0;
7144 if (input_use_buffer == true){
7145 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
7146 }
7147 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
7148 }
7149 return OMX_ErrorNone;
7150}
7151
Shalaj Jain273b3e02012-06-22 19:08:03 -07007152int omx_vdec::async_message_process (void *context, void* message)
7153{
7154 omx_vdec* omx = NULL;
7155 struct vdec_msginfo *vdec_msg = NULL;
7156 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08007157 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007158 struct vdec_output_frameinfo *output_respbuf = NULL;
7159 int rc=1;
7160 if (context == NULL || message == NULL)
7161 {
7162 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
7163 return -1;
7164 }
7165 vdec_msg = (struct vdec_msginfo *)message;
7166
7167 omx = reinterpret_cast<omx_vdec*>(context);
7168
Shalaj Jain273b3e02012-06-22 19:08:03 -07007169 switch (vdec_msg->msgcode)
7170 {
7171
7172 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08007173 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007174 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7175 break;
7176
7177 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007178 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007179 OMX_COMPONENT_GENERATE_START_DONE);
7180 break;
7181
7182 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007183 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007184 OMX_COMPONENT_GENERATE_STOP_DONE);
7185 break;
7186
7187 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007188 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007189 OMX_COMPONENT_GENERATE_RESUME_DONE);
7190 break;
7191
7192 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007193 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007194 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7195 break;
7196
7197 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007198 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007199 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7200 break;
7201 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08007202 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7204 break;
7205 case VDEC_MSG_RESP_INPUT_FLUSHED:
7206 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7207
Shalaj Jain286b0062013-02-21 20:35:48 -08007208 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7209 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210
7211 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7212 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7213 if (omxhdr == NULL ||
7214 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
7215 {
7216 omxhdr = NULL;
7217 vdec_msg->status_code = VDEC_S_EFATAL;
7218 }
Praneeth Paladuguaf669ca2013-06-11 16:09:26 -07007219 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED)
7220 {
7221 DEBUG_PRINT_HIGH("Unsupported input");
7222 omx->omx_report_error ();
7223 }
7224 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT)
7225 {
7226 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7227 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007228 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7229 OMX_COMPONENT_GENERATE_EBD);
7230 break;
7231 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7232 int64_t *timestamp;
7233 timestamp = (int64_t *) malloc(sizeof(int64_t));
7234 if (timestamp) {
7235 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7236 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7237 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
7238 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
7239 vdec_msg->msgdata.output_frame.time_stamp);
7240 }
7241 break;
7242 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7243 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7244
7245 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7246 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
7247 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
7248 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
7249 vdec_msg->msgdata.output_frame.pic_type);
7250
7251 if (omxhdr && omxhdr->pOutputPortPrivate &&
7252 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
7253 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
7254 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
7255 {
7256 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
7257 {
7258 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7259 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Vinay Kalia1c3c3142013-06-26 17:48:37 -07007260 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7261 omxhdr->nFlags = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007262
7263 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
7264 {
7265 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7266 //rc = -1;
7267 }
Praneeth Paladuguba248592013-06-04 23:08:11 -07007268 if (omxhdr->nFilledLen)
7269 {
7270 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7271 }
7272 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
7273 {
7274 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7275 }
7276 else
7277 {
7278 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7279 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08007280 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
7281 {
7282 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7283 }
Praneeth Paladugufc7dc592013-04-29 12:25:23 -07007284 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
7285 {
7286 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7287 }
Praneeth Paladugua63cfa62013-06-28 11:29:49 -07007288 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7289 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
7290 !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS))
7291 {
7292 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7293 OMX_COMPONENT_GENERATE_FTB);
7294 break;
7295 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07007296 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT)
7297 {
7298 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7299 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007300 vdec_msg->msgdata.output_frame.bufferaddr =
7301 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007302 int format_notably_changed = 0;
7303 if (omxhdr->nFilledLen &&
7304 (omxhdr->nFilledLen != omx->prev_n_filled_len))
7305 {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007306 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7307 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7308 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
7309 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7310 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7311 format_notably_changed = 1;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007312 }
7313 }
Shalaj Jain286b0062013-02-21 20:35:48 -08007314 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7315 vdec_msg->msgdata.output_frame.framesize.left)
7316 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08007317 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7318 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
Vinay Kalia0321dc12013-04-08 20:45:54 -07007319 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7320 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7321 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7322 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7323 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
7324 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
7325 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kaliafa7cc352013-04-03 17:02:37 -07007326 }
Vinay Kalia0321dc12013-04-08 20:45:54 -07007327 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
7328 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
7329 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007330 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7331 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7332 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7333 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
Vinay Kaliab9e98102013-04-02 19:31:43 -07007334 format_notably_changed = 1;
Vinay Kalia592e4b42012-12-19 15:55:47 -08007335 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007336 if (format_notably_changed) {
7337 if(omx->is_video_session_supported()) {
7338 omx->post_event (NULL, vdec_msg->status_code,
7339 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7340 } else {
Eric (Quicef17df02013-05-15 15:14:46 -07007341 if (!omx->client_buffers.update_buffer_req()) {
7342 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7343 }
Vinay Kaliab9e98102013-04-02 19:31:43 -07007344 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7345 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7346 }
7347 }
7348 if (omxhdr->nFilledLen)
7349 omx->prev_n_filled_len = omxhdr->nFilledLen;
7350
Shalaj Jain273b3e02012-06-22 19:08:03 -07007351 output_respbuf = (struct vdec_output_frameinfo *)\
7352 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007353 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7354 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08007355 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
7356 {
7357 output_respbuf->pic_type = PICTURE_TYPE_I;
7358 }
7359 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
7360 {
7361 output_respbuf->pic_type = PICTURE_TYPE_P;
7362 }
7363 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7364 output_respbuf->pic_type = PICTURE_TYPE_B;
7365 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007366
7367 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08007368 memcpy ( omxhdr->pBuffer, (void *)
7369 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7370 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7371 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007372 }
7373 else
7374 omxhdr->nFilledLen = 0;
7375 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7376 OMX_COMPONENT_GENERATE_FBD);
7377 }
7378 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007379 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007380 OMX_COMPONENT_GENERATE_EOS_DONE);
7381 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007382 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007383 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7384 break;
7385 case VDEC_MSG_EVT_CONFIG_CHANGED:
7386 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007387 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7388 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007389 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 default:
7391 break;
7392 }
7393 return rc;
7394}
7395
7396OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7397 OMX_HANDLETYPE hComp,
7398 OMX_BUFFERHEADERTYPE *buffer
7399 )
7400{
7401 unsigned address,p2,id;
7402 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7403
7404 if (buffer == NULL)
7405 {
7406 return OMX_ErrorBadParameter;
7407 }
7408 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007409 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7410 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007411
7412 /* return zero length and not an EOS buffer */
7413 /* return buffer if input flush in progress */
7414 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7415 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7416 {
7417 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7418 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7419 return OMX_ErrorNone;
7420 }
7421
7422 if (psource_frame == NULL)
7423 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007424 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007425 psource_frame = buffer;
7426 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7427 push_input_buffer (hComp);
7428 }
7429 else
7430 {
7431 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007432 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7433 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007434 {
7435 return OMX_ErrorBadParameter;
7436 }
7437 }
7438
7439
7440 return OMX_ErrorNone;
7441}
7442
7443OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7444{
7445 unsigned address,p2,id;
7446 OMX_ERRORTYPE ret = OMX_ErrorNone;
7447
7448 if (pdest_frame == NULL || psource_frame == NULL)
7449 {
7450 /*Check if we have a destination buffer*/
7451 if (pdest_frame == NULL)
7452 {
7453 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7454 if (m_input_free_q.m_size)
7455 {
7456 m_input_free_q.pop_entry(&address,&p2,&id);
7457 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7458 pdest_frame->nFilledLen = 0;
7459 pdest_frame->nTimeStamp = LLONG_MAX;
7460 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7461 }
7462 }
7463
7464 /*Check if we have a destination buffer*/
7465 if (psource_frame == NULL)
7466 {
7467 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7468 if (m_input_pending_q.m_size)
7469 {
7470 m_input_pending_q.pop_entry(&address,&p2,&id);
7471 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007472 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007473 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007474 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007475 psource_frame->nFlags,psource_frame->nFilledLen);
7476
7477 }
7478 }
7479
7480 }
7481
7482 while ((pdest_frame != NULL) && (psource_frame != NULL))
7483 {
7484 switch (codec_type_parse)
7485 {
7486 case CODEC_TYPE_MPEG4:
7487 case CODEC_TYPE_H263:
7488 case CODEC_TYPE_MPEG2:
7489 ret = push_input_sc_codec(hComp);
7490 break;
7491 case CODEC_TYPE_H264:
7492 ret = push_input_h264(hComp);
7493 break;
7494 case CODEC_TYPE_VC1:
7495 ret = push_input_vc1(hComp);
7496 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007497 default:
7498 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007499 }
7500 if (ret != OMX_ErrorNone)
7501 {
7502 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7503 omx_report_error ();
7504 break;
7505 }
7506 }
7507
7508 return ret;
7509}
7510
7511OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7512{
7513 OMX_U32 partial_frame = 1;
7514 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007515 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007516
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007517 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518 psource_frame,psource_frame->nTimeStamp);
7519 if (m_frame_parser.parse_sc_frame(psource_frame,
7520 pdest_frame,&partial_frame) == -1)
7521 {
7522 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7523 return OMX_ErrorBadParameter;
7524 }
7525
7526 if (partial_frame == 0)
7527 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007528 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007529 pdest_frame->nFilledLen,psource_frame,frame_count);
7530
7531
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007532 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007533 /*First Parsed buffer will have only header Hence skip*/
7534 if (frame_count == 0)
7535 {
7536 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7537
7538 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7539 codec_type_parse == CODEC_TYPE_DIVX) {
7540 mp4StreamType psBits;
7541 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7542 psBits.numBytes = pdest_frame->nFilledLen;
7543 mp4_headerparser.parseHeader(&psBits);
7544 }
7545
7546 frame_count++;
7547 }
7548 else
7549 {
7550 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7551 if(pdest_frame->nFilledLen)
7552 {
7553 /*Push the frame to the Decoder*/
7554 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7555 {
7556 return OMX_ErrorBadParameter;
7557 }
7558 frame_count++;
7559 pdest_frame = NULL;
7560
7561 if (m_input_free_q.m_size)
7562 {
7563 m_input_free_q.pop_entry(&address,&p2,&id);
7564 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7565 pdest_frame->nFilledLen = 0;
7566 }
7567 }
7568 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7569 {
7570 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007571 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7572 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007573 pdest_frame = NULL;
7574 }
7575 }
7576 }
7577 else
7578 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007579 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007580 /*Check if Destination Buffer is full*/
7581 if (pdest_frame->nAllocLen ==
7582 pdest_frame->nFilledLen + pdest_frame->nOffset)
7583 {
7584 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7585 return OMX_ErrorStreamCorrupt;
7586 }
7587 }
7588
7589 if (psource_frame->nFilledLen == 0)
7590 {
7591 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7592 {
7593 if (pdest_frame)
7594 {
7595 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007596 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007597 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007598 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007599 pdest_frame->nFilledLen,frame_count++);
7600 /*Push the frame to the Decoder*/
7601 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7602 {
7603 return OMX_ErrorBadParameter;
7604 }
7605 frame_count++;
7606 pdest_frame = NULL;
7607 }
7608 else
7609 {
7610 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7611 generate_ebd = OMX_FALSE;
7612 }
7613 }
7614 if(generate_ebd)
7615 {
7616 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7617 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7618 psource_frame = NULL;
7619
7620 if (m_input_pending_q.m_size)
7621 {
7622 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7623 m_input_pending_q.pop_entry(&address,&p2,&id);
7624 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007625 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007626 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007627 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007628 psource_frame->nFlags,psource_frame->nFilledLen);
7629 }
7630 }
7631 }
7632 return OMX_ErrorNone;
7633}
7634
7635OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7636{
7637 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007638 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007639 OMX_BOOL isNewFrame = OMX_FALSE;
7640 OMX_BOOL generate_ebd = OMX_TRUE;
7641
7642 if (h264_scratch.pBuffer == NULL)
7643 {
7644 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7645 return OMX_ErrorBadParameter;
7646 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007647 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007648 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007649 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007650 if (h264_scratch.nFilledLen && look_ahead_nal)
7651 {
7652 look_ahead_nal = false;
7653 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7654 h264_scratch.nFilledLen)
7655 {
7656 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7657 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7658 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7659 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7660 h264_scratch.nFilledLen = 0;
7661 }
7662 else
7663 {
7664 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7665 return OMX_ErrorBadParameter;
7666 }
7667 }
7668 if (nal_length == 0)
7669 {
7670 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7671 if (m_frame_parser.parse_sc_frame(psource_frame,
7672 &h264_scratch,&partial_frame) == -1)
7673 {
7674 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7675 return OMX_ErrorBadParameter;
7676 }
7677 }
7678 else
7679 {
7680 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7681 if (m_frame_parser.parse_h264_nallength(psource_frame,
7682 &h264_scratch,&partial_frame) == -1)
7683 {
7684 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7685 return OMX_ErrorBadParameter;
7686 }
7687 }
7688
7689 if (partial_frame == 0)
7690 {
7691 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7692 {
7693 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7694 nal_count++;
7695 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7696 h264_scratch.nFlags = psource_frame->nFlags;
7697 }
7698 else
7699 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007700 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007701 if(h264_scratch.nFilledLen)
7702 {
7703 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7704 NALU_TYPE_SPS);
7705#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7706 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7707 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7708 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7709 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7710 // If timeinfo is present frame info from SEI is already processed
7711 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7712 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7713#endif
7714 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7715 nal_count++;
7716 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7717 pdest_frame->nTimeStamp = h264_last_au_ts;
7718 pdest_frame->nFlags = h264_last_au_flags;
7719#ifdef PANSCAN_HDLR
7720 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7721 h264_parser->update_panscan_data(h264_last_au_ts);
7722#endif
7723 }
7724 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7725 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7726 h264_last_au_ts = h264_scratch.nTimeStamp;
7727 h264_last_au_flags = h264_scratch.nFlags;
7728#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7729 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7730 {
7731 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7732 if (!VALID_TS(h264_last_au_ts))
7733 h264_last_au_ts = ts_in_sei;
7734 }
7735#endif
7736 } else
7737 h264_last_au_ts = LLONG_MAX;
7738 }
7739
7740 if (!isNewFrame)
7741 {
7742 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7743 h264_scratch.nFilledLen)
7744 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007745 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007746 h264_scratch.nFilledLen);
7747 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7748 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7749 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7750 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7751 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7752 h264_scratch.nFilledLen = 0;
7753 }
7754 else
7755 {
7756 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7757 return OMX_ErrorBadParameter;
7758 }
7759 }
7760 else
7761 {
7762 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007763 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007764 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007765 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007766 pdest_frame->nFilledLen,frame_count++);
7767
7768 if (pdest_frame->nFilledLen == 0)
7769 {
7770 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7771 look_ahead_nal = false;
7772 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7773 h264_scratch.nFilledLen)
7774 {
7775 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7776 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7777 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7778 h264_scratch.nFilledLen = 0;
7779 }
7780 else
7781 {
7782 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7783 return OMX_ErrorBadParameter;
7784 }
7785 }
7786 else
7787 {
7788 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7789 {
7790 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7791 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7792 }
7793 /*Push the frame to the Decoder*/
7794 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7795 {
7796 return OMX_ErrorBadParameter;
7797 }
7798 //frame_count++;
7799 pdest_frame = NULL;
7800 if (m_input_free_q.m_size)
7801 {
7802 m_input_free_q.pop_entry(&address,&p2,&id);
7803 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7804 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7805 pdest_frame->nFilledLen = 0;
7806 pdest_frame->nFlags = 0;
7807 pdest_frame->nTimeStamp = LLONG_MAX;
7808 }
7809 }
7810 }
7811 }
7812 }
7813 else
7814 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007815 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007816 /*Check if Destination Buffer is full*/
7817 if (h264_scratch.nAllocLen ==
7818 h264_scratch.nFilledLen + h264_scratch.nOffset)
7819 {
7820 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7821 return OMX_ErrorStreamCorrupt;
7822 }
7823 }
7824
7825 if (!psource_frame->nFilledLen)
7826 {
7827 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7828
7829 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7830 {
7831 if (pdest_frame)
7832 {
7833 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7834 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7835 h264_scratch.nFilledLen)
7836 {
7837 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7838 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7839 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7840 h264_scratch.nFilledLen = 0;
7841 }
7842 else
7843 {
7844 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7845 return OMX_ErrorBadParameter;
7846 }
7847 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7848 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7849
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007850 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007851 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7852 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7853#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7854 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7855 {
7856 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7857 if (!VALID_TS(pdest_frame->nTimeStamp))
7858 pdest_frame->nTimeStamp = ts_in_sei;
7859 }
7860#endif
7861 /*Push the frame to the Decoder*/
7862 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7863 {
7864 return OMX_ErrorBadParameter;
7865 }
7866 frame_count++;
7867 pdest_frame = NULL;
7868 }
7869 else
7870 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007871 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007872 pdest_frame,h264_scratch.nFilledLen);
7873 generate_ebd = OMX_FALSE;
7874 }
7875 }
7876 }
7877 if(generate_ebd && !psource_frame->nFilledLen)
7878 {
7879 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7880 psource_frame = NULL;
7881 if (m_input_pending_q.m_size)
7882 {
7883 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7884 m_input_pending_q.pop_entry(&address,&p2,&id);
7885 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007886 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007887 psource_frame->nFlags,psource_frame->nFilledLen);
7888 }
7889 }
7890 return OMX_ErrorNone;
7891}
7892
7893OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7894{
7895 OMX_U8 *buf, *pdest;
7896 OMX_U32 partial_frame = 1;
7897 OMX_U32 buf_len, dest_len;
7898
7899 if(first_frame == 0)
7900 {
7901 first_frame = 1;
7902 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7903 if(!m_vendor_config.pData)
7904 {
7905 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7906 buf = psource_frame->pBuffer;
7907 buf_len = psource_frame->nFilledLen;
7908
7909 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7910 VC1_SP_MP_START_CODE)
7911 {
7912 m_vc1_profile = VC1_SP_MP_RCV;
7913 }
7914 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7915 {
7916 m_vc1_profile = VC1_AP;
7917 }
7918 else
7919 {
7920 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7921 return OMX_ErrorStreamCorrupt;
7922 }
7923 }
7924 else
7925 {
7926 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7927 pdest_frame->nOffset;
7928 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7929 pdest_frame->nOffset);
7930
7931 if(dest_len < m_vendor_config.nDataSize)
7932 {
7933 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7934 return OMX_ErrorBadParameter;
7935 }
7936 else
7937 {
7938 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7939 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7940 }
7941 }
7942 }
7943
7944 switch(m_vc1_profile)
7945 {
7946 case VC1_AP:
7947 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7948 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7949 {
7950 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7951 return OMX_ErrorBadParameter;
7952 }
7953 break;
7954
7955 case VC1_SP_MP_RCV:
7956 default:
7957 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7958 return OMX_ErrorBadParameter;
7959 }
7960 return OMX_ErrorNone;
7961}
7962
David Ng38e2d232013-03-15 20:05:58 -07007963#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007964bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7965 OMX_U32 alignment)
7966{
7967 struct pmem_allocation allocation;
7968 allocation.size = buffer_size;
7969 allocation.align = clip2(alignment);
7970 if (allocation.align < 4096)
7971 {
7972 allocation.align = 4096;
7973 }
7974 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7975 {
7976 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7977 allocation.align, allocation.size);
7978 return false;
7979 }
7980 return true;
7981}
David Ng38e2d232013-03-15 20:05:58 -07007982#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007983#ifdef USE_ION
7984int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7985 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7986 struct ion_fd_data *fd_data, int flag)
7987{
7988 int fd = -EINVAL;
7989 int rc = -EINVAL;
7990 int ion_dev_flag;
7991 struct vdec_ion ion_buf_info;
7992 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7993 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7994 return -EINVAL;
7995 }
Arun Menon737de532012-09-14 14:48:18 -07007996 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007997 fd = open (MEM_DEVICE, ion_dev_flag);
7998 if (fd < 0) {
7999 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
8000 return fd;
8001 }
Arun Menon737de532012-09-14 14:48:18 -07008002 alloc_data->flags = 0;
8003 if(!secure_mode && (flag & ION_FLAG_CACHED))
8004 {
8005 alloc_data->flags |= ION_FLAG_CACHED;
8006 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008007 alloc_data->len = buffer_size;
8008 alloc_data->align = clip2(alignment);
8009 if (alloc_data->align < 4096)
8010 {
8011 alloc_data->align = 4096;
8012 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07008013 if ((secure_mode) && (flag & ION_SECURE))
8014 alloc_data->flags |= ION_SECURE;
8015
Shalaj Jain5af07fb2013-03-07 11:38:41 -08008016 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
8017 if (secure_mode)
8018 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008019 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
8020 if (rc || !alloc_data->handle) {
8021 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
8022 alloc_data->handle = NULL;
8023 close(fd);
8024 fd = -ENOMEM;
8025 return fd;
8026 }
8027 fd_data->handle = alloc_data->handle;
8028 rc = ioctl(fd,ION_IOC_MAP,fd_data);
8029 if (rc) {
8030 DEBUG_PRINT_ERROR("\n ION MAP failed ");
8031 ion_buf_info.ion_alloc_data = *alloc_data;
8032 ion_buf_info.ion_device_fd = fd;
8033 ion_buf_info.fd_ion_data = *fd_data;
8034 free_ion_memory(&ion_buf_info);
8035 fd_data->fd =-1;
8036 close(fd);
8037 fd = -ENOMEM;
8038 }
8039
8040 return fd;
8041}
8042
8043void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
8044
8045 if(!buf_ion_info) {
8046 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
8047 return;
8048 }
8049 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
8050 &buf_ion_info->ion_alloc_data.handle)) {
8051 DEBUG_PRINT_ERROR("\n ION: free failed" );
8052 }
8053 close(buf_ion_info->ion_device_fd);
8054 buf_ion_info->ion_device_fd = -1;
8055 buf_ion_info->ion_alloc_data.handle = NULL;
8056 buf_ion_info->fd_ion_data.fd = -1;
8057}
8058#endif
8059void omx_vdec::free_output_buffer_header()
8060{
8061 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
8062 output_use_buffer = false;
8063 ouput_egl_buffers = false;
8064
8065 if (m_out_mem_ptr)
8066 {
8067 free (m_out_mem_ptr);
8068 m_out_mem_ptr = NULL;
8069 }
8070
8071 if(m_platform_list)
8072 {
8073 free(m_platform_list);
8074 m_platform_list = NULL;
8075 }
8076
8077 if (drv_ctx.ptr_respbuffer)
8078 {
8079 free (drv_ctx.ptr_respbuffer);
8080 drv_ctx.ptr_respbuffer = NULL;
8081 }
8082 if (drv_ctx.ptr_outputbuffer)
8083 {
8084 free (drv_ctx.ptr_outputbuffer);
8085 drv_ctx.ptr_outputbuffer = NULL;
8086 }
8087#ifdef USE_ION
8088 if (drv_ctx.op_buf_ion_info) {
8089 DEBUG_PRINT_LOW("\n Free o/p ion context");
8090 free(drv_ctx.op_buf_ion_info);
8091 drv_ctx.op_buf_ion_info = NULL;
8092 }
8093#endif
8094}
8095
8096void omx_vdec::free_input_buffer_header()
8097{
8098 input_use_buffer = false;
8099 if (arbitrary_bytes)
8100 {
8101 if (m_frame_parser.mutils)
8102 {
8103 DEBUG_PRINT_LOW("\n Free utils parser");
8104 delete (m_frame_parser.mutils);
8105 m_frame_parser.mutils = NULL;
8106 }
8107
8108 if (m_inp_heap_ptr)
8109 {
8110 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
8111 free (m_inp_heap_ptr);
8112 m_inp_heap_ptr = NULL;
8113 }
8114
8115 if (m_phdr_pmem_ptr)
8116 {
8117 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
8118 free (m_phdr_pmem_ptr);
8119 m_phdr_pmem_ptr = NULL;
8120 }
8121 }
8122 if (m_inp_mem_ptr)
8123 {
8124 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
8125 free (m_inp_mem_ptr);
8126 m_inp_mem_ptr = NULL;
8127 }
8128 if (drv_ctx.ptr_inputbuffer)
8129 {
8130 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
8131 free (drv_ctx.ptr_inputbuffer);
8132 drv_ctx.ptr_inputbuffer = NULL;
8133 }
8134#ifdef USE_ION
8135 if (drv_ctx.ip_buf_ion_info) {
8136 DEBUG_PRINT_LOW("\n Free ion context");
8137 free(drv_ctx.ip_buf_ion_info);
8138 drv_ctx.ip_buf_ion_info = NULL;
8139 }
8140#endif
8141}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008142
8143int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008144{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008145 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008146 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008147 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008148
8149 if (port == OMX_CORE_INPUT_PORT_INDEX) {
8150 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8151 v4l2_port = OUTPUT_PORT;
8152 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
8153 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8154 v4l2_port = CAPTURE_PORT;
8155 } else if (port == OMX_ALL) {
8156 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
8157 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
8158
8159 if (!rc_input)
8160 return rc_input;
8161 else
8162 return rc_output;
8163 }
8164
8165 if (!streaming[v4l2_port]) {
8166 // already streamed off, warn and move on
8167 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
8168 " which is already streamed off", v4l2_port);
8169 return 0;
8170 }
8171
8172 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
8173
Shalaj Jain273b3e02012-06-22 19:08:03 -07008174 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
8175 if (rc) {
8176 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008177 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008178 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008179 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008180 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008181
8182 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008183}
8184
8185OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
8186{
8187 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8188 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008189 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008190 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008191 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008192 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8193 buffer_prop->actualcount, buffer_prop->buffer_size);
8194 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07008195 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008196 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8197 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8198 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8199 fmt.fmt.pix_mp.pixelformat = output_capability;
8200 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
8201 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8202 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8203 fmt.fmt.pix_mp.pixelformat = capture_capability;
8204 }else {eRet = OMX_ErrorBadParameter;}
8205 if(eRet==OMX_ErrorNone){
8206 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8207 }
8208 if(ret)
8209 {
8210 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8211 /*TODO: How to handle this case */
8212 eRet = OMX_ErrorInsufficientResources;
8213 return eRet;
8214 }
8215 else
8216 {
8217 buffer_prop->actualcount = bufreq.count;
8218 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07008219 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008220 }
8221 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8222 buffer_prop->actualcount, buffer_prop->buffer_size);
8223
8224 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8225 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8226
8227 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8228
Vinay Kalia21649b32013-03-18 17:28:07 -07008229 update_resolution(fmt.fmt.pix_mp.width,
8230 fmt.fmt.pix_mp.height,
8231 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8232 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
Vinay Kalia5713bb32013-01-16 18:39:59 -08008233 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8234 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07008235 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008236
8237 if(ret)
8238 {
8239 /*TODO: How to handle this case */
8240 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8241 eRet = OMX_ErrorInsufficientResources;
8242 }
8243 else
8244 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008245 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08008246
8247 eRet = is_video_session_supported();
8248 if (eRet)
8249 return eRet;
8250
Shalaj Jain273b3e02012-06-22 19:08:03 -07008251 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8252 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008253 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8254 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8255 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8256 } else if (extra_idx >= VIDEO_MAX_PLANES) {
8257 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
8258 return OMX_ErrorBadParameter;
8259 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008260 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8261 {
8262 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008263 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008264 }
8265 if (client_extradata & OMX_INTERLACE_EXTRADATA)
8266 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008267 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008268 }
8269 if (client_extradata & OMX_PORTDEF_EXTRADATA)
8270 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008271 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
8272 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
8273 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008274 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008275 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008276 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008277 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07008278 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
8279 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008280 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
8281 drv_ctx.extradata_info.count = buffer_prop->actualcount;
8282 drv_ctx.extradata_info.buffer_size = extra_data_size;
8283 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008284 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8285 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008286 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008287 if (in_reconfig) // BufReq will be set to driver when port is disabled
8288 buffer_prop->buffer_size = buf_size;
8289 else if (buf_size != buffer_prop->buffer_size)
8290 {
8291 buffer_prop->buffer_size = buf_size;
8292 eRet = set_buffer_req(buffer_prop);
8293 }
8294 }
8295 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8296 buffer_prop->actualcount, buffer_prop->buffer_size);
8297 return eRet;
8298}
8299
8300OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8301{
8302 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8303 unsigned buf_size = 0;
8304 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008305 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008306 int ret;
8307 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8308 buffer_prop->actualcount, buffer_prop->buffer_size);
8309 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8310 if (buf_size != buffer_prop->buffer_size)
8311 {
8312 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8313 buffer_prop->buffer_size, buf_size);
8314 eRet = OMX_ErrorBadParameter;
8315 }
8316 else
8317 {
8318 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8319 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008320
8321 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
8322 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8323 fmt.fmt.pix_mp.pixelformat = output_capability;
8324 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8325 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8326 fmt.fmt.pix_mp.pixelformat = capture_capability;
8327 } else {eRet = OMX_ErrorBadParameter;}
8328
8329 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8330 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008331 {
8332 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008333 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008334 eRet = OMX_ErrorInsufficientResources;
8335 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008336
8337 bufreq.memory = V4L2_MEMORY_USERPTR;
8338 bufreq.count = buffer_prop->actualcount;
8339 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8340 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8341 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8342 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8343 } else {eRet = OMX_ErrorBadParameter;}
8344
8345 if (eRet==OMX_ErrorNone) {
8346 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8347 }
8348
8349 if (ret)
8350 {
8351 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8352 /*TODO: How to handle this case */
8353 eRet = OMX_ErrorInsufficientResources;
8354 } else if (bufreq.count < buffer_prop->actualcount) {
8355 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8356 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8357 buffer_prop->actualcount, bufreq.count);
8358 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008359 } else {
8360 if (!client_buffers.update_buffer_req()) {
8361 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8362 eRet = OMX_ErrorInsufficientResources;
8363 }
8364 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008365 }
8366 return eRet;
8367}
8368
Shalaj Jain273b3e02012-06-22 19:08:03 -07008369OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8370{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008371 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008372 return eRet;
8373}
8374
8375OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8376{
8377 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8378 if (!portDefn)
8379 {
8380 return OMX_ErrorBadParameter;
8381 }
8382 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8383 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8384 portDefn->nSize = sizeof(portDefn);
8385 portDefn->eDomain = OMX_PortDomainVideo;
8386 if (drv_ctx.frame_rate.fps_denominator > 0)
8387 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8388 drv_ctx.frame_rate.fps_denominator;
8389 else {
8390 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8391 return OMX_ErrorBadParameter;
8392 }
8393 if (0 == portDefn->nPortIndex)
8394 {
8395 portDefn->eDir = OMX_DirInput;
8396 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8397 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8398 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8399 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8400 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8401 portDefn->bEnabled = m_inp_bEnabled;
8402 portDefn->bPopulated = m_inp_bPopulated;
8403 }
8404 else if (1 == portDefn->nPortIndex)
8405 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008406 unsigned int buf_size = 0;
8407 if (!client_buffers.update_buffer_req()) {
8408 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8409 return OMX_ErrorHardware;
8410 }
8411 if (!client_buffers.get_buffer_req(buf_size)) {
8412 DEBUG_PRINT_ERROR("\n update buffer requirements");
8413 return OMX_ErrorHardware;
8414 }
8415 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008416 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008417 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8418 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008419 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8420 portDefn->bEnabled = m_out_bEnabled;
8421 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008422 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8423 DEBUG_PRINT_ERROR("\n Error in getting color format");
8424 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008425 }
8426 }
8427 else
8428 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008429 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008430 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8431 (int)portDefn->nPortIndex);
8432 eRet = OMX_ErrorBadPortIndex;
8433 }
8434 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8435 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8436 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8437 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008438 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8439 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008440 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008441 portDefn->format.video.nStride,
8442 portDefn->format.video.nSliceHeight);
8443 return eRet;
8444
8445}
8446
8447OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8448{
8449 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8450 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8451 unsigned i= 0;
8452
8453 if(!m_out_mem_ptr) {
8454 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8455 int nBufHdrSize = 0;
8456 int nPlatformEntrySize = 0;
8457 int nPlatformListSize = 0;
8458 int nPMEMInfoSize = 0;
8459 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8460 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8461 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8462
8463 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8464 drv_ctx.op_buf.actualcount);
8465 nBufHdrSize = drv_ctx.op_buf.actualcount *
8466 sizeof(OMX_BUFFERHEADERTYPE);
8467
8468 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8469 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8470 nPlatformListSize = drv_ctx.op_buf.actualcount *
8471 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8472 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8473 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8474
8475 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8476 sizeof(OMX_BUFFERHEADERTYPE),
8477 nPMEMInfoSize,
8478 nPlatformListSize);
8479 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8480 m_out_bm_count);
8481 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8482 // Alloc mem for platform specific info
8483 char *pPtr=NULL;
8484 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8485 nPMEMInfoSize,1);
8486 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8487 calloc (sizeof(struct vdec_bufferpayload),
8488 drv_ctx.op_buf.actualcount);
8489 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8490 calloc (sizeof (struct vdec_output_frameinfo),
8491 drv_ctx.op_buf.actualcount);
8492#ifdef USE_ION
8493 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8494 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8495#endif
8496
8497 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8498 && drv_ctx.ptr_respbuffer)
8499 {
8500 bufHdr = m_out_mem_ptr;
8501 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8502 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8503 (((char *) m_platform_list) + nPlatformListSize);
8504 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8505 (((char *) m_platform_entry) + nPlatformEntrySize);
8506 pPlatformList = m_platform_list;
8507 pPlatformEntry = m_platform_entry;
8508 pPMEMInfo = m_pmem_info;
8509
8510 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8511
8512 // Settting the entire storage nicely
8513 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8514 m_out_mem_ptr,pPlatformEntry);
8515 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8516 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8517 {
8518 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8519 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8520 // Set the values when we determine the right HxW param
8521 bufHdr->nAllocLen = 0;
8522 bufHdr->nFilledLen = 0;
8523 bufHdr->pAppPrivate = NULL;
8524 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8525 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8526 pPlatformEntry->entry = pPMEMInfo;
8527 // Initialize the Platform List
8528 pPlatformList->nEntries = 1;
8529 pPlatformList->entryList = pPlatformEntry;
8530 // Keep pBuffer NULL till vdec is opened
8531 bufHdr->pBuffer = NULL;
8532 pPMEMInfo->offset = 0;
8533 pPMEMInfo->pmem_fd = 0;
8534 bufHdr->pPlatformPrivate = pPlatformList;
8535 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8536#ifdef USE_ION
8537 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8538#endif
8539 /*Create a mapping between buffers*/
8540 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8541 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8542 &drv_ctx.ptr_outputbuffer[i];
8543 // Move the buffer and buffer header pointers
8544 bufHdr++;
8545 pPMEMInfo++;
8546 pPlatformEntry++;
8547 pPlatformList++;
8548 }
8549 }
8550 else
8551 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008552 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008553 m_out_mem_ptr, pPtr);
8554 if(m_out_mem_ptr)
8555 {
8556 free(m_out_mem_ptr);
8557 m_out_mem_ptr = NULL;
8558 }
8559 if(pPtr)
8560 {
8561 free(pPtr);
8562 pPtr = NULL;
8563 }
8564 if(drv_ctx.ptr_outputbuffer)
8565 {
8566 free(drv_ctx.ptr_outputbuffer);
8567 drv_ctx.ptr_outputbuffer = NULL;
8568 }
8569 if(drv_ctx.ptr_respbuffer)
8570 {
8571 free(drv_ctx.ptr_respbuffer);
8572 drv_ctx.ptr_respbuffer = NULL;
8573 }
8574#ifdef USE_ION
8575 if (drv_ctx.op_buf_ion_info) {
8576 DEBUG_PRINT_LOW("\n Free o/p ion context");
8577 free(drv_ctx.op_buf_ion_info);
8578 drv_ctx.op_buf_ion_info = NULL;
8579 }
8580#endif
8581 eRet = OMX_ErrorInsufficientResources;
8582 }
8583 } else {
8584 eRet = OMX_ErrorInsufficientResources;
8585 }
8586 return eRet;
8587}
8588
8589void omx_vdec::complete_pending_buffer_done_cbs()
8590{
8591 unsigned p1;
8592 unsigned p2;
8593 unsigned ident;
8594 omx_cmd_queue tmp_q, pending_bd_q;
8595 pthread_mutex_lock(&m_lock);
8596 // pop all pending GENERATE FDB from ftb queue
8597 while (m_ftb_q.m_size)
8598 {
8599 m_ftb_q.pop_entry(&p1,&p2,&ident);
8600 if(ident == OMX_COMPONENT_GENERATE_FBD)
8601 {
8602 pending_bd_q.insert_entry(p1,p2,ident);
8603 }
8604 else
8605 {
8606 tmp_q.insert_entry(p1,p2,ident);
8607 }
8608 }
8609 //return all non GENERATE FDB to ftb queue
8610 while(tmp_q.m_size)
8611 {
8612 tmp_q.pop_entry(&p1,&p2,&ident);
8613 m_ftb_q.insert_entry(p1,p2,ident);
8614 }
8615 // pop all pending GENERATE EDB from etb queue
8616 while (m_etb_q.m_size)
8617 {
8618 m_etb_q.pop_entry(&p1,&p2,&ident);
8619 if(ident == OMX_COMPONENT_GENERATE_EBD)
8620 {
8621 pending_bd_q.insert_entry(p1,p2,ident);
8622 }
8623 else
8624 {
8625 tmp_q.insert_entry(p1,p2,ident);
8626 }
8627 }
8628 //return all non GENERATE FDB to etb queue
8629 while(tmp_q.m_size)
8630 {
8631 tmp_q.pop_entry(&p1,&p2,&ident);
8632 m_etb_q.insert_entry(p1,p2,ident);
8633 }
8634 pthread_mutex_unlock(&m_lock);
8635 // process all pending buffer dones
8636 while(pending_bd_q.m_size)
8637 {
8638 pending_bd_q.pop_entry(&p1,&p2,&ident);
8639 switch(ident)
8640 {
8641 case OMX_COMPONENT_GENERATE_EBD:
8642 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8643 {
8644 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8645 omx_report_error ();
8646 }
8647 break;
8648
8649 case OMX_COMPONENT_GENERATE_FBD:
8650 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8651 {
8652 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8653 omx_report_error ();
8654 }
8655 break;
8656 }
8657 }
8658}
8659
8660void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8661{
8662 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008663 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07008664 && llabs(act_timestamp - prev_ts) > 2000)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008665 {
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -07008666 new_frame_interval = client_set_fps ? frm_int :
8667 llabs(act_timestamp - prev_ts);
Rajeshwar Kurapaty27be6e72013-06-19 21:24:02 +05308668 if (new_frame_interval < frm_int || frm_int == 0)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008669 {
8670 frm_int = new_frame_interval;
8671 if(frm_int)
8672 {
8673 drv_ctx.frame_rate.fps_numerator = 1e6;
8674 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008675 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008676 frm_int, drv_ctx.frame_rate.fps_numerator /
8677 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008678
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008679 /* We need to report the difference between this FBD and the previous FBD
8680 * back to the driver for clock scaling purposes. */
8681 struct v4l2_outputparm oparm;
8682 /*XXX: we're providing timing info as seconds per frame rather than frames
8683 * per second.*/
8684 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8685 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
8686
8687 struct v4l2_streamparm sparm;
8688 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8689 sparm.parm.output = oparm;
8690 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm))
8691 {
8692 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8693 performance might be affected");
8694 }
8695
Shalaj Jain273b3e02012-06-22 19:08:03 -07008696 }
8697 }
8698 }
8699 prev_ts = act_timestamp;
8700}
8701
8702void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8703{
8704 if (rst_prev_ts && VALID_TS(act_timestamp))
8705 {
8706 prev_ts = act_timestamp;
8707 rst_prev_ts = false;
8708 }
8709 else if (VALID_TS(prev_ts))
8710 {
8711 bool codec_cond = (drv_ctx.timestamp_adjust)?
8712 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8713 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8714 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8715 if(frm_int > 0 && codec_cond)
8716 {
8717 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8718 act_timestamp = prev_ts + frm_int;
8719 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8720 prev_ts = act_timestamp;
8721 }
8722 else
8723 set_frame_rate(act_timestamp);
8724 }
8725 else if (frm_int > 0) // In this case the frame rate was set along
8726 { // with the port definition, start ts with 0
8727 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8728 rst_prev_ts = true;
8729 }
8730}
8731
8732void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8733{
8734 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8735 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008736 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008737 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008738 OMX_U32 num_MB_in_frame;
8739 OMX_U32 recovery_sei_flags = 1;
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008740 int enable = 0;
8741 OMX_U32 mbaff = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008742 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008743 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008744 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8745 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008746 if (!drv_ctx.extradata_info.uaddr) {
8747 return;
8748 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008749 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008750 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8751 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8752 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008753 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008754 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008755 if (data) {
8756 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008757 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008758 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008759 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008760 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008761 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008762 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008763 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008764 struct msm_vidc_interlace_payload *payload;
8765 payload = (struct msm_vidc_interlace_payload *)data->data;
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008766 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8767 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8768 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8769 else {
8770 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8771 enable = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008772 }
Praneeth Paladuguc8326612013-05-08 10:11:36 -07008773 if(m_enable_android_native_buffers)
8774 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8775 PP_PARAM_INTERLACED, (void*)&enable);
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008776 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8777 append_interlace_extradata(p_extra, payload->format);
8778 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8779 }
8780 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008781 case EXTRADATA_FRAME_RATE:
8782 struct msm_vidc_framerate_payload *frame_rate_payload;
8783 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8784 frame_rate = frame_rate_payload->frame_rate;
8785 break;
8786 case EXTRADATA_TIMESTAMP:
8787 struct msm_vidc_ts_payload *time_stamp_payload;
8788 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008789 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008790 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008791 break;
8792 case EXTRADATA_NUM_CONCEALED_MB:
8793 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8794 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8795 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8796 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8797 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8798 break;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008799 case EXTRADATA_INDEX:
8800 int *etype;
8801 etype = (int *)(data->data);
8802 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008803 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008804 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8805 if (aspect_ratio_payload) {
8806 ((struct vdec_output_frameinfo *)
8807 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8808 ((struct vdec_output_frameinfo *)
8809 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8810 }
8811 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008812 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008813 case EXTRADATA_RECOVERY_POINT_SEI:
8814 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8815 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8816 recovery_sei_flags = recovery_sei_payload->flags;
8817 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
Praneeth Paladugu594e6822013-04-19 10:47:28 -07008818 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8819 DEBUG_PRINT_HIGH("\n");
8820 DEBUG_PRINT_HIGH("***************************************************\n");
8821 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
8822 DEBUG_PRINT_HIGH("***************************************************\n");
8823 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008824 break;
8825 case EXTRADATA_PANSCAN_WINDOW:
8826 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8827 break;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008828 case EXTRADATA_MPEG2_SEQDISP:
8829 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8830 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8831 if (seqdisp_payload) {
8832 m_disp_hor_size = seqdisp_payload->disp_width;
8833 m_disp_vert_size = seqdisp_payload->disp_height;
8834 }
8835 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008836 default:
8837 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008838 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008839 consumed_len += data->nSize;
8840 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008841 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008842 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008843 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008844 append_frame_info_extradata(p_extra,
8845 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008846 panscan_payload,&((struct vdec_output_frameinfo *)
8847 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008848 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008849unrecognized_extradata:
8850 if(!secure_mode && client_extradata)
8851 append_terminator_extradata(p_extra);
8852 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008853}
8854
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008855OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8856 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008857{
8858 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008859 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008860 if(m_state != OMX_StateLoaded)
8861 {
8862 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8863 return OMX_ErrorIncorrectStateOperation;
8864 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008865 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008866 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008867
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008868 if (!is_internal) {
8869 if (enable)
8870 client_extradata |= requested_extradata;
8871 else
8872 client_extradata = client_extradata & ~requested_extradata;
8873 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008874
8875 if (enable) {
8876 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8877 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8878 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8879 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8880 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8881 " Quality of interlaced clips might be impacted.\n");
8882 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008883 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8884 {
8885 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8886 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8887 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8888 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8889 }
8890 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8891 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8892 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8893 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8894 }
8895 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8896 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8897 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8898 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8899 }
8900 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8901 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8902 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8903 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8904 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008905 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8906 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8907 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8908 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8909 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008910 if (output_capability == V4L2_PIX_FMT_MPEG2)
8911 {
8912 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8913 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8914 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8915 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8916 }
8917 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008918 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8919 {
8920 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8921 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8922 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8923 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8924 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008925 }
8926 }
Srinu Gorlefaefbdd2013-07-09 16:20:06 +05308927 ret = get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008928 return ret;
8929}
8930
8931OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8932{
8933 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8934 OMX_U8 *data_ptr = extra->data, data = 0;
8935 while (byte_count < extra->nDataSize)
8936 {
8937 data = *data_ptr;
8938 while (data)
8939 {
8940 num_MB += (data&0x01);
8941 data >>= 1;
8942 }
8943 data_ptr++;
8944 byte_count++;
8945 }
8946 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8947 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8948 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8949}
8950
8951void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8952{
8953 if (!m_debug_extradata)
8954 return;
8955
8956 DEBUG_PRINT_HIGH(
8957 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008958 " Size: %lu \n"
8959 " Version: %lu \n"
8960 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008961 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008962 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008963 extra->nSize, extra->nVersion.nVersion,
8964 extra->nPortIndex, extra->eType, extra->nDataSize);
8965
Shalaj Jain286b0062013-02-21 20:35:48 -08008966 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008967 {
8968 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8969 DEBUG_PRINT_HIGH(
8970 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008971 " Size: %lu \n"
8972 " Version: %lu \n"
8973 " PortIndex: %lu \n"
8974 " Is Interlace Format: %d \n"
8975 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008976 "=========== End of Interlace ===========\n",
8977 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8978 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8979 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008980 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008981 {
8982 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8983
8984 DEBUG_PRINT_HIGH(
8985 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008986 " Picture Type: %d \n"
8987 " Interlace Type: %d \n"
8988 " Pan Scan Total Frame Num: %lu \n"
8989 " Concealed Macro Blocks: %lu \n"
8990 " frame rate: %lu \n"
8991 " Aspect Ratio X: %lu \n"
8992 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008993 fminfo->ePicType,
8994 fminfo->interlaceType,
8995 fminfo->panScan.numWindows,
8996 fminfo->nConcealedMacroblocks,
8997 fminfo->nFrameRate,
8998 fminfo->aspectRatio.aspectRatioX,
8999 fminfo->aspectRatio.aspectRatioY);
9000
Praneeth Paladugu32284302013-02-14 22:53:06 -08009001 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009002 {
9003 DEBUG_PRINT_HIGH(
9004 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08009005 " Pan Scan Frame Num: %lu \n"
9006 " Rectangle x: %ld \n"
9007 " Rectangle y: %ld \n"
9008 " Rectangle dx: %ld \n"
9009 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07009010 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
9011 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
9012 }
9013
9014 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
9015 }
9016 else if (extra->eType == OMX_ExtraDataNone)
9017 {
9018 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
9019 }
9020 else
9021 {
9022 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
9023 }
9024}
9025
9026void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9027 OMX_U32 interlaced_format_type)
9028{
9029 OMX_STREAMINTERLACEFORMAT *interlace_format;
9030 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08009031 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
9032 return;
9033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009034 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9035 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9036 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9037 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9038 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9039 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9040 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9041 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9042 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9043 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07009044 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009045 {
9046 interlace_format->bInterlaceFormat = OMX_FALSE;
9047 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9048 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
9049 }
9050 else
9051 {
9052 interlace_format->bInterlaceFormat = OMX_TRUE;
9053 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9054 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9055 }
9056 print_debug_extradata(extra);
9057}
9058
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009059void omx_vdec::fill_aspect_ratio_info(
9060 struct vdec_aspectratioinfo *aspect_ratio_info,
9061 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
9062{
9063 m_extradata = frame_info;
9064 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9065 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009066 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009067 m_extradata->aspectRatio.aspectRatioY);
9068}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009069
9070void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009071 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009072 struct msm_vidc_panscan_window_payload *panscan_payload,
9073 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009074{
9075 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009076 struct msm_vidc_panscan_window *panscan_window;
9077 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
9078 return;
9079 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009080 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9081 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9082 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9083 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9084 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9085 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9086 switch (picture_type)
9087 {
9088 case PICTURE_TYPE_I:
9089 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9090 break;
9091 case PICTURE_TYPE_P:
9092 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9093 break;
9094 case PICTURE_TYPE_B:
9095 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9096 break;
9097 default:
9098 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9099 }
9100 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9101 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9102 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9103 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9104 else
9105 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009106 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07009107 frame_info->nConcealedMacroblocks = num_conceal_mb;
9108 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009109 frame_info->panScan.numWindows = 0;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009110 if (output_capability == V4L2_PIX_FMT_MPEG2)
9111 {
9112 if (m_disp_hor_size && m_disp_vert_size)
9113 {
9114 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9115 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
9116 }
9117 }
9118
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009119 if(panscan_payload) {
9120 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9121 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08009122 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009123 {
9124 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9125 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9126 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9127 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9128 panscan_window++;
9129 }
9130 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009131 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009132 print_debug_extradata(extra);
9133}
9134
9135void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9136{
9137 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9138 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9139 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9140 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9141 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9142 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9143 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9144 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009145 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
9146 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07009147 portDefn->format.video.nFrameWidth,
9148 portDefn->format.video.nStride,
9149 portDefn->format.video.nSliceHeight);
9150}
9151
9152void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9153{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08009154 if (!client_extradata) {
9155 return;
9156 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009157 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9158 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9159 extra->eType = OMX_ExtraDataNone;
9160 extra->nDataSize = 0;
9161 extra->data[0] = 0;
9162
9163 print_debug_extradata(extra);
9164}
9165
9166OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9167{
9168 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9169 if (index >= drv_ctx.ip_buf.actualcount)
9170 {
9171 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
9172 return OMX_ErrorInsufficientResources;
9173 }
9174 if (m_desc_buffer_ptr == NULL)
9175 {
9176 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9177 calloc( (sizeof(desc_buffer_hdr)),
9178 drv_ctx.ip_buf.actualcount);
9179 if (m_desc_buffer_ptr == NULL)
9180 {
9181 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
9182 return OMX_ErrorInsufficientResources;
9183 }
9184 }
9185
9186 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9187 if (m_desc_buffer_ptr[index].buf_addr == NULL)
9188 {
9189 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
9190 return OMX_ErrorInsufficientResources;
9191 }
9192
9193 return eRet;
9194}
9195
9196void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9197{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009198 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009199 if (m_demux_entries < 8192)
9200 {
9201 m_demux_offsets[m_demux_entries++] = address_offset;
9202 }
9203 return;
9204}
9205
9206void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9207{
9208 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9209 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9210 OMX_U32 index = 0;
9211
9212 m_demux_entries = 0;
9213
9214 while (index < bytes_to_parse)
9215 {
9216 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9217 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9218 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9219 (buf[index+2] == 0x01)) )
9220 {
9221 //Found start code, insert address offset
9222 insert_demux_addr_offset(index);
9223 if (buf[index+2] == 0x01) // 3 byte start code
9224 index += 3;
9225 else //4 byte start code
9226 index += 4;
9227 }
9228 else
9229 index++;
9230 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009231 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009232 return;
9233}
9234
9235OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9236{
9237 //fix this, handle 3 byte start code, vc1 terminator entry
9238 OMX_U8 *p_demux_data = NULL;
9239 OMX_U32 desc_data = 0;
9240 OMX_U32 start_addr = 0;
9241 OMX_U32 nal_size = 0;
9242 OMX_U32 suffix_byte = 0;
9243 OMX_U32 demux_index = 0;
9244 OMX_U32 buffer_index = 0;
9245
9246 if (m_desc_buffer_ptr == NULL)
9247 {
9248 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9249 return OMX_ErrorBadParameter;
9250 }
9251
9252 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9253 if (buffer_index > drv_ctx.ip_buf.actualcount)
9254 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08009255 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009256 return OMX_ErrorBadParameter;
9257 }
9258
9259 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9260
9261 if ( ((OMX_U8*)p_demux_data == NULL) ||
9262 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
9263 {
9264 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9265 return OMX_ErrorBadParameter;
9266 }
9267 else
9268 {
9269 for (; demux_index < m_demux_entries; demux_index++)
9270 {
9271 desc_data = 0;
9272 start_addr = m_demux_offsets[demux_index];
9273 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
9274 {
9275 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9276 }
9277 else
9278 {
9279 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9280 }
9281 if (demux_index < (m_demux_entries - 1))
9282 {
9283 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9284 }
9285 else
9286 {
9287 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9288 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009289 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9290 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07009291 suffix_byte,
9292 nal_size,
9293 demux_index);
9294 desc_data = (start_addr >> 3) << 1;
9295 desc_data |= (start_addr & 7) << 21;
9296 desc_data |= suffix_byte << 24;
9297
9298 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9299 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9300 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9301 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9302
9303 p_demux_data += 16;
9304 }
9305 if (codec_type_parse == CODEC_TYPE_VC1)
9306 {
9307 DEBUG_PRINT_LOW("VC1 terminator entry");
9308 desc_data = 0;
9309 desc_data = 0x82 << 24;
9310 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9311 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9312 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9313 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9314 p_demux_data += 16;
9315 m_demux_entries++;
9316 }
9317 //Add zero word to indicate end of descriptors
9318 memset(p_demux_data, 0, sizeof(OMX_U32));
9319
9320 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07009321 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009322 }
9323 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9324 m_demux_entries = 0;
9325 DEBUG_PRINT_LOW("Demux table complete!");
9326 return OMX_ErrorNone;
9327}
9328
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009329OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009330{
9331 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009332 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07009333 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07009334 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9335 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009336 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009337 delete iDivXDrmDecrypt;
9338 iDivXDrmDecrypt = NULL;
9339 }
9340 }
9341 else {
9342 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009343 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009344 }
9345 return err;
9346}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009347
Vinay Kaliada4f4422013-01-09 10:45:03 -08009348omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9349{
9350 enabled = false;
9351 omx = NULL;
9352 init_members();
9353 ColorFormat = OMX_COLOR_FormatMax;
9354}
9355
9356void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9357{
9358 omx = reinterpret_cast<omx_vdec*>(client);
9359}
9360
9361void omx_vdec::allocate_color_convert_buf::init_members() {
9362 allocated_count = 0;
9363 buffer_size_req = 0;
9364 buffer_alignment_req = 0;
9365 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9366 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9367 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9368 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9369#ifdef USE_ION
9370 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9371#endif
9372 for (int i = 0; i < MAX_COUNT;i++)
9373 pmem_fd[i] = -1;
9374}
9375
9376omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
9377 c2d.destroy();
9378}
9379
9380bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9381{
9382 bool status = true;
9383 unsigned int src_size = 0, destination_size = 0;
9384 OMX_COLOR_FORMATTYPE drv_color_format;
9385 if (!omx){
9386 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9387 return false;
9388 }
9389 if (!enabled){
9390 DEBUG_PRINT_ERROR("\n No color conversion required");
9391 return status;
9392 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009393 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009394 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9395 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9396 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009397 status = false;
9398 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009399 }
9400 c2d.close();
9401 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9402 omx->drv_ctx.video_resolution.frame_width,
9403 NV12_128m,YCbCr420P);
9404 if (status) {
9405 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9406 if (status)
9407 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9408 }
9409 if (status) {
9410 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9411 !destination_size) {
9412 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9413 "driver size %d destination size %d",
9414 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9415 status = false;
9416 c2d.close();
9417 buffer_size_req = 0;
9418 } else {
9419 buffer_size_req = destination_size;
9420 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9421 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9422 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9423 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9424 }
9425 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009426fail_update_buf_req:
9427 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009428 return status;
9429}
9430
9431bool omx_vdec::allocate_color_convert_buf::set_color_format(
9432 OMX_COLOR_FORMATTYPE dest_color_format)
9433{
9434 bool status = true;
9435 OMX_COLOR_FORMATTYPE drv_color_format;
9436 if (!omx){
9437 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9438 return false;
9439 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009440 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009441 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9442 drv_color_format = (OMX_COLOR_FORMATTYPE)
9443 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9444 else {
9445 DEBUG_PRINT_ERROR("\n Incorrect color format");
9446 status = false;
9447 }
9448 if (status && (drv_color_format != dest_color_format)) {
9449 DEBUG_PRINT_LOW("Enabling C2D\n");
9450 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9451 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9452 status = false;
9453 } else {
9454 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9455 if (enabled)
9456 c2d.destroy();
9457 enabled = false;
9458 if (!c2d.init()) {
9459 DEBUG_PRINT_ERROR("\n open failed for c2d");
9460 status = false;
9461 } else
9462 enabled = true;
9463 }
9464 } else {
9465 if (enabled)
9466 c2d.destroy();
9467 enabled = false;
9468 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009469 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009470 return status;
9471}
9472
9473OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9474{
9475 if (!omx){
9476 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9477 return NULL;
9478 }
9479 if (!enabled)
9480 return omx->m_out_mem_ptr;
9481 return m_out_mem_ptr_client;
9482}
9483
9484OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9485 (OMX_BUFFERHEADERTYPE *bufadd)
9486{
9487 if (!omx){
9488 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9489 return NULL;
9490 }
9491 if (!enabled)
9492 return bufadd;
9493
9494 unsigned index = 0;
9495 index = bufadd - omx->m_out_mem_ptr;
9496 if (index < omx->drv_ctx.op_buf.actualcount) {
9497 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9498 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9499 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009500 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009501 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009502 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
Rajeshwar Kurapaty18ca33c2013-06-04 01:25:28 +05309503 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9504 pmem_baseaddress[index], pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009505 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009506 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9507 if (!status){
9508 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009509 m_out_mem_ptr_client[index].nFilledLen = 0;
9510 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009511 }
9512 } else
9513 m_out_mem_ptr_client[index].nFilledLen = 0;
9514 return &m_out_mem_ptr_client[index];
9515 }
9516 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9517 return NULL;
9518}
9519
9520OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9521 (OMX_BUFFERHEADERTYPE *bufadd)
9522{
9523 if (!omx){
9524 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9525 return NULL;
9526 }
9527 if (!enabled)
9528 return bufadd;
9529 unsigned index = 0;
9530 index = bufadd - m_out_mem_ptr_client;
9531 if (index < omx->drv_ctx.op_buf.actualcount) {
9532 return &omx->m_out_mem_ptr[index];
9533 }
9534 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9535 return NULL;
9536}
9537bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9538 (unsigned int &buffer_size)
9539{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009540 bool status = true;
9541 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009542 if (!enabled)
9543 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009544 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009545 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9546 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009547 status = false;
9548 goto fail_get_buffer_size;
9549 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009550 }
9551 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9552 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9553 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9554 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009555fail_get_buffer_size:
9556 pthread_mutex_unlock(&omx->c_lock);
9557 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009558}
9559OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9560 OMX_BUFFERHEADERTYPE *bufhdr) {
9561 unsigned int index = 0;
9562
9563 if (!enabled)
9564 return omx->free_output_buffer(bufhdr);
9565 if (enabled && omx->is_component_secure())
9566 return OMX_ErrorNone;
9567 if (!allocated_count || !bufhdr) {
9568 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9569 return OMX_ErrorBadParameter;
9570 }
9571 index = bufhdr - m_out_mem_ptr_client;
9572 if (index >= omx->drv_ctx.op_buf.actualcount){
9573 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9574 return OMX_ErrorBadParameter;
9575 }
9576 if (pmem_fd[index] > 0) {
9577 munmap(pmem_baseaddress[index], buffer_size_req);
9578 close(pmem_fd[index]);
9579 }
9580 pmem_fd[index] = -1;
9581#ifdef USE_ION
9582 omx->free_ion_memory(&op_buf_ion_info[index]);
9583#endif
9584 m_heap_ptr[index].video_heap_ptr = NULL;
9585 if (allocated_count > 0)
9586 allocated_count--;
9587 else
9588 allocated_count = 0;
9589 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009590 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009591 c2d.close();
9592 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009593 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009594 }
9595 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9596}
9597
9598OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9599 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9600{
9601 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9602 if (!enabled){
9603 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9604 return eRet;
9605 }
9606 if (enabled && omx->is_component_secure()) {
9607 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9608 omx->is_component_secure());
9609 return OMX_ErrorUnsupportedSetting;
9610 }
9611 if (!bufferHdr || bytes > buffer_size_req) {
9612 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009613 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009614 buffer_size_req,bytes);
9615 return OMX_ErrorBadParameter;
9616 }
9617 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9618 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9619 return OMX_ErrorInsufficientResources;
9620 }
9621 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9622 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9623 port,appData,omx->drv_ctx.op_buf.buffer_size);
9624 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9625 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9626 return eRet;
9627 }
9628 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9629 omx->drv_ctx.op_buf.actualcount) {
9630 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9631 (temp_bufferHdr - omx->m_out_mem_ptr));
9632 return OMX_ErrorUndefined;
9633 }
9634 unsigned int i = allocated_count;
9635#ifdef USE_ION
9636 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9637 buffer_size_req,buffer_alignment_req,
9638 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009639 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009640 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9641 if (op_buf_ion_info[i].ion_device_fd < 0) {
9642 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9643 return OMX_ErrorInsufficientResources;
9644 }
9645 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9646 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9647
9648 if (pmem_baseaddress[i] == MAP_FAILED) {
9649 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9650 close(pmem_fd[i]);
9651 omx->free_ion_memory(&op_buf_ion_info[i]);
9652 return OMX_ErrorInsufficientResources;
9653 }
9654 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9655 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9656 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9657#endif
9658 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9659 m_pmem_info_client[i].offset = 0;
9660 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9661 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9662 m_platform_list_client[i].nEntries = 1;
9663 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9664 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9665 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9666 m_out_mem_ptr_client[i].nFilledLen = 0;
9667 m_out_mem_ptr_client[i].nFlags = 0;
9668 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9669 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9670 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9671 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9672 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9673 m_out_mem_ptr_client[i].pAppPrivate = appData;
9674 *bufferHdr = &m_out_mem_ptr_client[i];
9675 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9676 allocated_count++;
9677 return eRet;
9678}
9679
9680bool omx_vdec::is_component_secure()
9681{
9682 return secure_mode;
9683}
9684
9685bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9686{
9687 bool status = true;
9688 if (!enabled) {
9689 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9690 dest_color_format = (OMX_COLOR_FORMATTYPE)
9691 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9692 else
9693 status = false;
9694 } else {
9695 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9696 status = false;
9697 } else
9698 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9699 }
9700 return status;
9701}