blob: 94575defe2503714fa6a075ecedee8a12168b66d [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Maheshwar Ajja507d6552014-01-03 14:54:29 +05302Copyright (c) 2010 - 2014, 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>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080053#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070054
55#ifndef _ANDROID_
56#include <sys/ioctl.h>
57#include <sys/mman.h>
58#endif //_ANDROID_
59
60#ifdef _ANDROID_
61#include <cutils/properties.h>
62#undef USE_EGL_IMAGE_GPU
63#endif
64
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070065#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070066
67#ifdef _ANDROID_
68#include "DivXDrmDecrypt.h"
69#endif //_ANDROID_
70
Arun Menon45346052013-11-13 12:40:08 -080071#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070072#include "QComOMXMetadata.h"
73#endif
74
Shalaj Jain273b3e02012-06-22 19:08:03 -070075#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070081
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070082#define BUFFER_LOG_LOC "/data/misc/media"
83
Shalaj Jain273b3e02012-06-22 19:08:03 -070084#ifdef OUTPUT_EXTRADATA_LOG
85FILE *outputExtradataFile;
86char ouputextradatafilename [] = "/data/extradata";
87#endif
88
89#define DEFAULT_FPS 30
90#define MAX_INPUT_ERROR DEFAULT_FPS
91#define MAX_SUPPORTED_FPS 120
92
93#define VC1_SP_MP_START_CODE 0xC5000000
94#define VC1_SP_MP_START_CODE_MASK 0xFF000000
95#define VC1_AP_SEQ_START_CODE 0x0F010000
96#define VC1_STRUCT_C_PROFILE_MASK 0xF0
97#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
98#define VC1_SIMPLE_PROFILE 0
99#define VC1_MAIN_PROFILE 1
100#define VC1_ADVANCE_PROFILE 3
101#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
102#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
103#define VC1_STRUCT_C_LEN 4
104#define VC1_STRUCT_C_POS 8
105#define VC1_STRUCT_A_POS 12
106#define VC1_STRUCT_B_POS 24
107#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700108#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700109
110#define MEM_DEVICE "/dev/ion"
111#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
112
113#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700114extern "C" {
115#include<utils/Log.h>
116}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700117#endif//_ANDROID_
118
Vinay Kalia53fa6832012-10-11 17:55:30 -0700119#define SZ_4K 0x1000
120#define SZ_1M 0x100000
121
Shalaj Jain273b3e02012-06-22 19:08:03 -0700122#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
123#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 -0700124#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
125
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800126#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700127
128int debug_level = PRIO_ERROR;
129
Praveen Chavancf924182013-12-06 23:16:23 -0800130static const OMX_U32 kMaxSmoothStreamingWidth = 1920;
131static const OMX_U32 kMaxSmoothStreamingHeight = 1088;
132
Shalaj Jain273b3e02012-06-22 19:08:03 -0700133void* async_message_thread (void *input)
134{
Arun Menon906de572013-06-18 17:01:40 -0700135 OMX_BUFFERHEADERTYPE *buffer;
136 struct v4l2_plane plane[VIDEO_MAX_PLANES];
137 struct pollfd pfd;
138 struct v4l2_buffer v4l2_buf;
139 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
140 struct v4l2_event dqevent;
141 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
142 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
143 pfd.fd = omx->drv_ctx.video_driver_fd;
144 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700145 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700146 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
147 while (1) {
148 rc = poll(&pfd, 1, POLL_TIMEOUT);
149 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700150 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700151 break;
152 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700153 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700154 break;
155 }
156 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
157 struct vdec_msginfo vdec_msg;
158 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
159 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
160 v4l2_buf.length = omx->drv_ctx.num_planes;
161 v4l2_buf.m.planes = plane;
162 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
163 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
164 vdec_msg.status_code=VDEC_S_SUCCESS;
165 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
166 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
167 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
168 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
169 (uint64_t)v4l2_buf.timestamp.tv_usec;
170 if (vdec_msg.msgdata.output_frame.len) {
171 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
172 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
173 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
174 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
175 }
176 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700177 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700178 break;
179 }
180 }
181 }
182 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
183 struct vdec_msginfo vdec_msg;
184 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
185 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
186 v4l2_buf.length = 1;
187 v4l2_buf.m.planes = plane;
188 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
189 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
190 vdec_msg.status_code=VDEC_S_SUCCESS;
191 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
192 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700193 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700194 break;
195 }
196 }
197 }
198 if (pfd.revents & POLLPRI) {
199 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
200 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
201 struct vdec_msginfo vdec_msg;
202 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
203 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700204 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700205 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700206 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700207 break;
208 }
209 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
210 struct vdec_msginfo vdec_msg;
211 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
212 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700213 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700214 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700215 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700216 break;
217 }
218 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
219 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700220 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700221 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700222 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700223 break;
224 }
225 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700226 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700227 break;
228 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
229 struct vdec_msginfo vdec_msg;
230 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
231 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700232 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700233 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700234 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700235 break;
236 }
Arun Menon45346052013-11-13 12:40:08 -0800237 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700238 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700239 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700240 omx->buf_ref_remove(ptr[0], ptr[1]);
241 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
242 unsigned int *ptr = (unsigned int *)dqevent.u.data;
243 struct vdec_msginfo vdec_msg;
244
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700245 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700246
247 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
248 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
249 v4l2_buf.length = omx->drv_ctx.num_planes;
250 v4l2_buf.m.planes = plane;
251 v4l2_buf.index = ptr[5];
252 v4l2_buf.flags = 0;
253
254 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
255 vdec_msg.status_code = VDEC_S_SUCCESS;
256 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
257 vdec_msg.msgdata.output_frame.len = 0;
258 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
259 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
260 (uint64_t)ptr[4];
261 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700262 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700263 break;
264 }
265 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700266 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700267 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700268 continue;
269 }
270 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700271 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700272 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700273 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700274}
275
276void* message_thread(void *input)
277{
Arun Menon906de572013-06-18 17:01:40 -0700278 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
279 unsigned char id;
280 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700281
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700282 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700283 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
284 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700285
Arun Menon906de572013-06-18 17:01:40 -0700286 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287
Arun Menon906de572013-06-18 17:01:40 -0700288 if (0 == n) {
289 break;
290 }
291
292 if (1 == n) {
293 omx->process_event_cb(omx, id);
294 }
295 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700296 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700297 break;
298 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700299 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700300 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700301 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302}
303
304void post_message(omx_vdec *omx, unsigned char id)
305{
Arun Menon906de572013-06-18 17:01:40 -0700306 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700307 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700308 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700309 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700310}
311
312// omx_cmd_queue destructor
313omx_vdec::omx_cmd_queue::~omx_cmd_queue()
314{
Arun Menon906de572013-06-18 17:01:40 -0700315 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700316}
317
318// omx cmd queue constructor
319omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
320{
321 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
322}
323
324// omx cmd queue insert
325bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
326{
Arun Menon906de572013-06-18 17:01:40 -0700327 bool ret = true;
328 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
329 m_q[m_write].id = id;
330 m_q[m_write].param1 = p1;
331 m_q[m_write].param2 = p2;
332 m_write++;
333 m_size ++;
334 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
335 m_write = 0;
336 }
337 } else {
338 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700339 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700340 }
Arun Menon906de572013-06-18 17:01:40 -0700341 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342}
343
344// omx cmd queue pop
345bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
346{
Arun Menon906de572013-06-18 17:01:40 -0700347 bool ret = true;
348 if (m_size > 0) {
349 *id = m_q[m_read].id;
350 *p1 = m_q[m_read].param1;
351 *p2 = m_q[m_read].param2;
352 // Move the read pointer ahead
353 ++m_read;
354 --m_size;
355 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
356 m_read = 0;
357 }
358 } else {
359 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700360 }
Arun Menon906de572013-06-18 17:01:40 -0700361 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700362}
363
364// Retrieve the first mesg type in the queue
365unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
366{
367 return m_q[m_read].id;
368}
369
370#ifdef _ANDROID_
371omx_vdec::ts_arr_list::ts_arr_list()
372{
Arun Menon906de572013-06-18 17:01:40 -0700373 //initialize timestamps array
374 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700375}
376omx_vdec::ts_arr_list::~ts_arr_list()
377{
Arun Menon906de572013-06-18 17:01:40 -0700378 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700379}
380
381bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
382{
Arun Menon906de572013-06-18 17:01:40 -0700383 bool ret = true;
384 bool duplicate_ts = false;
385 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700386
Arun Menon906de572013-06-18 17:01:40 -0700387 //insert at the first available empty location
388 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
389 if (!m_ts_arr_list[idx].valid) {
390 //found invalid or empty entry, save timestamp
391 m_ts_arr_list[idx].valid = true;
392 m_ts_arr_list[idx].timestamp = ts;
393 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
394 ts, idx);
395 break;
396 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700397 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700398
Arun Menon906de572013-06-18 17:01:40 -0700399 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
400 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
401 ret = false;
402 }
403 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700404}
405
406bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
407{
Arun Menon906de572013-06-18 17:01:40 -0700408 bool ret = true;
409 int min_idx = -1;
410 OMX_TICKS min_ts = 0;
411 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700412
Arun Menon906de572013-06-18 17:01:40 -0700413 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 if (m_ts_arr_list[idx].valid) {
416 //found valid entry, save index
417 if (min_idx < 0) {
418 //first valid entry
419 min_ts = m_ts_arr_list[idx].timestamp;
420 min_idx = idx;
421 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
422 min_ts = m_ts_arr_list[idx].timestamp;
423 min_idx = idx;
424 }
425 }
426
Shalaj Jain273b3e02012-06-22 19:08:03 -0700427 }
428
Arun Menon906de572013-06-18 17:01:40 -0700429 if (min_idx < 0) {
430 //no valid entries found
431 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
432 ts = 0;
433 ret = false;
434 } else {
435 ts = m_ts_arr_list[min_idx].timestamp;
436 m_ts_arr_list[min_idx].valid = false;
437 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
438 ts, min_idx);
439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700440
Arun Menon906de572013-06-18 17:01:40 -0700441 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442
443}
444
445
446bool omx_vdec::ts_arr_list::reset_ts_list()
447{
Arun Menon906de572013-06-18 17:01:40 -0700448 bool ret = true;
449 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700450
Arun Menon906de572013-06-18 17:01:40 -0700451 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
452 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
453 m_ts_arr_list[idx].valid = false;
454 }
455 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700456}
457#endif
458
459// factory function executed by the core to create instances
460void *get_omx_component_factory_fn(void)
461{
Arun Menon906de572013-06-18 17:01:40 -0700462 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700463}
464
465#ifdef _ANDROID_
466#ifdef USE_ION
467VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700468 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700469{
Arun Menon906de572013-06-18 17:01: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/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700481 FUNCTION
482 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700483
Arun Menon906de572013-06-18 17:01:40 -0700484 DESCRIPTION
485 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700486
Arun Menon906de572013-06-18 17:01:40 -0700487 PARAMETERS
488 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700489
Arun Menon906de572013-06-18 17:01:40 -0700490 RETURN VALUE
491 None.
492 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800493omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700494 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_
Arun Menon906de572013-06-18 17:01:40 -0700515 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#endif
Arun Menon906de572013-06-18 17:01:40 -0700517 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),
Arun Menon906de572013-06-18 17:01:40 -0700540 h264_last_au_ts(LLONG_MAX),
541 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530542 m_disp_hor_size(0),
543 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700544 prev_ts(LLONG_MAX),
545 rst_prev_ts(true),
546 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700547 in_reconfig(false),
548 m_display_id(NULL),
549 h264_parser(NULL),
550 client_extradata(0),
551 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530552 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700553#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700554 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
Arun Menon906de572013-06-18 17:01:40 -0700558 m_desc_buffer_ptr(NULL),
559 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530560 m_profile(0),
Arun Menon906de572013-06-18 17:01:40 -0700561 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700562{
Arun Menon906de572013-06-18 17:01:40 -0700563 /* Assumption is that , to begin with , we have all the frames with decoder */
564 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700565 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700566#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700567 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700568 property_get("vidc.debug.level", property_value, "0");
569 debug_level = atoi(property_value);
570 property_value[0] = '\0';
571
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700572 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
573
Arun Menon906de572013-06-18 17:01:40 -0700574 property_get("vidc.dec.debug.perf", property_value, "0");
575 perf_flag = atoi(property_value);
576 if (perf_flag) {
577 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
578 dec_time.start();
579 proc_frms = latency = 0;
580 }
581 prev_n_filled_len = 0;
582 property_value[0] = '\0';
583 property_get("vidc.dec.debug.ts", property_value, "0");
584 m_debug_timestamp = atoi(property_value);
585 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
586 if (m_debug_timestamp) {
587 time_stamp_dts.set_timestamp_reorder_mode(true);
588 time_stamp_dts.enable_debug_print(true);
589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700590
Arun Menon906de572013-06-18 17:01:40 -0700591 property_value[0] = '\0';
592 property_get("vidc.dec.debug.concealedmb", property_value, "0");
593 m_debug_concealedmb = atoi(property_value);
594 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700595
Arun Menon906de572013-06-18 17:01:40 -0700596 property_value[0] = '\0';
597 property_get("vidc.dec.profile.check", property_value, "0");
598 m_reject_avc_1080p_mp = atoi(property_value);
599 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530600
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700601 property_value[0] = '\0';
602 property_get("vidc.dec.log.in", property_value, "0");
603 m_debug.in_buffer_log = atoi(property_value);
604
605 property_value[0] = '\0';
606 property_get("vidc.dec.log.out", property_value, "0");
607 m_debug.out_buffer_log = atoi(property_value);
608 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
609
610 property_value[0] = '\0';
611 property_get("vidc.log.loc", property_value, "");
612 if (*property_value)
613 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700614#endif
Arun Menon906de572013-06-18 17:01:40 -0700615 memset(&m_cmp,0,sizeof(m_cmp));
616 memset(&m_cb,0,sizeof(m_cb));
617 memset (&drv_ctx,0,sizeof(drv_ctx));
618 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
619 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
620 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
621 m_demux_entries = 0;
622 msg_thread_id = 0;
623 async_thread_id = 0;
624 msg_thread_created = false;
625 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700626#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700627 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700628#endif
Arun Menon906de572013-06-18 17:01:40 -0700629 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530630 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700631 drv_ctx.timestamp_adjust = false;
632 drv_ctx.video_driver_fd = -1;
633 m_vendor_config.pData = NULL;
634 pthread_mutex_init(&m_lock, NULL);
635 pthread_mutex_init(&c_lock, NULL);
636 sem_init(&m_cmd_lock,0,0);
637 streaming[CAPTURE_PORT] =
638 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700639#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700640 char extradata_value[PROPERTY_VALUE_MAX] = {0};
641 property_get("vidc.dec.debug.extradata", extradata_value, "0");
642 m_debug_extradata = atoi(extradata_value);
643 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700644#endif
Arun Menon906de572013-06-18 17:01:40 -0700645 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
646 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700647 dynamic_buf_mode = false;
648 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800649 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800650 m_smoothstreaming_mode = false;
651 m_smoothstreaming_width = 0;
652 m_smoothstreaming_height = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700653}
654
Vinay Kalia85793762012-06-14 19:12:34 -0700655static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700656 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
657 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
658 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700659 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
660 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700661 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
662 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700663};
664
665static OMX_ERRORTYPE subscribe_to_events(int fd)
666{
Arun Menon906de572013-06-18 17:01:40 -0700667 OMX_ERRORTYPE eRet = OMX_ErrorNone;
668 struct v4l2_event_subscription sub;
669 int array_sz = sizeof(event_type)/sizeof(int);
670 int i,rc;
671 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700672 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700673 return OMX_ErrorBadParameter;
674 }
Vinay Kalia85793762012-06-14 19:12:34 -0700675
Arun Menon906de572013-06-18 17:01:40 -0700676 for (i = 0; i < array_sz; ++i) {
677 memset(&sub, 0, sizeof(sub));
678 sub.type = event_type[i];
679 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
680 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700681 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700682 break;
683 }
684 }
685 if (i < array_sz) {
686 for (--i; i >=0 ; i--) {
687 memset(&sub, 0, sizeof(sub));
688 sub.type = event_type[i];
689 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
690 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700691 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700692 }
693 eRet = OMX_ErrorNotImplemented;
694 }
695 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700696}
697
698
699static OMX_ERRORTYPE unsubscribe_to_events(int fd)
700{
Arun Menon906de572013-06-18 17:01:40 -0700701 OMX_ERRORTYPE eRet = OMX_ErrorNone;
702 struct v4l2_event_subscription sub;
703 int array_sz = sizeof(event_type)/sizeof(int);
704 int i,rc;
705 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700706 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700707 return OMX_ErrorBadParameter;
708 }
Vinay Kalia85793762012-06-14 19:12:34 -0700709
Arun Menon906de572013-06-18 17:01:40 -0700710 for (i = 0; i < array_sz; ++i) {
711 memset(&sub, 0, sizeof(sub));
712 sub.type = event_type[i];
713 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
714 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700715 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700716 break;
717 }
718 }
719 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700720}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700721
722/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700723 FUNCTION
724 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700725
Arun Menon906de572013-06-18 17:01:40 -0700726 DESCRIPTION
727 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728
Arun Menon906de572013-06-18 17:01:40 -0700729 PARAMETERS
730 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700731
Arun Menon906de572013-06-18 17:01:40 -0700732 RETURN VALUE
733 None.
734 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700735omx_vdec::~omx_vdec()
736{
Arun Menon906de572013-06-18 17:01:40 -0700737 m_pmem_info = NULL;
738 struct v4l2_decoder_cmd dec;
739 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
740 if (m_pipe_in) close(m_pipe_in);
741 if (m_pipe_out) close(m_pipe_out);
742 m_pipe_in = -1;
743 m_pipe_out = -1;
744 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
745 if (msg_thread_created)
746 pthread_join(msg_thread_id,NULL);
747 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
748 dec.cmd = V4L2_DEC_CMD_STOP;
749 if (drv_ctx.video_driver_fd >=0 ) {
750 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700751 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700752 }
753 if (async_thread_created)
754 pthread_join(async_thread_id,NULL);
755 unsubscribe_to_events(drv_ctx.video_driver_fd);
756 close(drv_ctx.video_driver_fd);
757 pthread_mutex_destroy(&m_lock);
758 pthread_mutex_destroy(&c_lock);
759 sem_destroy(&m_cmd_lock);
760 if (perf_flag) {
761 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
762 dec_time.end();
763 }
764 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700765}
766
Arun Menon906de572013-06-18 17:01:40 -0700767int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
768{
769 struct v4l2_requestbuffers bufreq;
770 int rc = 0;
771 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
772 bufreq.memory = V4L2_MEMORY_USERPTR;
773 bufreq.count = 0;
774 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
775 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530776 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
777 bufreq.memory = V4L2_MEMORY_USERPTR;
778 bufreq.count = 0;
779 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
780 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700781 }
782 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700783}
784
Shalaj Jain273b3e02012-06-22 19:08:03 -0700785/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700786 FUNCTION
787 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700788
Arun Menon906de572013-06-18 17:01:40 -0700789 DESCRIPTION
790 IL Client callbacks are generated through this routine. The decoder
791 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700792
Arun Menon906de572013-06-18 17:01:40 -0700793 PARAMETERS
794 ctxt -- Context information related to the self.
795 id -- Event identifier. This could be any of the following:
796 1. Command completion event
797 2. Buffer done callback event
798 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799
Arun Menon906de572013-06-18 17:01:40 -0700800 RETURN VALUE
801 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700802
Arun Menon906de572013-06-18 17:01:40 -0700803 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700804void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
805{
Arun Menon906de572013-06-18 17:01:40 -0700806 signed p1; // Parameter - 1
807 signed p2; // Parameter - 2
808 unsigned ident;
809 unsigned qsize=0; // qsize
810 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700811
Arun Menon906de572013-06-18 17:01:40 -0700812 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700813 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700814 __func__);
815 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816 }
817
Arun Menon906de572013-06-18 17:01:40 -0700818 // Protect the shared queue data structure
819 do {
820 /*Read the message id's from the queue*/
821 pthread_mutex_lock(&pThis->m_lock);
822 qsize = pThis->m_cmd_q.m_size;
823 if (qsize) {
824 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700825 }
Arun Menon906de572013-06-18 17:01:40 -0700826
827 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
828 qsize = pThis->m_ftb_q.m_size;
829 if (qsize) {
830 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
831 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700832 }
Arun Menon906de572013-06-18 17:01:40 -0700833
834 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
835 qsize = pThis->m_etb_q.m_size;
836 if (qsize) {
837 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
838 }
839 }
840 pthread_mutex_unlock(&pThis->m_lock);
841
842 /*process message if we have one*/
843 if (qsize > 0) {
844 id = ident;
845 switch (id) {
846 case OMX_COMPONENT_GENERATE_EVENT:
847 if (pThis->m_cb.EventHandler) {
848 switch (p1) {
849 case OMX_CommandStateSet:
850 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700851 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700852 pThis->m_state);
853 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
854 OMX_EventCmdComplete, p1, p2, NULL);
855 break;
856
857 case OMX_EventError:
858 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700859 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700860 pThis->m_state = (OMX_STATETYPE) p2;
861 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
862 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
863 } else if (p2 == OMX_ErrorHardware) {
864 pThis->omx_report_error();
865 } else {
866 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
867 OMX_EventError, p2, (OMX_U32)NULL, NULL );
868 }
869 break;
870
871 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700872 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700873 if (BITMASK_PRESENT(&pThis->m_flags,
874 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
875 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
876 break;
877 }
878 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
879 OMX_ERRORTYPE eRet = OMX_ErrorNone;
880 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
881 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700882 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700883 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
884 pThis->in_reconfig = false;
885 if (eRet != OMX_ErrorNone) {
886 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
887 pThis->omx_report_error();
888 break;
889 }
890 }
891 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
892 OMX_EventCmdComplete, p1, p2, NULL );
893 break;
894 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700895 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700896 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
897 OMX_EventCmdComplete, p1, p2, NULL );
898 break;
899
900 default:
901 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
902 OMX_EventCmdComplete, p1, p2, NULL );
903 break;
904
905 }
906 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700907 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700908 }
909 break;
910 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
911 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
912 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700913 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700914 pThis->omx_report_error ();
915 }
916 break;
917 case OMX_COMPONENT_GENERATE_ETB:
918 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
919 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700920 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700921 pThis->omx_report_error ();
922 }
923 break;
924
925 case OMX_COMPONENT_GENERATE_FTB:
926 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
927 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->omx_report_error ();
930 }
931 break;
932
933 case OMX_COMPONENT_GENERATE_COMMAND:
934 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
935 (OMX_U32)p2,(OMX_PTR)NULL);
936 break;
937
938 case OMX_COMPONENT_GENERATE_EBD:
939
940 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700941 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700942 pThis->omx_report_error ();
943 } else {
944 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
945 pThis->m_inp_err_count++;
946 pThis->time_stamp_dts.remove_time_stamp(
947 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
948 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
949 ?true:false);
950 } else {
951 pThis->m_inp_err_count = 0;
952 }
953 if ( pThis->empty_buffer_done(&pThis->m_cmp,
954 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700955 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700956 pThis->omx_report_error ();
957 }
958 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700959 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700960 pThis->omx_report_error ();
961 }
962 }
963 break;
964 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
965 int64_t *timestamp = (int64_t *)p1;
966 if (p1) {
967 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
968 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
969 ?true:false);
970 free(timestamp);
971 }
972 }
973 break;
974 case OMX_COMPONENT_GENERATE_FBD:
975 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700976 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700977 pThis->omx_report_error ();
978 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
979 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700980 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700986 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -0700987 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700988 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -0700989 } else {
990 pThis->execute_input_flush();
991 if (pThis->m_cb.EventHandler) {
992 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700993 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -0700994 pThis->omx_report_error ();
995 } else {
996 /*Check if we need generate event for Flush done*/
997 if (BITMASK_PRESENT(&pThis->m_flags,
998 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
999 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001000 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001001 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1002 OMX_EventCmdComplete,OMX_CommandFlush,
1003 OMX_CORE_INPUT_PORT_INDEX,NULL );
1004 }
1005 if (BITMASK_PRESENT(&pThis->m_flags,
1006 OMX_COMPONENT_IDLE_PENDING)) {
1007 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001008 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001009 pThis->omx_report_error ();
1010 } else {
1011 pThis->streaming[OUTPUT_PORT] = false;
1012 }
1013 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001014 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001015 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1016 OMX_COMPONENT_GENERATE_STOP_DONE);
1017 }
1018 }
1019 }
1020 } else {
1021 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1022 }
1023 }
1024 break;
1025
1026 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001027 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001028 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001029 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001030 } else {
1031 pThis->execute_output_flush();
1032 if (pThis->m_cb.EventHandler) {
1033 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001034 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001035 pThis->omx_report_error ();
1036 } else {
1037 /*Check if we need generate event for Flush done*/
1038 if (BITMASK_PRESENT(&pThis->m_flags,
1039 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001040 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001041 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1042 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1043 OMX_EventCmdComplete,OMX_CommandFlush,
1044 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1045 }
1046 if (BITMASK_PRESENT(&pThis->m_flags,
1047 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001048 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001049 BITMASK_CLEAR (&pThis->m_flags,
1050 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1051 if (BITMASK_PRESENT(&pThis->m_flags,
1052 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1053 pThis->post_event(OMX_CommandPortDisable,
1054 OMX_CORE_OUTPUT_PORT_INDEX,
1055 OMX_COMPONENT_GENERATE_EVENT);
1056 BITMASK_CLEAR (&pThis->m_flags,
1057 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1058
1059 }
1060 }
1061
1062 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1063 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001064 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001065 pThis->omx_report_error ();
1066 break;
1067 }
1068 pThis->streaming[CAPTURE_PORT] = false;
1069 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001070 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001071 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1072 OMX_COMPONENT_GENERATE_STOP_DONE);
1073 }
1074 }
1075 }
1076 } else {
1077 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1078 }
1079 }
1080 break;
1081
1082 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001083 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001084
1085 if (pThis->m_cb.EventHandler) {
1086 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001087 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001088 pThis->omx_report_error ();
1089 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001090 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001091 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001092 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001093 // Send the callback now
1094 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1095 pThis->m_state = OMX_StateExecuting;
1096 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1097 OMX_EventCmdComplete,OMX_CommandStateSet,
1098 OMX_StateExecuting, NULL);
1099 } else if (BITMASK_PRESENT(&pThis->m_flags,
1100 OMX_COMPONENT_PAUSE_PENDING)) {
1101 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1102 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001103 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001104 pThis->omx_report_error ();
1105 }
1106 }
1107 }
1108 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001109 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001110 }
1111 break;
1112
1113 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001114 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001115 if (pThis->m_cb.EventHandler) {
1116 if (p2 != VDEC_S_SUCCESS) {
1117 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1118 pThis->omx_report_error ();
1119 } else {
1120 pThis->complete_pending_buffer_done_cbs();
1121 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001122 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001123 //Send the callback now
1124 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1125 pThis->m_state = OMX_StatePause;
1126 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1127 OMX_EventCmdComplete,OMX_CommandStateSet,
1128 OMX_StatePause, NULL);
1129 }
1130 }
1131 } else {
1132 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1133 }
1134
1135 break;
1136
1137 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001138 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001139 if (pThis->m_cb.EventHandler) {
1140 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001141 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001142 pThis->omx_report_error ();
1143 } else {
1144 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001145 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001146 // Send the callback now
1147 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1148 pThis->m_state = OMX_StateExecuting;
1149 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1150 OMX_EventCmdComplete,OMX_CommandStateSet,
1151 OMX_StateExecuting,NULL);
1152 }
1153 }
1154 } else {
1155 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1156 }
1157
1158 break;
1159
1160 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001161 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001162 if (pThis->m_cb.EventHandler) {
1163 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001164 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001165 pThis->omx_report_error ();
1166 } else {
1167 pThis->complete_pending_buffer_done_cbs();
1168 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001169 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001170 // Send the callback now
1171 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1172 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001173 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001174 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1175 OMX_EventCmdComplete,OMX_CommandStateSet,
1176 OMX_StateIdle,NULL);
1177 }
1178 }
1179 } else {
1180 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1181 }
1182
1183 break;
1184
1185 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001186 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001187
1188 if (p2 == OMX_IndexParamPortDefinition) {
1189 pThis->in_reconfig = true;
1190 }
1191 if (pThis->m_cb.EventHandler) {
1192 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1193 OMX_EventPortSettingsChanged, p1, p2, NULL );
1194 } else {
1195 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1196 }
1197
Arun Menon906de572013-06-18 17:01:40 -07001198 break;
1199
1200 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001201 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001202 if (pThis->m_cb.EventHandler) {
1203 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1204 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1205 } else {
1206 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1207 }
1208 pThis->prev_ts = LLONG_MAX;
1209 pThis->rst_prev_ts = true;
1210 break;
1211
1212 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001213 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001214 pThis->omx_report_error ();
1215 break;
1216
1217 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001218 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001219 pThis->omx_report_unsupported_setting();
1220 break;
1221
Arun Menon906de572013-06-18 17:01:40 -07001222 default:
1223 break;
1224 }
1225 }
1226 pthread_mutex_lock(&pThis->m_lock);
1227 qsize = pThis->m_cmd_q.m_size;
1228 if (pThis->m_state != OMX_StatePause)
1229 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1230 pthread_mutex_unlock(&pThis->m_lock);
1231 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001232
1233}
1234
Vinay Kaliab9e98102013-04-02 19:31:43 -07001235int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001236{
Arun Menon906de572013-06-18 17:01:40 -07001237 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301238 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1239 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001240 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001241 width, drv_ctx.video_resolution.frame_width,
1242 height,drv_ctx.video_resolution.frame_height);
1243 format_changed = 1;
1244 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 drv_ctx.video_resolution.frame_height = height;
1246 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001247 drv_ctx.video_resolution.scan_lines = scan_lines;
1248 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001249 rectangle.nLeft = 0;
1250 rectangle.nTop = 0;
1251 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1252 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001253 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001254}
1255
Arun Menon6836ba02013-02-19 20:37:40 -08001256OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1257{
Arun Menon906de572013-06-18 17:01:40 -07001258 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1259 OMX_MAX_STRINGNAME_SIZE) &&
1260 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1261 m_decoder_capability.max_width = 1280;
1262 m_decoder_capability.max_height = 720;
1263 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1264 }
Arun Menon888aa852013-05-30 11:24:42 -07001265
Arun Menon906de572013-06-18 17:01:40 -07001266 if ((drv_ctx.video_resolution.frame_width *
1267 drv_ctx.video_resolution.frame_height >
1268 m_decoder_capability.max_width *
1269 m_decoder_capability.max_height) ||
1270 (drv_ctx.video_resolution.frame_width*
1271 drv_ctx.video_resolution.frame_height <
1272 m_decoder_capability.min_width *
1273 m_decoder_capability.min_height)) {
1274 DEBUG_PRINT_ERROR(
1275 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1276 drv_ctx.video_resolution.frame_width,
1277 drv_ctx.video_resolution.frame_height,
1278 m_decoder_capability.min_width,
1279 m_decoder_capability.min_height,
1280 m_decoder_capability.max_width,
1281 m_decoder_capability.max_height);
1282 return OMX_ErrorUnsupportedSetting;
1283 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001284 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001285 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001286}
1287
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001288int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1289{
1290 if (m_debug.in_buffer_log && !m_debug.infile) {
1291 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1292 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1293 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1294 }
1295 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1296 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); }
1297 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1298 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1299 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1300 }
1301 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1302 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1303 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1304 }
1305 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1306 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1307 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1308 }
1309 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1310 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1311 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1312 }
1313 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1314 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1315 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1316 }
1317 m_debug.infile = fopen (m_debug.infile_name, "ab");
1318 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001319 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001320 m_debug.infile_name[0] = '\0';
1321 return -1;
1322 }
1323 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1324 struct ivf_file_header {
1325 OMX_U8 signature[4]; //='DKIF';
1326 OMX_U8 version ; //= 0;
1327 OMX_U8 headersize ; //= 32;
1328 OMX_U32 FourCC;
1329 OMX_U8 width;
1330 OMX_U8 height;
1331 OMX_U32 rate;
1332 OMX_U32 scale;
1333 OMX_U32 length;
1334 OMX_U8 unused[4];
1335 } file_header;
1336
1337 memset((void *)&file_header,0,sizeof(file_header));
1338 file_header.signature[0] = 'D';
1339 file_header.signature[1] = 'K';
1340 file_header.signature[2] = 'I';
1341 file_header.signature[3] = 'F';
1342 file_header.version = 0;
1343 file_header.headersize = 32;
1344 file_header.FourCC = 0x30385056;
1345 fwrite((const char *)&file_header,
1346 sizeof(file_header),1,m_debug.infile);
1347 }
1348 }
1349 if (m_debug.infile && buffer_addr && buffer_len) {
1350 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1351 struct vp8_ivf_frame_header {
1352 OMX_U32 framesize;
1353 OMX_U32 timestamp_lo;
1354 OMX_U32 timestamp_hi;
1355 } vp8_frame_header;
1356 vp8_frame_header.framesize = buffer_len;
1357 /* Currently FW doesn't use timestamp values */
1358 vp8_frame_header.timestamp_lo = 0;
1359 vp8_frame_header.timestamp_hi = 0;
1360 fwrite((const char *)&vp8_frame_header,
1361 sizeof(vp8_frame_header),1,m_debug.infile);
1362 }
1363 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1364 }
1365 return 0;
1366}
1367
1368int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1369 if (m_debug.out_buffer_log && !m_debug.outfile) {
1370 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1371 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1372 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1373 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001374 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001375 m_debug.outfile_name[0] = '\0';
1376 return -1;
1377 }
1378 }
1379 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1380 int buf_index = buffer - m_out_mem_ptr;
1381 int stride = drv_ctx.video_resolution.stride;
1382 int scanlines = drv_ctx.video_resolution.scan_lines;
1383 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1384 unsigned i;
1385 int bytes_written = 0;
1386 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1387 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1388 temp += stride;
1389 }
1390 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1391 int stride_c = stride;
1392 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1393 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1394 temp += stride_c;
1395 }
1396 }
1397 return 0;
1398}
1399
Shalaj Jain273b3e02012-06-22 19:08:03 -07001400/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001401 FUNCTION
1402 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001403
Arun Menon906de572013-06-18 17:01:40 -07001404 DESCRIPTION
1405 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001406
Arun Menon906de572013-06-18 17:01:40 -07001407 PARAMETERS
1408 ctxt -- Context information related to the self.
1409 id -- Event identifier. This could be any of the following:
1410 1. Command completion event
1411 2. Buffer done callback event
1412 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001413
Arun Menon906de572013-06-18 17:01:40 -07001414 RETURN VALUE
1415 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001416
Arun Menon906de572013-06-18 17:01:40 -07001417 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1419{
1420
Arun Menon906de572013-06-18 17:01:40 -07001421 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1422 struct v4l2_fmtdesc fdesc;
1423 struct v4l2_format fmt;
1424 struct v4l2_requestbuffers bufreq;
1425 struct v4l2_control control;
1426 struct v4l2_frmsizeenum frmsize;
1427 unsigned int alignment = 0,buffer_size = 0;
1428 int fds[2];
1429 int r,ret=0;
1430 bool codec_ambiguous = false;
1431 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001432
1433#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001434 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001435 property_get("ro.board.platform", platform_name, "0");
1436 if (!strncmp(platform_name, "msm8610", 7)) {
1437 device_name = (OMX_STRING)"/dev/video/q6_dec";
1438 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001439#endif
1440
Arun Menon906de572013-06-18 17:01:40 -07001441 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1442 struct v4l2_control control;
1443 secure_mode = true;
1444 arbitrary_bytes = false;
1445 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301446 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1447 OMX_MAX_STRINGNAME_SIZE)){
1448 secure_mode = true;
1449 arbitrary_bytes = false;
1450 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001451 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001452
Arun Menon906de572013-06-18 17:01:40 -07001453 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001455 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001456 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457
Arun Menon906de572013-06-18 17:01:40 -07001458 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001459 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001460 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1461 close(0);
1462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001463
Arun Menon906de572013-06-18 17:01:40 -07001464 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001465 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001466 return OMX_ErrorInsufficientResources;
1467 }
1468 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1469 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001470
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001471 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001472 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001473 async_thread_created = true;
1474 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1475 }
1476 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001477 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001478 async_thread_created = false;
1479 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001481
Shalaj Jain273b3e02012-06-22 19:08:03 -07001482#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001483 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001484#endif
1485
Arun Menon906de572013-06-18 17:01:40 -07001486 // Copy the role information which provides the decoder kind
1487 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001488
Arun Menon906de572013-06-18 17:01:40 -07001489 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1490 OMX_MAX_STRINGNAME_SIZE)) {
1491 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1492 OMX_MAX_STRINGNAME_SIZE);
1493 drv_ctx.timestamp_adjust = true;
1494 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1495 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1496 output_capability=V4L2_PIX_FMT_MPEG4;
1497 /*Initialize Start Code for MPEG4*/
1498 codec_type_parse = CODEC_TYPE_MPEG4;
1499 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001500 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1501 OMX_MAX_STRINGNAME_SIZE)) {
1502 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1503 OMX_MAX_STRINGNAME_SIZE);
1504 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1505 output_capability = V4L2_PIX_FMT_MPEG2;
1506 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1507 /*Initialize Start Code for MPEG2*/
1508 codec_type_parse = CODEC_TYPE_MPEG2;
1509 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001510 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1511 OMX_MAX_STRINGNAME_SIZE)) {
1512 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001513 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001514 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1515 eCompressionFormat = OMX_VIDEO_CodingH263;
1516 output_capability = V4L2_PIX_FMT_H263;
1517 codec_type_parse = CODEC_TYPE_H263;
1518 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001519 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1520 OMX_MAX_STRINGNAME_SIZE)) {
1521 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001522 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001523 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1524 output_capability = V4L2_PIX_FMT_DIVX_311;
1525 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1526 codec_type_parse = CODEC_TYPE_DIVX;
1527 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001528
Arun Menon906de572013-06-18 17:01:40 -07001529 eRet = createDivxDrmContext();
1530 if (eRet != OMX_ErrorNone) {
1531 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1532 return eRet;
1533 }
1534 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1535 OMX_MAX_STRINGNAME_SIZE)) {
1536 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001537 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001538 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1539 output_capability = V4L2_PIX_FMT_DIVX;
1540 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1541 codec_type_parse = CODEC_TYPE_DIVX;
1542 codec_ambiguous = true;
1543 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001544
Arun Menon906de572013-06-18 17:01:40 -07001545 eRet = createDivxDrmContext();
1546 if (eRet != OMX_ErrorNone) {
1547 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1548 return eRet;
1549 }
1550 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1551 OMX_MAX_STRINGNAME_SIZE)) {
1552 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001553 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001554 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);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001560
Arun Menon906de572013-06-18 17:01:40 -07001561 eRet = createDivxDrmContext();
1562 if (eRet != OMX_ErrorNone) {
1563 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1564 return eRet;
1565 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001566
Arun Menon906de572013-06-18 17:01:40 -07001567 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1568 OMX_MAX_STRINGNAME_SIZE)) {
1569 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1570 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1571 output_capability=V4L2_PIX_FMT_H264;
1572 eCompressionFormat = OMX_VIDEO_CodingAVC;
1573 codec_type_parse = CODEC_TYPE_H264;
1574 m_frame_parser.init_start_codes (codec_type_parse);
1575 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001576 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1577 OMX_MAX_STRINGNAME_SIZE)) {
1578 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1579 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1580 eCompressionFormat = OMX_VIDEO_CodingWMV;
1581 codec_type_parse = CODEC_TYPE_VC1;
1582 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1583 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001584 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1585 OMX_MAX_STRINGNAME_SIZE)) {
1586 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1587 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1588 eCompressionFormat = OMX_VIDEO_CodingWMV;
1589 codec_type_parse = CODEC_TYPE_VC1;
1590 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1591 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001592 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1593 OMX_MAX_STRINGNAME_SIZE)) {
1594 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1595 output_capability=V4L2_PIX_FMT_VP8;
1596 eCompressionFormat = OMX_VIDEO_CodingVPX;
1597 codec_type_parse = CODEC_TYPE_VP8;
1598 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001599
Arun Menon906de572013-06-18 17:01:40 -07001600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001601 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001602 eRet = OMX_ErrorInvalidComponentName;
1603 }
Arun Menon906de572013-06-18 17:01:40 -07001604 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605
Arun Menon906de572013-06-18 17:01:40 -07001606 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001607 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1608 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1609 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001610 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001611 eRet = OMX_ErrorInsufficientResources;
1612 }
1613
Arun Menon906de572013-06-18 17:01:40 -07001614 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001615
Arun Menon906de572013-06-18 17:01:40 -07001616 struct v4l2_capability cap;
1617 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1618 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001619 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001620 /*TODO: How to handle this case */
1621 } else {
1622 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001623 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001624 cap.bus_info, cap.version, cap.capabilities);
1625 }
1626 ret=0;
1627 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1628 fdesc.index=0;
1629 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001630 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001631 fdesc.pixelformat, fdesc.flags);
1632 fdesc.index++;
1633 }
1634 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1635 fdesc.index=0;
1636 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001638 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001639 fdesc.pixelformat, fdesc.flags);
1640 fdesc.index++;
1641 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001642 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001643 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1644 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1645 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1646 fmt.fmt.pix_mp.pixelformat = output_capability;
1647 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1648 if (ret) {
1649 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001650 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001651 return OMX_ErrorInsufficientResources;
1652 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001653 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001654 if (codec_ambiguous) {
1655 if (output_capability == V4L2_PIX_FMT_DIVX) {
1656 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001657
Arun Menon906de572013-06-18 17:01:40 -07001658 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1659 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1660 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1661 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1662 } else {
1663 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1664 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665
Arun Menon906de572013-06-18 17:01:40 -07001666 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1667 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1668 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001669 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001670 }
1671 } else {
1672 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1673 }
1674 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001675
Arun Menon906de572013-06-18 17:01:40 -07001676 //Get the hardware capabilities
1677 memset((void *)&frmsize,0,sizeof(frmsize));
1678 frmsize.index = 0;
1679 frmsize.pixel_format = output_capability;
1680 ret = ioctl(drv_ctx.video_driver_fd,
1681 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1682 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001683 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001684 return OMX_ErrorHardware;
1685 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001686
Arun Menon906de572013-06-18 17:01:40 -07001687 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1688 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1689 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1690 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1691 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1692 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001693
Arun Menon906de572013-06-18 17:01:40 -07001694 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1695 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1696 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1697 fmt.fmt.pix_mp.pixelformat = capture_capability;
1698 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1699 if (ret) {
1700 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001701 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001702 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001703 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001704 if (secure_mode) {
1705 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1706 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001707 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001708 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1709 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001710 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001711 return OMX_ErrorInsufficientResources;
1712 }
1713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001714
Arun Menon906de572013-06-18 17:01:40 -07001715 /*Get the Buffer requirements for input and output ports*/
1716 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1717 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1718 if (secure_mode) {
1719 drv_ctx.op_buf.alignment=SZ_1M;
1720 drv_ctx.ip_buf.alignment=SZ_1M;
1721 } else {
1722 drv_ctx.op_buf.alignment=SZ_4K;
1723 drv_ctx.ip_buf.alignment=SZ_4K;
1724 }
1725 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1726 drv_ctx.extradata = 0;
1727 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1728 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1729 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1730 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1731 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732
Vinay Kalia5713bb32013-01-16 18:39:59 -08001733 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001734#ifdef DEFAULT_EXTRADATA
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301735 if (eRet == OMX_ErrorNone)
Vinay Kalia5713bb32013-01-16 18:39:59 -08001736 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001737#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001738 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001739 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001740 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001741 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1742 if (m_frame_parser.mutils == NULL) {
1743 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001744
Arun Menon906de572013-06-18 17:01:40 -07001745 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001746 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001747 eRet = OMX_ErrorInsufficientResources;
1748 } else {
1749 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1750 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1751 h264_scratch.nFilledLen = 0;
1752 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001753
Arun Menon906de572013-06-18 17:01:40 -07001754 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001755 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001756 return OMX_ErrorInsufficientResources;
1757 }
1758 m_frame_parser.mutils->initialize_frame_checking_environment();
1759 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1760 }
1761 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001762
Arun Menon906de572013-06-18 17:01:40 -07001763 h264_parser = new h264_stream_parser();
1764 if (!h264_parser) {
1765 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1766 eRet = OMX_ErrorInsufficientResources;
1767 }
1768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001769
Arun Menon906de572013-06-18 17:01:40 -07001770 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001771 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001772 eRet = OMX_ErrorInsufficientResources;
1773 } else {
1774 int temp1[2];
1775 if (fds[0] == 0 || fds[1] == 0) {
1776 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001777 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001778 return OMX_ErrorInsufficientResources;
1779 }
1780 //close (fds[0]);
1781 //close (fds[1]);
1782 fds[0] = temp1 [0];
1783 fds[1] = temp1 [1];
1784 }
1785 m_pipe_in = fds[0];
1786 m_pipe_out = fds[1];
1787 msg_thread_created = true;
1788 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001789
Arun Menon906de572013-06-18 17:01:40 -07001790 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001791 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001792 msg_thread_created = false;
1793 eRet = OMX_ErrorInsufficientResources;
1794 }
1795 }
1796 }
1797
1798 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001799 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001800 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001801 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001802 }
1803 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1804 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805}
1806
1807/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001808 FUNCTION
1809 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001810
Arun Menon906de572013-06-18 17:01:40 -07001811 DESCRIPTION
1812 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001813
Arun Menon906de572013-06-18 17:01:40 -07001814 PARAMETERS
1815 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001816
Arun Menon906de572013-06-18 17:01:40 -07001817 RETURN VALUE
1818 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001819
Arun Menon906de572013-06-18 17:01:40 -07001820 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001821OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001822(
1823 OMX_IN OMX_HANDLETYPE hComp,
1824 OMX_OUT OMX_STRING componentName,
1825 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1826 OMX_OUT OMX_VERSIONTYPE* specVersion,
1827 OMX_OUT OMX_UUIDTYPE* componentUUID
1828 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001829{
Arun Menon906de572013-06-18 17:01:40 -07001830 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001831 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001832 return OMX_ErrorInvalidState;
1833 }
Arun Menon906de572013-06-18 17:01:40 -07001834 /* TBD -- Return the proper version */
1835 if (specVersion) {
1836 specVersion->nVersion = OMX_SPEC_VERSION;
1837 }
1838 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001839}
1840/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001841 FUNCTION
1842 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001843
Arun Menon906de572013-06-18 17:01:40 -07001844 DESCRIPTION
1845 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001846
Arun Menon906de572013-06-18 17:01:40 -07001847 PARAMETERS
1848 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849
Arun Menon906de572013-06-18 17:01:40 -07001850 RETURN VALUE
1851 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852
Arun Menon906de572013-06-18 17:01:40 -07001853 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001855 OMX_IN OMX_COMMANDTYPE cmd,
1856 OMX_IN OMX_U32 param1,
1857 OMX_IN OMX_PTR cmdData
1858 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001859{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001860 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001861 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001862 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001863 return OMX_ErrorInvalidState;
1864 }
1865 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001866 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001867 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001868 "to invalid port: %lu", param1);
1869 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001870 }
1871 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1872 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001873 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001874 return OMX_ErrorNone;
1875}
1876
1877/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001878 FUNCTION
1879 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001880
Arun Menon906de572013-06-18 17:01:40 -07001881 DESCRIPTION
1882 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001883
Arun Menon906de572013-06-18 17:01:40 -07001884 PARAMETERS
1885 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001886
Arun Menon906de572013-06-18 17:01:40 -07001887 RETURN VALUE
1888 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001889
Arun Menon906de572013-06-18 17:01:40 -07001890 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001892 OMX_IN OMX_COMMANDTYPE cmd,
1893 OMX_IN OMX_U32 param1,
1894 OMX_IN OMX_PTR cmdData
1895 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001896{
Arun Menon906de572013-06-18 17:01:40 -07001897 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1898 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1899 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001900
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001901 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1902 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001903 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001904
Arun Menon906de572013-06-18 17:01:40 -07001905 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001906 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1907 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001908 /***************************/
1909 /* Current State is Loaded */
1910 /***************************/
1911 if (m_state == OMX_StateLoaded) {
1912 if (eState == OMX_StateIdle) {
1913 //if all buffers are allocated or all ports disabled
1914 if (allocate_done() ||
1915 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001916 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001917 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001918 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001919 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1920 // Skip the event notification
1921 bFlag = 0;
1922 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001923 }
Arun Menon906de572013-06-18 17:01:40 -07001924 /* Requesting transition from Loaded to Loaded */
1925 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001926 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001927 post_event(OMX_EventError,OMX_ErrorSameState,\
1928 OMX_COMPONENT_GENERATE_EVENT);
1929 eRet = OMX_ErrorSameState;
1930 }
1931 /* Requesting transition from Loaded to WaitForResources */
1932 else if (eState == OMX_StateWaitForResources) {
1933 /* Since error is None , we will post an event
1934 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001935 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001936 }
1937 /* Requesting transition from Loaded to Executing */
1938 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001939 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001940 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1941 OMX_COMPONENT_GENERATE_EVENT);
1942 eRet = OMX_ErrorIncorrectStateTransition;
1943 }
1944 /* Requesting transition from Loaded to Pause */
1945 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001946 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001947 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1948 OMX_COMPONENT_GENERATE_EVENT);
1949 eRet = OMX_ErrorIncorrectStateTransition;
1950 }
1951 /* Requesting transition from Loaded to Invalid */
1952 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001953 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001954 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1955 eRet = OMX_ErrorInvalidState;
1956 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001957 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001958 eState);
1959 eRet = OMX_ErrorBadParameter;
1960 }
1961 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001962
Arun Menon906de572013-06-18 17:01:40 -07001963 /***************************/
1964 /* Current State is IDLE */
1965 /***************************/
1966 else if (m_state == OMX_StateIdle) {
1967 if (eState == OMX_StateLoaded) {
1968 if (release_done()) {
1969 /*
1970 Since error is None , we will post an event at the end
1971 of this function definition
1972 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001973 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001974 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001975 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001976 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1977 // Skip the event notification
1978 bFlag = 0;
1979 }
1980 }
1981 /* Requesting transition from Idle to Executing */
1982 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001983 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001984 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1985 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001986 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001987 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001988 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07001989 }
1990 /* Requesting transition from Idle to Idle */
1991 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001993 post_event(OMX_EventError,OMX_ErrorSameState,\
1994 OMX_COMPONENT_GENERATE_EVENT);
1995 eRet = OMX_ErrorSameState;
1996 }
1997 /* Requesting transition from Idle to WaitForResources */
1998 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001999 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002000 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2001 OMX_COMPONENT_GENERATE_EVENT);
2002 eRet = OMX_ErrorIncorrectStateTransition;
2003 }
2004 /* Requesting transition from Idle to Pause */
2005 else if (eState == OMX_StatePause) {
2006 /*To pause the Video core we need to start the driver*/
2007 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2008 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002009 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002010 omx_report_error ();
2011 eRet = OMX_ErrorHardware;
2012 } else {
2013 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002015 bFlag = 0;
2016 }
2017 }
2018 /* Requesting transition from Idle to Invalid */
2019 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002020 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002021 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2022 eRet = OMX_ErrorInvalidState;
2023 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002024 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002025 eRet = OMX_ErrorBadParameter;
2026 }
2027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002028
Arun Menon906de572013-06-18 17:01:40 -07002029 /******************************/
2030 /* Current State is Executing */
2031 /******************************/
2032 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002033 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002034 /* Requesting transition from Executing to Idle */
2035 if (eState == OMX_StateIdle) {
2036 /* Since error is None , we will post an event
2037 at the end of this function definition
2038 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002039 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002040 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2041 if (!sem_posted) {
2042 sem_posted = 1;
2043 sem_post (&m_cmd_lock);
2044 execute_omx_flush(OMX_ALL);
2045 }
2046 bFlag = 0;
2047 }
2048 /* Requesting transition from Executing to Paused */
2049 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002050 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002051 m_state = OMX_StatePause;
2052 bFlag = 1;
2053 }
2054 /* Requesting transition from Executing to Loaded */
2055 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002056 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002057 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2058 OMX_COMPONENT_GENERATE_EVENT);
2059 eRet = OMX_ErrorIncorrectStateTransition;
2060 }
2061 /* Requesting transition from Executing to WaitForResources */
2062 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002063 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002064 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2065 OMX_COMPONENT_GENERATE_EVENT);
2066 eRet = OMX_ErrorIncorrectStateTransition;
2067 }
2068 /* Requesting transition from Executing to Executing */
2069 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002070 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002071 post_event(OMX_EventError,OMX_ErrorSameState,\
2072 OMX_COMPONENT_GENERATE_EVENT);
2073 eRet = OMX_ErrorSameState;
2074 }
2075 /* Requesting transition from Executing to Invalid */
2076 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002077 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002078 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2079 eRet = OMX_ErrorInvalidState;
2080 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002081 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002082 eRet = OMX_ErrorBadParameter;
2083 }
2084 }
2085 /***************************/
2086 /* Current State is Pause */
2087 /***************************/
2088 else if (m_state == OMX_StatePause) {
2089 /* Requesting transition from Pause to Executing */
2090 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002091 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002092 m_state = OMX_StateExecuting;
2093 bFlag = 1;
2094 }
2095 /* Requesting transition from Pause to Idle */
2096 else if (eState == OMX_StateIdle) {
2097 /* Since error is None , we will post an event
2098 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002099 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002100 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2101 if (!sem_posted) {
2102 sem_posted = 1;
2103 sem_post (&m_cmd_lock);
2104 execute_omx_flush(OMX_ALL);
2105 }
2106 bFlag = 0;
2107 }
2108 /* Requesting transition from Pause to loaded */
2109 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002110 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002111 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2112 OMX_COMPONENT_GENERATE_EVENT);
2113 eRet = OMX_ErrorIncorrectStateTransition;
2114 }
2115 /* Requesting transition from Pause to WaitForResources */
2116 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002117 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002118 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2119 OMX_COMPONENT_GENERATE_EVENT);
2120 eRet = OMX_ErrorIncorrectStateTransition;
2121 }
2122 /* Requesting transition from Pause to Pause */
2123 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002124 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002125 post_event(OMX_EventError,OMX_ErrorSameState,\
2126 OMX_COMPONENT_GENERATE_EVENT);
2127 eRet = OMX_ErrorSameState;
2128 }
2129 /* Requesting transition from Pause to Invalid */
2130 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002131 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002132 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2133 eRet = OMX_ErrorInvalidState;
2134 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002135 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002136 eRet = OMX_ErrorBadParameter;
2137 }
2138 }
2139 /***************************/
2140 /* Current State is WaitForResources */
2141 /***************************/
2142 else if (m_state == OMX_StateWaitForResources) {
2143 /* Requesting transition from WaitForResources to Loaded */
2144 if (eState == OMX_StateLoaded) {
2145 /* Since error is None , we will post an event
2146 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002147 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002148 }
2149 /* Requesting transition from WaitForResources to WaitForResources */
2150 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002151 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002152 post_event(OMX_EventError,OMX_ErrorSameState,
2153 OMX_COMPONENT_GENERATE_EVENT);
2154 eRet = OMX_ErrorSameState;
2155 }
2156 /* Requesting transition from WaitForResources to Executing */
2157 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002158 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002159 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2160 OMX_COMPONENT_GENERATE_EVENT);
2161 eRet = OMX_ErrorIncorrectStateTransition;
2162 }
2163 /* Requesting transition from WaitForResources to Pause */
2164 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002165 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002166 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2167 OMX_COMPONENT_GENERATE_EVENT);
2168 eRet = OMX_ErrorIncorrectStateTransition;
2169 }
2170 /* Requesting transition from WaitForResources to Invalid */
2171 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002172 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002173 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorInvalidState;
2175 }
2176 /* Requesting transition from WaitForResources to Loaded -
2177 is NOT tested by Khronos TS */
2178
2179 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002180 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002181 eRet = OMX_ErrorBadParameter;
2182 }
2183 }
2184 /********************************/
2185 /* Current State is Invalid */
2186 /*******************************/
2187 else if (m_state == OMX_StateInvalid) {
2188 /* State Transition from Inavlid to any state */
2189 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2190 || OMX_StateIdle || OMX_StateExecuting
2191 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002192 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002193 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2194 OMX_COMPONENT_GENERATE_EVENT);
2195 eRet = OMX_ErrorInvalidState;
2196 }
2197 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002198 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002199 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002200#ifdef _MSM8974_
2201 send_codec_config();
2202#endif
Arun Menon906de572013-06-18 17:01:40 -07002203 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2204 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2205 }
2206 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2207 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2208 }
2209 if (!sem_posted) {
2210 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002212 sem_post (&m_cmd_lock);
2213 execute_omx_flush(param1);
2214 }
2215 bFlag = 0;
2216 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002217 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002218 "with param1: %lu", param1);
2219 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2220 m_inp_bEnabled = OMX_TRUE;
2221
2222 if ( (m_state == OMX_StateLoaded &&
2223 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2224 || allocate_input_done()) {
2225 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2226 OMX_COMPONENT_GENERATE_EVENT);
2227 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002228 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002229 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2230 // Skip the event notification
2231 bFlag = 0;
2232 }
2233 }
2234 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002235 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002236 m_out_bEnabled = OMX_TRUE;
2237
2238 if ( (m_state == OMX_StateLoaded &&
2239 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2240 || (allocate_output_done())) {
2241 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2242 OMX_COMPONENT_GENERATE_EVENT);
2243
2244 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002245 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002246 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2247 // Skip the event notification
2248 bFlag = 0;
2249 }
2250 }
2251 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002252 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002253 "with param1: %lu", param1);
2254 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002255 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002256 m_inp_bEnabled = OMX_FALSE;
2257 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2258 && release_input_done()) {
2259 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2260 OMX_COMPONENT_GENERATE_EVENT);
2261 } else {
2262 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2263 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2264 if (!sem_posted) {
2265 sem_posted = 1;
2266 sem_post (&m_cmd_lock);
2267 }
2268 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2269 }
2270
2271 // Skip the event notification
2272 bFlag = 0;
2273 }
2274 }
2275 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2276 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002277 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002278 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2279 && release_output_done()) {
2280 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2281 OMX_COMPONENT_GENERATE_EVENT);
2282 } else {
2283 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2284 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2285 if (!sem_posted) {
2286 sem_posted = 1;
2287 sem_post (&m_cmd_lock);
2288 }
2289 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2290 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2291 }
2292 // Skip the event notification
2293 bFlag = 0;
2294
2295 }
2296 }
2297 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002298 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002299 eRet = OMX_ErrorNotImplemented;
2300 }
2301 if (eRet == OMX_ErrorNone && bFlag) {
2302 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2303 }
2304 if (!sem_posted) {
2305 sem_post(&m_cmd_lock);
2306 }
2307
2308 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002309}
2310
2311/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002312 FUNCTION
2313 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002314
Arun Menon906de572013-06-18 17:01:40 -07002315 DESCRIPTION
2316 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002317
Arun Menon906de572013-06-18 17:01:40 -07002318 PARAMETERS
2319 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002320
Arun Menon906de572013-06-18 17:01:40 -07002321 RETURN VALUE
2322 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002323
Arun Menon906de572013-06-18 17:01:40 -07002324 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002325bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2326{
Arun Menon906de572013-06-18 17:01:40 -07002327 bool bRet = false;
2328 struct v4l2_plane plane;
2329 struct v4l2_buffer v4l2_buf;
2330 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302331 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002332 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2333 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002334
Arun Menon906de572013-06-18 17:01:40 -07002335 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002336
Arun Menon906de572013-06-18 17:01:40 -07002337 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2338 output_flush_progress = true;
2339 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2340 } else {
2341 /* XXX: The driver/hardware does not support flushing of individual ports
2342 * in all states. So we pretty much need to flush both ports internally,
2343 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2344 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2345 * we automatically omit sending the FLUSH done for the "opposite" port. */
2346 input_flush_progress = true;
2347 output_flush_progress = true;
2348 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2349 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002350
Arun Menon906de572013-06-18 17:01:40 -07002351 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002352 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002353 bRet = false;
2354 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002355
Arun Menon906de572013-06-18 17:01:40 -07002356 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002357}
2358/*=========================================================================
2359FUNCTION : execute_output_flush
2360
2361DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002362Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002363
2364PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002365None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002366
2367RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002368true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002369==========================================================================*/
2370bool omx_vdec::execute_output_flush()
2371{
Arun Menon906de572013-06-18 17:01:40 -07002372 unsigned p1 = 0; // Parameter - 1
2373 unsigned p2 = 0; // Parameter - 2
2374 unsigned ident = 0;
2375 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002376
Arun Menon906de572013-06-18 17:01:40 -07002377 /*Generate FBD for all Buffers in the FTBq*/
2378 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002379 DEBUG_PRINT_LOW("Initiate Output Flush");
Arun Menon906de572013-06-18 17:01:40 -07002380 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002381 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002382 m_ftb_q.m_size,pending_output_buffers);
2383 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002384 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002385 if (ident == m_fill_output_msg ) {
2386 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2387 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2388 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002390 }
Arun Menon906de572013-06-18 17:01:40 -07002391 pthread_mutex_unlock(&m_lock);
2392 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002393
Arun Menon906de572013-06-18 17:01:40 -07002394 if (arbitrary_bytes) {
2395 prev_ts = LLONG_MAX;
2396 rst_prev_ts = true;
2397 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002398 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002399 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400}
2401/*=========================================================================
2402FUNCTION : execute_input_flush
2403
2404DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002405Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002406
2407PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002408None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002409
2410RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002411true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002412==========================================================================*/
2413bool omx_vdec::execute_input_flush()
2414{
Arun Menon906de572013-06-18 17:01:40 -07002415 unsigned i =0;
2416 unsigned p1 = 0; // Parameter - 1
2417 unsigned p2 = 0; // Parameter - 2
2418 unsigned ident = 0;
2419 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002420
Arun Menon906de572013-06-18 17:01:40 -07002421 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002422 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002423
Arun Menon906de572013-06-18 17:01:40 -07002424 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002425 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002426 while (m_etb_q.m_size) {
2427 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002428
Arun Menon906de572013-06-18 17:01:40 -07002429 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002430 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002431 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2432 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2433 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002434 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002435 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2436 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2437 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002438 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002439 (OMX_BUFFERHEADERTYPE *)p1);
2440 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002442 }
Arun Menon906de572013-06-18 17:01:40 -07002443 time_stamp_dts.flush_timestamp();
2444 /*Check if Heap Buffers are to be flushed*/
2445 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002446 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002447 h264_scratch.nFilledLen = 0;
2448 nal_count = 0;
2449 look_ahead_nal = false;
2450 frame_count = 0;
2451 h264_last_au_ts = LLONG_MAX;
2452 h264_last_au_flags = 0;
2453 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2454 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002455 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002456 if (m_frame_parser.mutils) {
2457 m_frame_parser.mutils->initialize_frame_checking_environment();
2458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459
Arun Menon906de572013-06-18 17:01:40 -07002460 while (m_input_pending_q.m_size) {
2461 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2462 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2463 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002464
Arun Menon906de572013-06-18 17:01:40 -07002465 if (psource_frame) {
2466 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2467 psource_frame = NULL;
2468 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002469
Arun Menon906de572013-06-18 17:01:40 -07002470 if (pdest_frame) {
2471 pdest_frame->nFilledLen = 0;
2472 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2473 (unsigned int)NULL);
2474 pdest_frame = NULL;
2475 }
2476 m_frame_parser.flush();
2477 } else if (codec_config_flag) {
2478 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2479 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002480 }
Arun Menon906de572013-06-18 17:01:40 -07002481 pthread_mutex_unlock(&m_lock);
2482 input_flush_progress = false;
2483 if (!arbitrary_bytes) {
2484 prev_ts = LLONG_MAX;
2485 rst_prev_ts = true;
2486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002488 if (m_debug_timestamp) {
2489 m_timestamp_list.reset_ts_list();
2490 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002491#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002492 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002493 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002494}
2495
2496
2497/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002498 FUNCTION
2499 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002500
Arun Menon906de572013-06-18 17:01:40 -07002501 DESCRIPTION
2502 Send the event to decoder pipe. This is needed to generate the callbacks
2503 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504
Arun Menon906de572013-06-18 17:01:40 -07002505 PARAMETERS
2506 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002507
Arun Menon906de572013-06-18 17:01:40 -07002508 RETURN VALUE
2509 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002510
Arun Menon906de572013-06-18 17:01:40 -07002511 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002512bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002513 unsigned int p2,
2514 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002515{
Arun Menon906de572013-06-18 17:01:40 -07002516 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002517
2518
Arun Menon906de572013-06-18 17:01:40 -07002519 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002520
Arun Menon906de572013-06-18 17:01:40 -07002521 if (id == m_fill_output_msg ||
2522 id == OMX_COMPONENT_GENERATE_FBD) {
2523 m_ftb_q.insert_entry(p1,p2,id);
2524 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2525 id == OMX_COMPONENT_GENERATE_EBD ||
2526 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2527 m_etb_q.insert_entry(p1,p2,id);
2528 } else {
2529 m_cmd_q.insert_entry(p1,p2,id);
2530 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531
Arun Menon906de572013-06-18 17:01:40 -07002532 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002533 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002534 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002535
Arun Menon906de572013-06-18 17:01:40 -07002536 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537
Arun Menon906de572013-06-18 17:01:40 -07002538 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002539}
2540
2541OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2542{
Arun Menon906de572013-06-18 17:01:40 -07002543 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2544 if (!profileLevelType)
2545 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002546
Arun Menon906de572013-06-18 17:01:40 -07002547 if (profileLevelType->nPortIndex == 0) {
2548 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2549 if (profileLevelType->nProfileIndex == 0) {
2550 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2551 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002552
Arun Menon906de572013-06-18 17:01:40 -07002553 } else if (profileLevelType->nProfileIndex == 1) {
2554 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2555 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2556 } else if (profileLevelType->nProfileIndex == 2) {
2557 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2558 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2559 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002560 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002561 profileLevelType->nProfileIndex);
2562 eRet = OMX_ErrorNoMore;
2563 }
2564 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2565 if (profileLevelType->nProfileIndex == 0) {
2566 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2567 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2568 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002569 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002570 eRet = OMX_ErrorNoMore;
2571 }
2572 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2573 if (profileLevelType->nProfileIndex == 0) {
2574 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2575 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2576 } else if (profileLevelType->nProfileIndex == 1) {
2577 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2578 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2579 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002580 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002581 eRet = OMX_ErrorNoMore;
2582 }
2583 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2584 eRet = OMX_ErrorNoMore;
2585 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2586 if (profileLevelType->nProfileIndex == 0) {
2587 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2588 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2589 } else if (profileLevelType->nProfileIndex == 1) {
2590 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2591 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2592 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002593 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002594 eRet = OMX_ErrorNoMore;
2595 }
2596 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002597 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002598 eRet = OMX_ErrorNoMore;
2599 }
2600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002601 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002602 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002603 }
Arun Menon906de572013-06-18 17:01:40 -07002604 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002605}
2606
2607/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002608 FUNCTION
2609 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 DESCRIPTION
2612 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002613
Arun Menon906de572013-06-18 17:01:40 -07002614 PARAMETERS
2615 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002616
Arun Menon906de572013-06-18 17:01:40 -07002617 RETURN VALUE
2618 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002619
Arun Menon906de572013-06-18 17:01:40 -07002620 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002621OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002622 OMX_IN OMX_INDEXTYPE paramIndex,
2623 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002624{
2625 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2626
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002627 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002628 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002629 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630 return OMX_ErrorInvalidState;
2631 }
Arun Menon906de572013-06-18 17:01:40 -07002632 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002633 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002634 return OMX_ErrorBadParameter;
2635 }
Arun Menon906de572013-06-18 17:01:40 -07002636 switch ((unsigned long)paramIndex) {
2637 case OMX_IndexParamPortDefinition: {
2638 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2639 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002641 eRet = update_portdef(portDefn);
2642 if (eRet == OMX_ErrorNone)
2643 m_port_def = *portDefn;
2644 break;
2645 }
2646 case OMX_IndexParamVideoInit: {
2647 OMX_PORT_PARAM_TYPE *portParamType =
2648 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002649 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002650
Arun Menon906de572013-06-18 17:01:40 -07002651 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2652 portParamType->nSize = sizeof(portParamType);
2653 portParamType->nPorts = 2;
2654 portParamType->nStartPortNumber = 0;
2655 break;
2656 }
2657 case OMX_IndexParamVideoPortFormat: {
2658 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2659 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002660 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002661
Arun Menon906de572013-06-18 17:01:40 -07002662 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2663 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002664
Arun Menon906de572013-06-18 17:01:40 -07002665 if (0 == portFmt->nPortIndex) {
2666 if (0 == portFmt->nIndex) {
2667 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2668 portFmt->eCompressionFormat = eCompressionFormat;
2669 } else {
2670 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002671 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002672 eRet = OMX_ErrorNoMore;
2673 }
2674 } else if (1 == portFmt->nPortIndex) {
2675 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002676
Arun Menon906de572013-06-18 17:01:40 -07002677 if (0 == portFmt->nIndex)
2678 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2679 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2680 else if (1 == portFmt->nIndex)
2681 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2682 else {
2683 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002684 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002685 eRet = OMX_ErrorNoMore;
2686 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002687 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002688 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002689 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002690 (int)portFmt->nPortIndex);
2691 eRet = OMX_ErrorBadPortIndex;
2692 }
2693 break;
2694 }
2695 /*Component should support this port definition*/
2696 case OMX_IndexParamAudioInit: {
2697 OMX_PORT_PARAM_TYPE *audioPortParamType =
2698 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002699 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002700 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2701 audioPortParamType->nSize = sizeof(audioPortParamType);
2702 audioPortParamType->nPorts = 0;
2703 audioPortParamType->nStartPortNumber = 0;
2704 break;
2705 }
2706 /*Component should support this port definition*/
2707 case OMX_IndexParamImageInit: {
2708 OMX_PORT_PARAM_TYPE *imagePortParamType =
2709 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002710 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002711 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2712 imagePortParamType->nSize = sizeof(imagePortParamType);
2713 imagePortParamType->nPorts = 0;
2714 imagePortParamType->nStartPortNumber = 0;
2715 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002716
Arun Menon906de572013-06-18 17:01:40 -07002717 }
2718 /*Component should support this port definition*/
2719 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002720 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002721 paramIndex);
2722 eRet =OMX_ErrorUnsupportedIndex;
2723 break;
2724 }
2725 case OMX_IndexParamStandardComponentRole: {
2726 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2727 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2728 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2729 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002730
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002731 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002732 paramIndex);
2733 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2734 OMX_MAX_STRINGNAME_SIZE);
2735 break;
2736 }
2737 /* Added for parameter test */
2738 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002739
Arun Menon906de572013-06-18 17:01:40 -07002740 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2741 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002742 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002743 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2744 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002745
Arun Menon906de572013-06-18 17:01:40 -07002746 break;
2747 }
2748 /* Added for parameter test */
2749 case OMX_IndexParamCompBufferSupplier: {
2750 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2751 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002752 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002753
Arun Menon906de572013-06-18 17:01:40 -07002754 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2755 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2756 if (0 == bufferSupplierType->nPortIndex)
2757 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2758 else if (1 == bufferSupplierType->nPortIndex)
2759 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2760 else
2761 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002762
2763
Arun Menon906de572013-06-18 17:01:40 -07002764 break;
2765 }
2766 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002767 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002768 paramIndex);
2769 break;
2770 }
2771 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002772 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002773 paramIndex);
2774 break;
2775 }
2776 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002777 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002778 paramIndex);
2779 break;
2780 }
2781 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002782 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002783 paramIndex);
2784 break;
2785 }
2786 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002787 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002788 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2789 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2790 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2791 break;
2792 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002793#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002794 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002795 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002796 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2797 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798
Arun Menon906de572013-06-18 17:01:40 -07002799 if (secure_mode) {
2800 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2801 GRALLOC_USAGE_PRIVATE_UNCACHED);
2802 } else {
2803 nativeBuffersUsage->nUsage =
2804 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2805 GRALLOC_USAGE_PRIVATE_UNCACHED);
2806 }
2807 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002808 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002809 eRet = OMX_ErrorBadParameter;
2810 }
2811 }
2812 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813#endif
2814
Arun Menon906de572013-06-18 17:01:40 -07002815 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002816 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002817 eRet =OMX_ErrorUnsupportedIndex;
2818 }
2819
Shalaj Jain273b3e02012-06-22 19:08:03 -07002820 }
2821
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002822 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002823 drv_ctx.video_resolution.frame_width,
2824 drv_ctx.video_resolution.frame_height,
2825 drv_ctx.video_resolution.stride,
2826 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002827
Arun Menon906de572013-06-18 17:01:40 -07002828 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002829}
2830
2831#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2832OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2833{
2834 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2835 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2836 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2837
Arun Menon906de572013-06-18 17:01:40 -07002838 if ((params == NULL) ||
2839 (params->nativeBuffer == NULL) ||
2840 (params->nativeBuffer->handle == NULL) ||
2841 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842 return OMX_ErrorBadParameter;
2843 m_use_android_native_buffers = OMX_TRUE;
2844 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2845 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002846 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
Shalaj Jain273b3e02012-06-22 19:08:03 -07002847 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002848 if (!secure_mode) {
2849 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002850 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002851 if (buffer == MAP_FAILED) {
2852 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2853 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002854 }
2855 }
2856 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2857 } else {
2858 eRet = OMX_ErrorBadParameter;
2859 }
2860 return eRet;
2861}
2862#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002863
2864OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2865 struct v4l2_control control;
2866 struct v4l2_format fmt;
2867 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2868 control.value = 1;
2869 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2870 if (rc < 0) {
2871 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2872 return OMX_ErrorHardware;
2873 }
2874 m_smoothstreaming_mode = true;
2875 return OMX_ErrorNone;
2876}
2877
Shalaj Jain273b3e02012-06-22 19:08:03 -07002878/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002879 FUNCTION
2880 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002881
Arun Menon906de572013-06-18 17:01:40 -07002882 DESCRIPTION
2883 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002884
Arun Menon906de572013-06-18 17:01:40 -07002885 PARAMETERS
2886 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002887
Arun Menon906de572013-06-18 17:01:40 -07002888 RETURN VALUE
2889 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002890
Arun Menon906de572013-06-18 17:01:40 -07002891 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002892OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002893 OMX_IN OMX_INDEXTYPE paramIndex,
2894 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002895{
2896 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002897 int ret=0;
2898 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002899 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002900 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002901 return OMX_ErrorInvalidState;
2902 }
Arun Menon906de572013-06-18 17:01:40 -07002903 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002904 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002905 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002906 }
Arun Menon906de572013-06-18 17:01:40 -07002907 if ((m_state != OMX_StateLoaded) &&
2908 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2909 (m_out_bEnabled == OMX_TRUE) &&
2910 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2911 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002912 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002913 return OMX_ErrorIncorrectStateOperation;
2914 }
Arun Menon906de572013-06-18 17:01:40 -07002915 switch ((unsigned long)paramIndex) {
2916 case OMX_IndexParamPortDefinition: {
2917 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2918 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2919 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2920 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002921 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002922 (int)portDefn->format.video.nFrameHeight,
2923 (int)portDefn->format.video.nFrameWidth);
2924 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002925 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002926 m_display_id = portDefn->format.video.pNativeWindow;
2927 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002928 /* update output port resolution with client supplied dimensions
2929 in case scaling is enabled, else it follows input resolution set
2930 */
2931 if (is_down_scalar_enabled) {
2932 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002933 portDefn->format.video.nFrameWidth,
2934 portDefn->format.video.nFrameHeight);
2935 if (portDefn->format.video.nFrameHeight != 0x0 &&
2936 portDefn->format.video.nFrameWidth != 0x0) {
2937 update_resolution(portDefn->format.video.nFrameWidth,
2938 portDefn->format.video.nFrameHeight,
2939 portDefn->format.video.nFrameWidth,
2940 portDefn->format.video.nFrameHeight);
2941 eRet = is_video_session_supported();
2942 if (eRet)
2943 break;
2944 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2945 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2946 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2947 fmt.fmt.pix_mp.pixelformat = capture_capability;
2948 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);
2949 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2950 if (ret) {
2951 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2952 eRet = OMX_ErrorUnsupportedSetting;
2953 } else
2954 eRet = get_buffer_req(&drv_ctx.op_buf);
2955 }
Praveen Chavane78460c2013-12-06 23:16:04 -08002956 }
Arun Menon906de572013-06-18 17:01:40 -07002957 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002958 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07002959 eRet = OMX_ErrorBadParameter;
2960 } else {
2961 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2962 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2963 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2964 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2965 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2966 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2967 drv_ctx.extradata_info.buffer_size;
2968 eRet = set_buffer_req(&drv_ctx.op_buf);
2969 if (eRet == OMX_ErrorNone)
2970 m_port_def = *portDefn;
2971 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002972 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07002973 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2974 portDefn->nBufferCountActual, portDefn->nBufferSize);
2975 eRet = OMX_ErrorBadParameter;
2976 }
2977 }
2978 } else if (OMX_DirInput == portDefn->eDir) {
2979 bool port_format_changed = false;
2980 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2981 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2982 // Frame rate only should be set if this is a "known value" or to
2983 // activate ts prediction logic (arbitrary mode only) sending input
2984 // timestamps with max value (LLONG_MAX).
2985 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2986 portDefn->format.video.xFramerate >> 16);
2987 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2988 drv_ctx.frame_rate.fps_denominator);
2989 if (!drv_ctx.frame_rate.fps_numerator) {
2990 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2991 drv_ctx.frame_rate.fps_numerator = 30;
2992 }
2993 if (drv_ctx.frame_rate.fps_denominator)
2994 drv_ctx.frame_rate.fps_numerator = (int)
2995 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2996 drv_ctx.frame_rate.fps_denominator = 1;
2997 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2998 drv_ctx.frame_rate.fps_numerator;
2999 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3000 frm_int, drv_ctx.frame_rate.fps_numerator /
3001 (float)drv_ctx.frame_rate.fps_denominator);
3002 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003003 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003004 if (drv_ctx.video_resolution.frame_height !=
3005 portDefn->format.video.nFrameHeight ||
3006 drv_ctx.video_resolution.frame_width !=
3007 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003008 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003009 portDefn->format.video.nFrameWidth,
3010 portDefn->format.video.nFrameHeight);
3011 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003012 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3013 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3014 if (frameHeight != 0x0 && frameWidth != 0x0) {
3015 if (m_smoothstreaming_mode &&
3016 ((frameWidth * frameHeight) <
3017 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3018 frameWidth = m_smoothstreaming_width;
3019 frameHeight = m_smoothstreaming_height;
3020 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3021 frameWidth, frameHeight);
3022 }
3023 update_resolution(frameWidth, frameHeight,
3024 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003025 eRet = is_video_session_supported();
3026 if (eRet)
3027 break;
3028 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3029 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3030 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3031 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003032 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
Arun Menon906de572013-06-18 17:01:40 -07003033 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3034 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003035 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003036 eRet = OMX_ErrorUnsupportedSetting;
3037 } else
3038 eRet = get_buffer_req(&drv_ctx.op_buf);
3039 }
3040 }
3041 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3042 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3043 port_format_changed = true;
3044 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3045 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3046 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3047 (~(buffer_prop->alignment - 1));
3048 eRet = set_buffer_req(buffer_prop);
3049 }
3050 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003051 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003052 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3053 portDefn->nBufferCountActual, portDefn->nBufferSize);
3054 eRet = OMX_ErrorBadParameter;
3055 }
3056 } else if (portDefn->eDir == OMX_DirMax) {
3057 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3058 (int)portDefn->nPortIndex);
3059 eRet = OMX_ErrorBadPortIndex;
3060 }
3061 }
3062 break;
3063 case OMX_IndexParamVideoPortFormat: {
3064 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3065 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3066 int ret=0;
3067 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003068 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003069 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003070
Arun Menon906de572013-06-18 17:01:40 -07003071 if (1 == portFmt->nPortIndex) {
3072 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3073 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3074 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3075 fmt.fmt.pix_mp.pixelformat = capture_capability;
3076 enum vdec_output_fromat op_format;
3077 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3078 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3079 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3080 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3081 else if (portFmt->eColorFormat ==
3082 (OMX_COLOR_FORMATTYPE)
3083 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3084 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3085 else
3086 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087
Arun Menon906de572013-06-18 17:01:40 -07003088 if (eRet == OMX_ErrorNone) {
3089 drv_ctx.output_format = op_format;
3090 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3091 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003092 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003093 eRet = OMX_ErrorUnsupportedSetting;
3094 /*TODO: How to handle this case */
3095 } else {
3096 eRet = get_buffer_req(&drv_ctx.op_buf);
3097 }
3098 }
3099 if (eRet == OMX_ErrorNone) {
3100 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003101 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003102 eRet = OMX_ErrorBadParameter;
3103 }
3104 }
3105 }
3106 }
3107 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003108
Arun Menon906de572013-06-18 17:01:40 -07003109 case OMX_QcomIndexPortDefn: {
3110 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3111 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003112 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003113 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003114
Arun Menon906de572013-06-18 17:01:40 -07003115 /* Input port */
3116 if (portFmt->nPortIndex == 0) {
3117 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3118 if (secure_mode) {
3119 arbitrary_bytes = false;
3120 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3121 eRet = OMX_ErrorUnsupportedSetting;
3122 } else {
3123 arbitrary_bytes = true;
3124 }
3125 } else if (portFmt->nFramePackingFormat ==
3126 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3127 arbitrary_bytes = false;
3128 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003129 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003130 portFmt->nFramePackingFormat);
3131 eRet = OMX_ErrorUnsupportedSetting;
3132 }
3133 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003134 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003135 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3136 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3137 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3138 m_out_mem_region_smi = OMX_TRUE;
3139 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003140 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003141 m_use_output_pmem = OMX_TRUE;
3142 }
3143 }
3144 }
3145 }
3146 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003147
Arun Menon906de572013-06-18 17:01:40 -07003148 case OMX_IndexParamStandardComponentRole: {
3149 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3150 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003151 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003152 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003153
Arun Menon906de572013-06-18 17:01:40 -07003154 if ((m_state == OMX_StateLoaded)&&
3155 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3156 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3157 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003158 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003159 return OMX_ErrorIncorrectStateOperation;
3160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003161
Arun Menon906de572013-06-18 17:01:40 -07003162 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3163 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3164 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3165 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003166 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003167 eRet =OMX_ErrorUnsupportedSetting;
3168 }
3169 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3170 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3171 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3172 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003173 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003174 eRet = OMX_ErrorUnsupportedSetting;
3175 }
3176 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3177 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3178 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3179 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003180 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003181 eRet =OMX_ErrorUnsupportedSetting;
3182 }
3183 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3184 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3185 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3186 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003187 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003188 eRet = OMX_ErrorUnsupportedSetting;
3189 }
3190 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3191 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3192 ) {
3193 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3194 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3195 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003196 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003197 eRet =OMX_ErrorUnsupportedSetting;
3198 }
3199 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3200 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3201 ) {
3202 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3203 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3204 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003205 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003206 eRet =OMX_ErrorUnsupportedSetting;
3207 }
3208 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3209 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3210 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3211 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3212 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003213 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003214 eRet = OMX_ErrorUnsupportedSetting;
3215 }
3216 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003217 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003218 eRet = OMX_ErrorInvalidComponentName;
3219 }
3220 break;
3221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003222
Arun Menon906de572013-06-18 17:01:40 -07003223 case OMX_IndexParamPriorityMgmt: {
3224 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003225 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003226 return OMX_ErrorIncorrectStateOperation;
3227 }
3228 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003229 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003230 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003231
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003232 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003233 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003234
Arun Menon906de572013-06-18 17:01:40 -07003235 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3236 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003237
Arun Menon906de572013-06-18 17:01:40 -07003238 break;
3239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003240
Arun Menon906de572013-06-18 17:01:40 -07003241 case OMX_IndexParamCompBufferSupplier: {
3242 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003243 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003244 bufferSupplierType->eBufferSupplier);
3245 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3246 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247
Arun Menon906de572013-06-18 17:01:40 -07003248 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003249
Arun Menon906de572013-06-18 17:01:40 -07003250 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003251
Arun Menon906de572013-06-18 17:01:40 -07003252 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003253
Arun Menon906de572013-06-18 17:01:40 -07003254 }
3255 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003256 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003257 paramIndex);
3258 break;
3259 }
3260 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003261 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003262 paramIndex);
3263 break;
3264 }
3265 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003266 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003267 paramIndex);
3268 break;
3269 }
3270 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003271 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003272 paramIndex);
3273 break;
3274 }
3275 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3276 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3277 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3278 struct v4l2_control control;
3279 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003280 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003281 pictureOrder->eOutputPictureOrder);
3282 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3283 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3284 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3285 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3286 time_stamp_dts.set_timestamp_reorder_mode(false);
3287 } else
3288 eRet = OMX_ErrorBadParameter;
3289 if (eRet == OMX_ErrorNone) {
3290 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3291 control.value = pic_order;
3292 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3293 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003294 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003295 eRet = OMX_ErrorUnsupportedSetting;
3296 }
3297 }
3298 break;
3299 }
3300 case OMX_QcomIndexParamConcealMBMapExtraData:
3301 if (!secure_mode)
3302 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3303 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3304 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003305 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003306 eRet = OMX_ErrorUnsupportedSetting;
3307 }
3308 break;
3309 case OMX_QcomIndexParamFrameInfoExtraData: {
3310 if (!secure_mode)
3311 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3312 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3313 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003314 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003315 eRet = OMX_ErrorUnsupportedSetting;
3316 }
3317 break;
3318 }
3319 case OMX_QcomIndexParamInterlaceExtraData:
3320 if (!secure_mode)
3321 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3322 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3323 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003324 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003325 eRet = OMX_ErrorUnsupportedSetting;
3326 }
3327 break;
3328 case OMX_QcomIndexParamH264TimeInfo:
3329 if (!secure_mode)
3330 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3331 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3332 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003333 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003334 eRet = OMX_ErrorUnsupportedSetting;
3335 }
3336 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303337 case OMX_QcomIndexParamVideoFramePackingExtradata:
3338 if (!secure_mode)
3339 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3340 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3341 else {
3342 DEBUG_PRINT_ERROR("\n Setting extradata in secure mode is not supported");
3343 eRet = OMX_ErrorUnsupportedSetting;
3344 }
3345 break;
Arun Menon906de572013-06-18 17:01:40 -07003346 case OMX_QcomIndexParamVideoDivx: {
3347 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3348 }
3349 break;
3350 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003351 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003352 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3353 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3354 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3355 eRet = OMX_ErrorUnsupportedSetting;
3356 } else {
3357 m_out_pvt_entry_pmem = OMX_TRUE;
3358 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003359 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003360 m_use_output_pmem = OMX_TRUE;
3361 }
3362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003363
Arun Menon906de572013-06-18 17:01:40 -07003364 }
3365 break;
3366 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3367 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3368 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3369 struct v4l2_control control;
3370 int rc;
3371 drv_ctx.idr_only_decoding = 1;
3372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3373 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3374 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3375 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003376 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003377 eRet = OMX_ErrorUnsupportedSetting;
3378 } else {
3379 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3380 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3381 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3382 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003383 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003384 eRet = OMX_ErrorUnsupportedSetting;
3385 }
3386 /*Setting sync frame decoding on driver might change buffer
3387 * requirements so update them here*/
3388 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003389 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003390 eRet = OMX_ErrorUnsupportedSetting;
3391 }
3392 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003393 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003394 eRet = OMX_ErrorUnsupportedSetting;
3395 }
3396 }
3397 }
3398 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003399
Arun Menon906de572013-06-18 17:01:40 -07003400 case OMX_QcomIndexParamIndexExtraDataType: {
3401 if (!secure_mode) {
3402 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3403 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3404 (extradataIndexType->bEnabled == OMX_TRUE) &&
3405 (extradataIndexType->nPortIndex == 1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003406 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
Arun Menon906de572013-06-18 17:01:40 -07003407 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003408
Arun Menon906de572013-06-18 17:01:40 -07003409 }
3410 }
3411 }
3412 break;
3413 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003414#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003415 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003416#else
Arun Menon906de572013-06-18 17:01:40 -07003417 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003418#endif
Arun Menon906de572013-06-18 17:01:40 -07003419 }
3420 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003421#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003422 /* Need to allow following two set_parameters even in Idle
3423 * state. This is ANDROID architecture which is not in sync
3424 * with openmax standard. */
3425 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3426 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3427 if (enableNativeBuffers) {
3428 m_enable_android_native_buffers = enableNativeBuffers->enable;
3429 }
3430 }
3431 break;
3432 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3433 eRet = use_android_native_buffer(hComp, paramData);
3434 }
3435 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003436#endif
Arun Menon906de572013-06-18 17:01:40 -07003437 case OMX_QcomIndexParamEnableTimeStampReorder: {
3438 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3439 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3440 if (reorder->bEnable == OMX_TRUE) {
3441 frm_int =0;
3442 time_stamp_dts.set_timestamp_reorder_mode(true);
3443 } else
3444 time_stamp_dts.set_timestamp_reorder_mode(false);
3445 } else {
3446 time_stamp_dts.set_timestamp_reorder_mode(false);
3447 if (reorder->bEnable == OMX_TRUE) {
3448 eRet = OMX_ErrorUnsupportedSetting;
3449 }
3450 }
3451 }
3452 break;
3453 case OMX_IndexParamVideoProfileLevelCurrent: {
3454 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3455 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3456 if (pParam) {
3457 m_profile_lvl.eProfile = pParam->eProfile;
3458 m_profile_lvl.eLevel = pParam->eLevel;
3459 }
3460 break;
Arun Menon888aa852013-05-30 11:24:42 -07003461
Arun Menon906de572013-06-18 17:01:40 -07003462 }
Arun Menone5652482013-08-04 13:33:05 -07003463 case OMX_QcomIndexParamVideoMetaBufferMode:
3464 {
3465 StoreMetaDataInBuffersParams *metabuffer =
3466 (StoreMetaDataInBuffersParams *)paramData;
3467 if (!metabuffer) {
3468 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3469 eRet = OMX_ErrorBadParameter;
3470 break;
3471 }
3472 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3473 //set property dynamic buffer mode to driver.
3474 struct v4l2_control control;
3475 struct v4l2_format fmt;
3476 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3477 if (metabuffer->bStoreMetaData == true) {
3478 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3479 } else {
3480 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3481 }
3482 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3483 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003484 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003485 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003486 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003487 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003488 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003489 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3490 eRet = OMX_ErrorUnsupportedSetting;
3491 }
3492 } else {
3493 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003494 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003495 metabuffer->nPortIndex);
3496 eRet = OMX_ErrorUnsupportedSetting;
3497 }
3498 break;
3499 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003500 case OMX_QcomIndexParamVideoDownScalar: {
3501 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3502 struct v4l2_control control;
3503 int rc;
3504 if (pParam) {
3505 is_down_scalar_enabled = pParam->bEnable;
3506 if (is_down_scalar_enabled) {
3507 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3508 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3509 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3510 pParam->bEnable);
3511 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3512 if (rc < 0) {
3513 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3514 eRet = OMX_ErrorUnsupportedSetting;
3515 }
3516 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3517 control.value = 1;
3518 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3519 if (rc < 0) {
3520 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3521 eRet = OMX_ErrorUnsupportedSetting;
3522 }
3523 }
3524 }
3525 break;
3526 }
Praveen Chavancf924182013-12-06 23:16:23 -08003527#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3528 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3529 {
3530 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3531 PrepareForAdaptivePlaybackParams* pParams =
3532 (PrepareForAdaptivePlaybackParams *) paramData;
3533 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3534 if (!pParams->bEnable) {
3535 return OMX_ErrorNone;
3536 }
3537 if (pParams->nMaxFrameWidth > kMaxSmoothStreamingWidth
3538 || pParams->nMaxFrameHeight > kMaxSmoothStreamingHeight) {
3539 DEBUG_PRINT_ERROR(
3540 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3541 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
3542 kMaxSmoothStreamingWidth, kMaxSmoothStreamingHeight);
3543 eRet = OMX_ErrorBadParameter;
3544 } else {
3545 eRet = enable_smoothstreaming();
3546 if (eRet != OMX_ErrorNone) {
3547 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3548 eRet = OMX_ErrorHardware;
3549 } else {
3550 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3551 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3552 m_smoothstreaming_mode = true;
3553 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3554 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3555 }
3556 }
3557 } else {
3558 DEBUG_PRINT_ERROR(
3559 "Prepare for adaptive playback supported only on output port");
3560 eRet = OMX_ErrorBadParameter;
3561 }
3562 break;
3563 }
3564
3565#endif
Arun Menon906de572013-06-18 17:01:40 -07003566 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003567 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003568 eRet = OMX_ErrorUnsupportedIndex;
3569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003570 }
Arun Menon906de572013-06-18 17:01:40 -07003571 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003572}
3573
3574/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003575 FUNCTION
3576 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003577
Arun Menon906de572013-06-18 17:01:40 -07003578 DESCRIPTION
3579 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003580
Arun Menon906de572013-06-18 17:01:40 -07003581 PARAMETERS
3582 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583
Arun Menon906de572013-06-18 17:01:40 -07003584 RETURN VALUE
3585 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003586
Arun Menon906de572013-06-18 17:01:40 -07003587 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003588OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003589 OMX_IN OMX_INDEXTYPE configIndex,
3590 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003591{
Arun Menon906de572013-06-18 17:01:40 -07003592 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003593
Arun Menon906de572013-06-18 17:01:40 -07003594 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003595 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003596 return OMX_ErrorInvalidState;
3597 }
Arun Menon906de572013-06-18 17:01:40 -07003598
3599 switch ((unsigned long)configIndex) {
3600 case OMX_QcomIndexConfigInterlaced: {
3601 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3602 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3603 if (configFmt->nPortIndex == 1) {
3604 if (configFmt->nIndex == 0) {
3605 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3606 } else if (configFmt->nIndex == 1) {
3607 configFmt->eInterlaceType =
3608 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3609 } else if (configFmt->nIndex == 2) {
3610 configFmt->eInterlaceType =
3611 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3612 } else {
3613 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003614 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003615 eRet = OMX_ErrorNoMore;
3616 }
3617
3618 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003619 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003620 (int)configFmt->nPortIndex);
3621 eRet = OMX_ErrorBadPortIndex;
3622 }
3623 break;
3624 }
3625 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3626 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3627 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3628 decoderinstances->nNumOfInstances = 16;
3629 /*TODO: How to handle this case */
3630 break;
3631 }
3632 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3633 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3634 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3635 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303636 memcpy(configFmt, &m_frame_pack_arrangement,
3637 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003638 } else {
3639 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3640 }
3641 break;
3642 }
3643 case OMX_IndexConfigCommonOutputCrop: {
3644 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3645 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3646 break;
3647 }
3648 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003649 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003650 eRet = OMX_ErrorBadParameter;
3651 }
3652
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653 }
Arun Menon906de572013-06-18 17:01:40 -07003654
3655 return eRet;
3656}
3657
3658/* ======================================================================
3659 FUNCTION
3660 omx_vdec::SetConfig
3661
3662 DESCRIPTION
3663 OMX Set Config method implementation
3664
3665 PARAMETERS
3666 <TBD>.
3667
3668 RETURN VALUE
3669 OMX Error None if successful.
3670 ========================================================================== */
3671OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3672 OMX_IN OMX_INDEXTYPE configIndex,
3673 OMX_IN OMX_PTR configData)
3674{
3675 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003676 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003677 return OMX_ErrorInvalidState;
3678 }
3679
3680 OMX_ERRORTYPE ret = OMX_ErrorNone;
3681 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3682
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003683 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003684
3685 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3686 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003687 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003688 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003689 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003690 OMX_U32 extra_size;
3691 // Parsing done here for the AVC atom is definitely not generic
3692 // Currently this piece of code is working, but certainly
3693 // not tested with all .mp4 files.
3694 // Incase of failure, we might need to revisit this
3695 // for a generic piece of code.
3696
3697 // Retrieve size of NAL length field
3698 // byte #4 contains the size of NAL lenght field
3699 nal_length = (config->pData[4] & 0x03) + 1;
3700
3701 extra_size = 0;
3702 if (nal_length > 2) {
3703 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3704 extra_size = (nal_length - 2) * 2;
3705 }
3706
3707 // SPS starts from byte #6
3708 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3709 OMX_U8 *pDestBuf;
3710 m_vendor_config.nPortIndex = config->nPortIndex;
3711
3712 // minus 6 --> SPS starts from byte #6
3713 // minus 1 --> picture param set byte to be ignored from avcatom
3714 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3715 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3716 OMX_U32 len;
3717 OMX_U8 index = 0;
3718 // case where SPS+PPS is sent as part of set_config
3719 pDestBuf = m_vendor_config.pData;
3720
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003721 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003722 m_vendor_config.nPortIndex,
3723 m_vendor_config.nDataSize,
3724 m_vendor_config.pData);
3725 while (index < 2) {
3726 uint8 *psize;
3727 len = *pSrcBuf;
3728 len = len << 8;
3729 len |= *(pSrcBuf + 1);
3730 psize = (uint8 *) & len;
3731 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3732 for (unsigned int i = 0; i < nal_length; i++) {
3733 pDestBuf[i] = psize[nal_length - 1 - i];
3734 }
3735 //memcpy(pDestBuf,pSrcBuf,(len+2));
3736 pDestBuf += len + nal_length;
3737 pSrcBuf += len + 2;
3738 index++;
3739 pSrcBuf++; // skip picture param set
3740 len = 0;
3741 }
3742 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3743 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3744 m_vendor_config.nPortIndex = config->nPortIndex;
3745 m_vendor_config.nDataSize = config->nDataSize;
3746 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3747 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3748 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3749 if (m_vendor_config.pData) {
3750 free(m_vendor_config.pData);
3751 m_vendor_config.pData = NULL;
3752 m_vendor_config.nDataSize = 0;
3753 }
3754
3755 if (((*((OMX_U32 *) config->pData)) &
3756 VC1_SP_MP_START_CODE_MASK) ==
3757 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003758 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003759 m_vendor_config.nPortIndex = config->nPortIndex;
3760 m_vendor_config.nDataSize = config->nDataSize;
3761 m_vendor_config.pData =
3762 (OMX_U8 *) malloc(config->nDataSize);
3763 memcpy(m_vendor_config.pData, config->pData,
3764 config->nDataSize);
3765 m_vc1_profile = VC1_SP_MP_RCV;
3766 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003767 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003768 m_vendor_config.nPortIndex = config->nPortIndex;
3769 m_vendor_config.nDataSize = config->nDataSize;
3770 m_vendor_config.pData =
3771 (OMX_U8 *) malloc((config->nDataSize));
3772 memcpy(m_vendor_config.pData, config->pData,
3773 config->nDataSize);
3774 m_vc1_profile = VC1_AP;
3775 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003776 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003777 m_vendor_config.nPortIndex = config->nPortIndex;
3778 m_vendor_config.nDataSize = config->nDataSize;
3779 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3780 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3781 m_vc1_profile = VC1_SP_MP_RCV;
3782 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003783 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003784 }
3785 }
3786 return ret;
3787 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3788 struct v4l2_control temp;
3789 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3790
3791 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3792 switch (pNal->nNaluBytes) {
3793 case 0:
3794 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3795 break;
3796 case 2:
3797 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3798 break;
3799 case 4:
3800 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3801 break;
3802 default:
3803 return OMX_ErrorUnsupportedSetting;
3804 }
3805
3806 if (!arbitrary_bytes) {
3807 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3808 * with start code, so only need to notify driver in frame by frame mode */
3809 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3810 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3811 return OMX_ErrorHardware;
3812 }
3813 }
3814
3815 nal_length = pNal->nNaluBytes;
3816 m_frame_parser.init_nal_length(nal_length);
3817
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003818 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003819 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303820 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003821 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303822 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003823
3824 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3825 if (config->bEnabled) {
3826 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303827 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003828 config->nFps >> 16);
3829 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3830 drv_ctx.frame_rate.fps_denominator);
3831
3832 if (!drv_ctx.frame_rate.fps_numerator) {
3833 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3834 drv_ctx.frame_rate.fps_numerator = 30;
3835 }
3836
3837 if (drv_ctx.frame_rate.fps_denominator) {
3838 drv_ctx.frame_rate.fps_numerator = (int)
3839 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3840 }
3841
3842 drv_ctx.frame_rate.fps_denominator = 1;
3843 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3844 drv_ctx.frame_rate.fps_numerator;
3845
3846 struct v4l2_outputparm oparm;
3847 /*XXX: we're providing timing info as seconds per frame rather than frames
3848 * per second.*/
3849 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3850 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3851
3852 struct v4l2_streamparm sparm;
3853 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3854 sparm.parm.output = oparm;
3855 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3856 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3857 performance might be affected");
3858 ret = OMX_ErrorHardware;
3859 }
3860 client_set_fps = true;
3861 } else {
3862 DEBUG_PRINT_ERROR("Frame rate not supported.");
3863 ret = OMX_ErrorUnsupportedSetting;
3864 }
3865 } else {
3866 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3867 client_set_fps = false;
3868 }
3869 } else {
3870 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3871 (int)config->nPortIndex);
3872 ret = OMX_ErrorBadPortIndex;
3873 }
3874
3875 return ret;
3876 }
3877
3878 return OMX_ErrorNotImplemented;
3879}
3880
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303881#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3882
Arun Menon906de572013-06-18 17:01:40 -07003883/* ======================================================================
3884 FUNCTION
3885 omx_vdec::GetExtensionIndex
3886
3887 DESCRIPTION
3888 OMX GetExtensionIndex method implementaion. <TBD>
3889
3890 PARAMETERS
3891 <TBD>.
3892
3893 RETURN VALUE
3894 OMX Error None if everything successful.
3895
3896 ========================================================================== */
3897OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3898 OMX_IN OMX_STRING paramName,
3899 OMX_OUT OMX_INDEXTYPE* indexType)
3900{
3901 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003902 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003903 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303904 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003905 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303906 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003907 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303908 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3909 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3910 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3911 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003912 }
3913#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303914 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003915 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303916 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003917 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303918 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003919 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003920 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303921 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003922 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3923 }
3924#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303925 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07003926 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3927 }
Praveen Chavancf924182013-12-06 23:16:23 -08003928#if ADAPTIVE_PLAYBACK_SUPPORTED
3929 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
3930 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
3931 }
3932#endif
Arun Menon906de572013-06-18 17:01:40 -07003933 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003934 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003935 return OMX_ErrorNotImplemented;
3936 }
3937 return OMX_ErrorNone;
3938}
3939
3940/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003941 FUNCTION
3942 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003943
Arun Menon906de572013-06-18 17:01:40 -07003944 DESCRIPTION
3945 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003946
Arun Menon906de572013-06-18 17:01:40 -07003947 PARAMETERS
3948 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003949
Arun Menon906de572013-06-18 17:01:40 -07003950 RETURN VALUE
3951 Error None if everything is successful.
3952 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003953OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003954 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003955{
Arun Menon906de572013-06-18 17:01:40 -07003956 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003957 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07003958 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003959}
3960
3961/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003962 FUNCTION
3963 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003964
Arun Menon906de572013-06-18 17:01:40 -07003965 DESCRIPTION
3966 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003967
Arun Menon906de572013-06-18 17:01:40 -07003968 PARAMETERS
3969 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003970
Arun Menon906de572013-06-18 17:01:40 -07003971 RETURN VALUE
3972 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003973
Arun Menon906de572013-06-18 17:01:40 -07003974 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003975OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003976 OMX_IN OMX_U32 port,
3977 OMX_IN OMX_HANDLETYPE peerComponent,
3978 OMX_IN OMX_U32 peerPort,
3979 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003980{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003981 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07003982 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003983}
3984
3985/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003986 FUNCTION
3987 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003988
Arun Menon906de572013-06-18 17:01:40 -07003989 DESCRIPTION
3990 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003991
Arun Menon906de572013-06-18 17:01:40 -07003992 PARAMETERS
3993 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003994
Arun Menon906de572013-06-18 17:01:40 -07003995 RETURN VALUE
3996 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003997
Arun Menon906de572013-06-18 17:01:40 -07003998 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003999OMX_ERRORTYPE omx_vdec::allocate_extradata()
4000{
4001#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004002 if (drv_ctx.extradata_info.buffer_size) {
4003 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4004 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4005 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4006 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004007 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004008 }
4009 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4010 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4011 drv_ctx.extradata_info.size, 4096,
4012 &drv_ctx.extradata_info.ion.ion_alloc_data,
4013 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4014 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004015 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004016 return OMX_ErrorInsufficientResources;
4017 }
4018 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4019 drv_ctx.extradata_info.size,
4020 PROT_READ|PROT_WRITE, MAP_SHARED,
4021 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4022 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004023 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004024 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4025 free_ion_memory(&drv_ctx.extradata_info.ion);
4026 return OMX_ErrorInsufficientResources;
4027 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004028 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004029#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304030 if (!m_other_extradata) {
4031 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4032 if (!m_other_extradata) {
4033 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4034 return OMX_ErrorInsufficientResources;
4035 }
4036 }
Arun Menon906de572013-06-18 17:01:40 -07004037 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004038}
4039
Arun Menon906de572013-06-18 17:01:40 -07004040void omx_vdec::free_extradata()
4041{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004042#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004043 if (drv_ctx.extradata_info.uaddr) {
4044 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4045 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4046 free_ion_memory(&drv_ctx.extradata_info.ion);
4047 }
4048 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004049#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304050 if (m_other_extradata) {
4051 free(m_other_extradata);
4052 m_other_extradata = NULL;
4053 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004054}
4055
Shalaj Jain273b3e02012-06-22 19:08:03 -07004056OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004057 OMX_IN OMX_HANDLETYPE hComp,
4058 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4059 OMX_IN OMX_U32 port,
4060 OMX_IN OMX_PTR appData,
4061 OMX_IN OMX_U32 bytes,
4062 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004063{
Arun Menon906de572013-06-18 17:01:40 -07004064 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4065 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4066 unsigned i= 0; // Temporary counter
4067 struct vdec_setbuffer_cmd setbuffers;
4068 OMX_PTR privateAppData = NULL;
4069 private_handle_t *handle = NULL;
4070 OMX_U8 *buff = buffer;
4071 struct v4l2_buffer buf;
4072 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4073 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004074
Arun Menon906de572013-06-18 17:01:40 -07004075 if (!m_out_mem_ptr) {
4076 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4077 eRet = allocate_output_headers();
4078 if (eRet == OMX_ErrorNone)
4079 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004080 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004081
Arun Menon906de572013-06-18 17:01:40 -07004082 if (eRet == OMX_ErrorNone) {
4083 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4084 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4085 break;
4086 }
4087 }
4088 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004089
Arun Menon906de572013-06-18 17:01:40 -07004090 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004091 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004092 eRet = OMX_ErrorInsufficientResources;
4093 }
4094
Arun Menonbdb80b02013-08-12 17:45:54 -07004095 if (dynamic_buf_mode) {
4096 *bufferHdr = (m_out_mem_ptr + i );
4097 (*bufferHdr)->pBuffer = NULL;
4098 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4099 enum v4l2_buf_type buf_type;
4100 int rr = 0;
4101 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4102 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4103 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4104 return OMX_ErrorInsufficientResources;
4105 } else {
4106 streaming[CAPTURE_PORT] = true;
4107 DEBUG_PRINT_LOW("STREAMON Successful");
4108 }
4109 }
4110 BITMASK_SET(&m_out_bm_count,i);
4111 (*bufferHdr)->pAppPrivate = appData;
4112 (*bufferHdr)->pBuffer = buffer;
4113 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4114 return eRet;
4115 }
Arun Menon906de572013-06-18 17:01:40 -07004116 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004117#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004118 if (m_enable_android_native_buffers) {
4119 if (m_use_android_native_buffers) {
4120 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4121 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4122 handle = (private_handle_t *)nBuf->handle;
4123 privateAppData = params->pAppPrivate;
4124 } else {
4125 handle = (private_handle_t *)buff;
4126 privateAppData = appData;
4127 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004128
Arun Menon906de572013-06-18 17:01:40 -07004129 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4130 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4131 " expected %u, got %lu",
4132 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4133 return OMX_ErrorBadParameter;
4134 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004135
Arun Menon906de572013-06-18 17:01:40 -07004136 if (!m_use_android_native_buffers) {
4137 if (!secure_mode) {
4138 buff = (OMX_U8*)mmap(0, handle->size,
4139 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4140 if (buff == MAP_FAILED) {
4141 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4142 return OMX_ErrorInsufficientResources;
4143 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004144 }
4145 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004146#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004147 native_buffer[i].nativehandle = handle;
4148 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004149#endif
Arun Menon906de572013-06-18 17:01:40 -07004150 if (!handle) {
4151 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4152 return OMX_ErrorBadParameter;
4153 }
4154 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4155 drv_ctx.ptr_outputbuffer[i].offset = 0;
4156 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4157 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4158 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4159 } else
4160#endif
4161
4162 if (!ouput_egl_buffers && !m_use_output_pmem) {
4163#ifdef USE_ION
4164 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4165 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4166 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4167 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4168 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004169 DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd);
Arun Menon906de572013-06-18 17:01:40 -07004170 return OMX_ErrorInsufficientResources;
4171 }
4172 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4173 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4174#else
4175 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4176 open (MEM_DEVICE,O_RDWR);
4177
4178 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004179 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004180 return OMX_ErrorInsufficientResources;
4181 }
4182
4183 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4184 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4185 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4186 open (MEM_DEVICE,O_RDWR);
4187 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004188 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004189 return OMX_ErrorInsufficientResources;
4190 }
4191 }
4192
4193 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4194 drv_ctx.op_buf.buffer_size,
4195 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004196 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004197 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4198 return OMX_ErrorInsufficientResources;
4199 }
4200#endif
4201 if (!secure_mode) {
4202 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4203 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4204 PROT_READ|PROT_WRITE, MAP_SHARED,
4205 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4206 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4207 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4208#ifdef USE_ION
4209 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4210#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004211 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004212 return OMX_ErrorInsufficientResources;
4213 }
4214 }
4215 drv_ctx.ptr_outputbuffer[i].offset = 0;
4216 privateAppData = appData;
4217 } else {
4218
4219 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4220 if (!appData || !bytes ) {
4221 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004222 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004223 return OMX_ErrorBadParameter;
4224 }
4225 }
4226
4227 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4228 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4229 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4230 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4231 !pmem_list->nEntries ||
4232 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004233 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004234 return OMX_ErrorBadParameter;
4235 }
4236 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4237 pmem_list->entryList->entry;
4238 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4239 pmem_info->pmem_fd);
4240 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4241 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4242 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4243 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4244 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4245 privateAppData = appData;
4246 }
4247 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4248 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304249 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4250 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4251 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004252
4253 *bufferHdr = (m_out_mem_ptr + i );
4254 if (secure_mode)
4255 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4256 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4257 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4258 sizeof (vdec_bufferpayload));
4259
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004260 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004261 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4262 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4263
4264 buf.index = i;
4265 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4266 buf.memory = V4L2_MEMORY_USERPTR;
4267 plane[0].length = drv_ctx.op_buf.buffer_size;
4268 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4269 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4270 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4271 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4272 plane[0].data_offset = 0;
4273 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4274 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4275 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4276 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4277#ifdef USE_ION
4278 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4279#endif
4280 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4281 plane[extra_idx].data_offset = 0;
4282 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004283 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004284 return OMX_ErrorBadParameter;
4285 }
Arun Menon906de572013-06-18 17:01:40 -07004286 buf.m.planes = plane;
4287 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288
Arun Menon906de572013-06-18 17:01:40 -07004289 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004290 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004291 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004292 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004293 }
4294
Arun Menon906de572013-06-18 17:01:40 -07004295 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4296 enum v4l2_buf_type buf_type;
4297 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4298 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4299 return OMX_ErrorInsufficientResources;
4300 } else {
4301 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004302 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004303 }
4304 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004305
Arun Menon906de572013-06-18 17:01:40 -07004306 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4307 if (m_enable_android_native_buffers) {
4308 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4309 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4310 } else {
4311 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004312 }
Arun Menon906de572013-06-18 17:01:40 -07004313 (*bufferHdr)->pAppPrivate = privateAppData;
4314 BITMASK_SET(&m_out_bm_count,i);
4315 }
4316 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004317}
4318
4319/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004320 FUNCTION
4321 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004322
Arun Menon906de572013-06-18 17:01:40 -07004323 DESCRIPTION
4324 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004325
Arun Menon906de572013-06-18 17:01:40 -07004326 PARAMETERS
4327 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328
Arun Menon906de572013-06-18 17:01:40 -07004329 RETURN VALUE
4330 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004331
Arun Menon906de572013-06-18 17:01:40 -07004332 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004333OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004334 OMX_IN OMX_HANDLETYPE hComp,
4335 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4336 OMX_IN OMX_U32 port,
4337 OMX_IN OMX_PTR appData,
4338 OMX_IN OMX_U32 bytes,
4339 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004340{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004341 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004342 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4343 if (!m_inp_heap_ptr)
4344 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4345 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4346 drv_ctx.ip_buf.actualcount);
4347 if (!m_phdr_pmem_ptr)
4348 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4349 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4350 drv_ctx.ip_buf.actualcount);
4351 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4352 DEBUG_PRINT_ERROR("Insufficent memory");
4353 eRet = OMX_ErrorInsufficientResources;
4354 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4355 input_use_buffer = true;
4356 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4357 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4358 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4359 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4360 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4361 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4362 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4363 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004364 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
Arun Menon906de572013-06-18 17:01:40 -07004365 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4366 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004367 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004368 return OMX_ErrorInsufficientResources;
4369 }
4370 m_in_alloc_cnt++;
4371 } else {
4372 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4373 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004374 }
Arun Menon906de572013-06-18 17:01:40 -07004375 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004376}
4377
4378/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004379 FUNCTION
4380 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004381
Arun Menon906de572013-06-18 17:01:40 -07004382 DESCRIPTION
4383 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004384
Arun Menon906de572013-06-18 17:01:40 -07004385 PARAMETERS
4386 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004387
Arun Menon906de572013-06-18 17:01:40 -07004388 RETURN VALUE
4389 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004390
Arun Menon906de572013-06-18 17:01:40 -07004391 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004392OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004393 OMX_IN OMX_HANDLETYPE hComp,
4394 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4395 OMX_IN OMX_U32 port,
4396 OMX_IN OMX_PTR appData,
4397 OMX_IN OMX_U32 bytes,
4398 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399{
Arun Menon906de572013-06-18 17:01:40 -07004400 OMX_ERRORTYPE error = OMX_ErrorNone;
4401 struct vdec_setbuffer_cmd setbuffers;
4402
4403 if (bufferHdr == NULL || bytes == 0) {
4404 if (!secure_mode && buffer == NULL) {
4405 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4406 return OMX_ErrorBadParameter;
4407 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408 }
Arun Menon906de572013-06-18 17:01:40 -07004409 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004410 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004411 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004412 }
Arun Menon906de572013-06-18 17:01:40 -07004413 if (port == OMX_CORE_INPUT_PORT_INDEX)
4414 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4415 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4416 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4417 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004418 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004419 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004420 }
Arun Menon906de572013-06-18 17:01:40 -07004421 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4422 if (error == OMX_ErrorNone) {
4423 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4424 // Send the callback now
4425 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4426 post_event(OMX_CommandStateSet,OMX_StateIdle,
4427 OMX_COMPONENT_GENERATE_EVENT);
4428 }
4429 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4430 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4431 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4432 post_event(OMX_CommandPortEnable,
4433 OMX_CORE_INPUT_PORT_INDEX,
4434 OMX_COMPONENT_GENERATE_EVENT);
4435 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4436 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4437 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4438 post_event(OMX_CommandPortEnable,
4439 OMX_CORE_OUTPUT_PORT_INDEX,
4440 OMX_COMPONENT_GENERATE_EVENT);
4441 }
4442 }
4443 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004444}
4445
4446OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004447 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004448{
Arun Menon906de572013-06-18 17:01:40 -07004449 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4450 if (m_inp_heap_ptr[bufferindex].pBuffer)
4451 free(m_inp_heap_ptr[bufferindex].pBuffer);
4452 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4453 }
4454 if (pmem_bufferHdr)
4455 free_input_buffer(pmem_bufferHdr);
4456 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004457}
4458
4459OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4460{
Arun Menon906de572013-06-18 17:01:40 -07004461 unsigned int index = 0;
4462 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4463 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004465
Arun Menon906de572013-06-18 17:01:40 -07004466 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004467 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004468
4469 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004470 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004471 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4472 struct vdec_setbuffer_cmd setbuffers;
4473 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4474 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4475 sizeof (vdec_bufferpayload));
4476 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004477 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004478 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004479 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004480 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4481 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4482 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4483 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4484 }
4485 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4486 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4487 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4488 free(m_desc_buffer_ptr[index].buf_addr);
4489 m_desc_buffer_ptr[index].buf_addr = NULL;
4490 m_desc_buffer_ptr[index].desc_data_size = 0;
4491 }
4492#ifdef USE_ION
4493 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4494#endif
4495 }
4496 }
4497
4498 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004499}
4500
4501OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4502{
Arun Menon906de572013-06-18 17:01:40 -07004503 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004504
Arun Menon906de572013-06-18 17:01:40 -07004505 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4506 return OMX_ErrorBadParameter;
4507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004508
Arun Menon906de572013-06-18 17:01:40 -07004509 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004510 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004511
Arun Menon906de572013-06-18 17:01:40 -07004512 if (index < drv_ctx.op_buf.actualcount
4513 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004514 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004515 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004516
Arun Menon906de572013-06-18 17:01:40 -07004517 struct vdec_setbuffer_cmd setbuffers;
4518 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4519 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4520 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004521
4522 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004523#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004524 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004525 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004526 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4527 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4528 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4529 }
Arun Menon906de572013-06-18 17:01:40 -07004530 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004531 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4532 } else {
4533#endif
4534 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4535 if (!secure_mode) {
4536 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4537 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4538 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4539 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4540 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4541 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4542 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4543 }
4544 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4545 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004546#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004547 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004548#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004549 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004550#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004551 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004553 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004554 if (release_output_done()) {
4555 free_extradata();
4556 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004557 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004558
Arun Menon906de572013-06-18 17:01:40 -07004559 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004560
4561}
4562
4563OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004564 OMX_BUFFERHEADERTYPE **bufferHdr,
4565 OMX_U32 port,
4566 OMX_PTR appData,
4567 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004568{
Arun Menon906de572013-06-18 17:01:40 -07004569 OMX_BUFFERHEADERTYPE *input = NULL;
4570 unsigned char *buf_addr = NULL;
4571 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4572 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573
Arun Menon906de572013-06-18 17:01:40 -07004574 /* Sanity Check*/
4575 if (bufferHdr == NULL) {
4576 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577 }
4578
Arun Menon906de572013-06-18 17:01:40 -07004579 if (m_inp_heap_ptr == NULL) {
4580 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4581 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4582 drv_ctx.ip_buf.actualcount);
4583 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4584 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4585 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004586
Arun Menon906de572013-06-18 17:01:40 -07004587 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004588 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004589 return OMX_ErrorInsufficientResources;
4590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004591 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004592
Arun Menon906de572013-06-18 17:01:40 -07004593 /*Find a Free index*/
4594 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4595 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004596 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004597 break;
4598 }
4599 }
4600
4601 if (i < drv_ctx.ip_buf.actualcount) {
4602 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4603
4604 if (buf_addr == NULL) {
4605 return OMX_ErrorInsufficientResources;
4606 }
4607
4608 *bufferHdr = (m_inp_heap_ptr + i);
4609 input = *bufferHdr;
4610 BITMASK_SET(&m_heap_inp_bm_count,i);
4611
4612 input->pBuffer = (OMX_U8 *)buf_addr;
4613 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4614 input->nVersion.nVersion = OMX_SPEC_VERSION;
4615 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4616 input->pAppPrivate = appData;
4617 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004618 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004619 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004620 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004621 /*Add the Buffers to freeq*/
4622 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4623 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004624 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004625 return OMX_ErrorInsufficientResources;
4626 }
4627 } else {
4628 return OMX_ErrorBadParameter;
4629 }
4630
4631 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004632
4633}
4634
4635
4636/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004637 FUNCTION
4638 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004639
Arun Menon906de572013-06-18 17:01:40 -07004640 DESCRIPTION
4641 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004642
Arun Menon906de572013-06-18 17:01:40 -07004643 PARAMETERS
4644 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645
Arun Menon906de572013-06-18 17:01:40 -07004646 RETURN VALUE
4647 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648
Arun Menon906de572013-06-18 17:01:40 -07004649 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004650OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004651 OMX_IN OMX_HANDLETYPE hComp,
4652 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4653 OMX_IN OMX_U32 port,
4654 OMX_IN OMX_PTR appData,
4655 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004656{
4657
Arun Menon906de572013-06-18 17:01:40 -07004658 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4659 struct vdec_setbuffer_cmd setbuffers;
4660 OMX_BUFFERHEADERTYPE *input = NULL;
4661 unsigned i = 0;
4662 unsigned char *buf_addr = NULL;
4663 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004664
Arun Menon906de572013-06-18 17:01:40 -07004665 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004666 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004667 bytes, drv_ctx.ip_buf.buffer_size);
4668 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004669 }
4670
Arun Menon906de572013-06-18 17:01:40 -07004671 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004672 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004673 drv_ctx.ip_buf.actualcount,
4674 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004675
Arun Menon906de572013-06-18 17:01:40 -07004676 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4677 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4678
4679 if (m_inp_mem_ptr == NULL) {
4680 return OMX_ErrorInsufficientResources;
4681 }
4682
4683 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4684 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4685
4686 if (drv_ctx.ptr_inputbuffer == NULL) {
4687 return OMX_ErrorInsufficientResources;
4688 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004689#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004690 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4691 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004692
Arun Menon906de572013-06-18 17:01:40 -07004693 if (drv_ctx.ip_buf_ion_info == NULL) {
4694 return OMX_ErrorInsufficientResources;
4695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004696#endif
4697
Arun Menon906de572013-06-18 17:01:40 -07004698 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4699 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004700#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004701 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004702#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004703 }
4704 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705
Arun Menon906de572013-06-18 17:01:40 -07004706 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4707 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004708 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004709 break;
4710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004711 }
Arun Menon906de572013-06-18 17:01:40 -07004712
4713 if (i < drv_ctx.ip_buf.actualcount) {
4714 struct v4l2_buffer buf;
4715 struct v4l2_plane plane;
4716 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004717 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004718#ifdef USE_ION
4719 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4720 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4721 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4722 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4723 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4724 return OMX_ErrorInsufficientResources;
4725 }
4726 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4727#else
4728 pmem_fd = open (MEM_DEVICE,O_RDWR);
4729
4730 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004731 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004732 return OMX_ErrorInsufficientResources;
4733 }
4734
4735 if (pmem_fd == 0) {
4736 pmem_fd = open (MEM_DEVICE,O_RDWR);
4737
4738 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004739 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004740 return OMX_ErrorInsufficientResources;
4741 }
4742 }
4743
4744 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4745 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004746 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004747 close(pmem_fd);
4748 return OMX_ErrorInsufficientResources;
4749 }
4750#endif
4751 if (!secure_mode) {
4752 buf_addr = (unsigned char *)mmap(NULL,
4753 drv_ctx.ip_buf.buffer_size,
4754 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4755
4756 if (buf_addr == MAP_FAILED) {
4757 close(pmem_fd);
4758#ifdef USE_ION
4759 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4760#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004761 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004762 return OMX_ErrorInsufficientResources;
4763 }
4764 }
4765 *bufferHdr = (m_inp_mem_ptr + i);
4766 if (secure_mode)
4767 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4768 else
4769 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4770 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4771 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4772 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4773 drv_ctx.ptr_inputbuffer [i].offset = 0;
4774
4775
4776 buf.index = i;
4777 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4778 buf.memory = V4L2_MEMORY_USERPTR;
4779 plane.bytesused = 0;
4780 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4781 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4782 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4783 plane.reserved[1] = 0;
4784 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4785 buf.m.planes = &plane;
4786 buf.length = 1;
4787
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004788 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004789 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4790
4791 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4792
4793 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004794 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004795 /*TODO: How to handle this case */
4796 return OMX_ErrorInsufficientResources;
4797 }
4798
4799 input = *bufferHdr;
4800 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004801 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004802 if (secure_mode)
4803 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4804 else
4805 input->pBuffer = (OMX_U8 *)buf_addr;
4806 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4807 input->nVersion.nVersion = OMX_SPEC_VERSION;
4808 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4809 input->pAppPrivate = appData;
4810 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4811 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4812
4813 if (drv_ctx.disable_dmx) {
4814 eRet = allocate_desc_buffer(i);
4815 }
4816 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004817 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004818 eRet = OMX_ErrorInsufficientResources;
4819 }
4820 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004821}
4822
4823
4824/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004825 FUNCTION
4826 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004827
Arun Menon906de572013-06-18 17:01:40 -07004828 DESCRIPTION
4829 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004830
Arun Menon906de572013-06-18 17:01:40 -07004831 PARAMETERS
4832 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004833
Arun Menon906de572013-06-18 17:01:40 -07004834 RETURN VALUE
4835 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836
Arun Menon906de572013-06-18 17:01:40 -07004837 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004838OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004839 OMX_IN OMX_HANDLETYPE hComp,
4840 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4841 OMX_IN OMX_U32 port,
4842 OMX_IN OMX_PTR appData,
4843 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004844{
Arun Menon906de572013-06-18 17:01:40 -07004845 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4846 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4847 unsigned i= 0; // Temporary counter
4848 struct vdec_setbuffer_cmd setbuffers;
4849 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004850#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004851 int ion_device_fd =-1;
4852 struct ion_allocation_data ion_alloc_data;
4853 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004854#endif
Arun Menon906de572013-06-18 17:01:40 -07004855 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004856 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004857 drv_ctx.op_buf.actualcount,
4858 drv_ctx.op_buf.buffer_size);
4859 int nBufHdrSize = 0;
4860 int nPlatformEntrySize = 0;
4861 int nPlatformListSize = 0;
4862 int nPMEMInfoSize = 0;
4863 int pmem_fd = -1;
4864 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004865
Arun Menon906de572013-06-18 17:01:40 -07004866 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4867 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4868 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004869
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004870 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004871 drv_ctx.op_buf.actualcount);
4872 nBufHdrSize = drv_ctx.op_buf.actualcount *
4873 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004874
Arun Menon906de572013-06-18 17:01:40 -07004875 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4876 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4877 nPlatformListSize = drv_ctx.op_buf.actualcount *
4878 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4879 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4880 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004881
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004882 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004883 sizeof(OMX_BUFFERHEADERTYPE),
4884 nPMEMInfoSize,
4885 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004886 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004887 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004888#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004889 ion_device_fd = alloc_map_ion_memory(
4890 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4891 drv_ctx.op_buf.alignment,
4892 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4893 if (ion_device_fd < 0) {
4894 return OMX_ErrorInsufficientResources;
4895 }
4896 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004897#else
Arun Menon906de572013-06-18 17:01:40 -07004898 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004899
Arun Menon906de572013-06-18 17:01:40 -07004900 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004901 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004902 drv_ctx.op_buf.buffer_size);
4903 return OMX_ErrorInsufficientResources;
4904 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004905
Arun Menon906de572013-06-18 17:01:40 -07004906 if (pmem_fd == 0) {
4907 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004908
Arun Menon906de572013-06-18 17:01:40 -07004909 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004910 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004911 drv_ctx.op_buf.buffer_size);
4912 return OMX_ErrorInsufficientResources;
4913 }
4914 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915
Arun Menon906de572013-06-18 17:01:40 -07004916 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4917 drv_ctx.op_buf.actualcount,
4918 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004919 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004920 close(pmem_fd);
4921 return OMX_ErrorInsufficientResources;
4922 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004923#endif
Arun Menon906de572013-06-18 17:01:40 -07004924 if (!secure_mode) {
4925 pmem_baseaddress = (unsigned char *)mmap(NULL,
4926 (drv_ctx.op_buf.buffer_size *
4927 drv_ctx.op_buf.actualcount),
4928 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4929 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004930 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07004931 drv_ctx.op_buf.buffer_size);
4932 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004933#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004934 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004935#endif
Arun Menon906de572013-06-18 17:01:40 -07004936 return OMX_ErrorInsufficientResources;
4937 }
4938 }
4939 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4940 // Alloc mem for platform specific info
4941 char *pPtr=NULL;
4942 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4943 nPMEMInfoSize,1);
4944 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4945 calloc (sizeof(struct vdec_bufferpayload),
4946 drv_ctx.op_buf.actualcount);
4947 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4948 calloc (sizeof (struct vdec_output_frameinfo),
4949 drv_ctx.op_buf.actualcount);
4950#ifdef USE_ION
4951 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4952 calloc (sizeof(struct vdec_ion),
4953 drv_ctx.op_buf.actualcount);
4954#endif
4955
4956 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4957 && drv_ctx.ptr_respbuffer) {
4958 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4959 (drv_ctx.op_buf.buffer_size *
4960 drv_ctx.op_buf.actualcount);
4961 bufHdr = m_out_mem_ptr;
4962 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4963 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4964 (((char *) m_platform_list) + nPlatformListSize);
4965 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4966 (((char *) m_platform_entry) + nPlatformEntrySize);
4967 pPlatformList = m_platform_list;
4968 pPlatformEntry = m_platform_entry;
4969 pPMEMInfo = m_pmem_info;
4970
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004971 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07004972
4973 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004974 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
4975 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07004976 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4977 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4978 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4979 // Set the values when we determine the right HxW param
4980 bufHdr->nAllocLen = bytes;
4981 bufHdr->nFilledLen = 0;
4982 bufHdr->pAppPrivate = appData;
4983 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4984 // Platform specific PMEM Information
4985 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004986 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004987 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4988 pPlatformEntry->entry = pPMEMInfo;
4989 // Initialize the Platform List
4990 pPlatformList->nEntries = 1;
4991 pPlatformList->entryList = pPlatformEntry;
4992 // Keep pBuffer NULL till vdec is opened
4993 bufHdr->pBuffer = NULL;
4994 bufHdr->nOffset = 0;
4995
4996 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4997 pPMEMInfo->pmem_fd = 0;
4998 bufHdr->pPlatformPrivate = pPlatformList;
4999
5000 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5001 m_pmem_info[i].pmem_fd = pmem_fd;
5002#ifdef USE_ION
5003 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5004 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5005 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5006#endif
5007
5008 /*Create a mapping between buffers*/
5009 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5010 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5011 &drv_ctx.ptr_outputbuffer[i];
5012 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5013 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5014 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305015 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5016 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5017 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005018
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005019 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005020 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5021 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5022 // Move the buffer and buffer header pointers
5023 bufHdr++;
5024 pPMEMInfo++;
5025 pPlatformEntry++;
5026 pPlatformList++;
5027 }
5028 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005029 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005030 m_out_mem_ptr, pPtr);
5031 if (m_out_mem_ptr) {
5032 free(m_out_mem_ptr);
5033 m_out_mem_ptr = NULL;
5034 }
5035 if (pPtr) {
5036 free(pPtr);
5037 pPtr = NULL;
5038 }
5039 if (drv_ctx.ptr_outputbuffer) {
5040 free(drv_ctx.ptr_outputbuffer);
5041 drv_ctx.ptr_outputbuffer = NULL;
5042 }
5043 if (drv_ctx.ptr_respbuffer) {
5044 free(drv_ctx.ptr_respbuffer);
5045 drv_ctx.ptr_respbuffer = NULL;
5046 }
5047#ifdef USE_ION
5048 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005049 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005050 free(drv_ctx.op_buf_ion_info);
5051 drv_ctx.op_buf_ion_info = NULL;
5052 }
5053#endif
5054 eRet = OMX_ErrorInsufficientResources;
5055 }
5056 if (eRet == OMX_ErrorNone)
5057 eRet = allocate_extradata();
5058 }
5059
5060 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5061 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005062 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005063 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005064 }
5065 }
Arun Menon906de572013-06-18 17:01:40 -07005066
5067 if (eRet == OMX_ErrorNone) {
5068 if (i < drv_ctx.op_buf.actualcount) {
5069 struct v4l2_buffer buf;
5070 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5071 int rc;
5072 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5073
5074 drv_ctx.ptr_outputbuffer[i].buffer_len =
5075 drv_ctx.op_buf.buffer_size;
5076
5077 *bufferHdr = (m_out_mem_ptr + i );
5078 if (secure_mode) {
5079 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5080 }
5081 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5082
5083 buf.index = i;
5084 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5085 buf.memory = V4L2_MEMORY_USERPTR;
5086 plane[0].length = drv_ctx.op_buf.buffer_size;
5087 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5088 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005089#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005090 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005091#endif
Arun Menon906de572013-06-18 17:01:40 -07005092 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5093 plane[0].data_offset = 0;
5094 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5095 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5096 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5097 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005098#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005099 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005100#endif
Arun Menon906de572013-06-18 17:01:40 -07005101 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5102 plane[extra_idx].data_offset = 0;
5103 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005104 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005105 return OMX_ErrorBadParameter;
5106 }
5107 buf.m.planes = plane;
5108 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005109 DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
Arun Menon906de572013-06-18 17:01:40 -07005110 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5111 if (rc) {
5112 /*TODO: How to handle this case */
5113 return OMX_ErrorInsufficientResources;
5114 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005115
Arun Menon906de572013-06-18 17:01:40 -07005116 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5117 enum v4l2_buf_type buf_type;
5118 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5119 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5120 if (rc) {
5121 return OMX_ErrorInsufficientResources;
5122 } else {
5123 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005124 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005125 }
5126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127
Arun Menon906de572013-06-18 17:01:40 -07005128 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5129 (*bufferHdr)->pAppPrivate = appData;
5130 BITMASK_SET(&m_out_bm_count,i);
5131 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005132 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005133 eRet = OMX_ErrorInsufficientResources;
5134 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005135 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005136
Arun Menon906de572013-06-18 17:01:40 -07005137 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005138}
5139
5140
5141// AllocateBuffer -- API Call
5142/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005143 FUNCTION
5144 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005145
Arun Menon906de572013-06-18 17:01:40 -07005146 DESCRIPTION
5147 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005148
Arun Menon906de572013-06-18 17:01:40 -07005149 PARAMETERS
5150 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151
Arun Menon906de572013-06-18 17:01:40 -07005152 RETURN VALUE
5153 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005154
Arun Menon906de572013-06-18 17:01:40 -07005155 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005156OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005157 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5158 OMX_IN OMX_U32 port,
5159 OMX_IN OMX_PTR appData,
5160 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005161{
5162 unsigned i = 0;
5163 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5164
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005165 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005166 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005167 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005168 return OMX_ErrorInvalidState;
5169 }
5170
Arun Menon906de572013-06-18 17:01:40 -07005171 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5172 if (arbitrary_bytes) {
5173 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5174 } else {
5175 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5176 }
5177 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005178 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5179 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005180 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005182 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005183 }
5184 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005185 if (eRet == OMX_ErrorNone) {
5186 if (allocate_done()) {
5187 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005188 // Send the callback now
5189 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5190 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005191 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192 }
5193 }
Arun Menon906de572013-06-18 17:01:40 -07005194 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5195 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5196 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5197 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005198 OMX_CORE_INPUT_PORT_INDEX,
5199 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005200 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 }
Arun Menon906de572013-06-18 17:01:40 -07005202 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5203 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5204 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005205 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005206 OMX_CORE_OUTPUT_PORT_INDEX,
5207 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208 }
5209 }
5210 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005211 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005212 return eRet;
5213}
5214
5215// Free Buffer - API call
5216/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005217 FUNCTION
5218 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005219
Arun Menon906de572013-06-18 17:01:40 -07005220 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005221
Arun Menon906de572013-06-18 17:01:40 -07005222 PARAMETERS
5223 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224
Arun Menon906de572013-06-18 17:01:40 -07005225 RETURN VALUE
5226 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005227
Arun Menon906de572013-06-18 17:01:40 -07005228 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005229OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005230 OMX_IN OMX_U32 port,
5231 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005232{
5233 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5234 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005235 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005236
Arun Menon906de572013-06-18 17:01:40 -07005237 if (m_state == OMX_StateIdle &&
5238 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005239 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005240 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5241 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005242 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005243 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5244 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5245 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5246 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005247 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005248 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005249 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005250 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005251 OMX_ErrorPortUnpopulated,
5252 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005253
5254 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005255 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005256 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005257 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005258 OMX_ErrorPortUnpopulated,
5259 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005260 }
5261
Arun Menon906de572013-06-18 17:01:40 -07005262 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5263 /*Check if arbitrary bytes*/
5264 if (!arbitrary_bytes && !input_use_buffer)
5265 nPortIndex = buffer - m_inp_mem_ptr;
5266 else
5267 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005268
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005269 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005270 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5271 // Clear the bit associated with it.
5272 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5273 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5274 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005275
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005276 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005277 if (m_phdr_pmem_ptr)
5278 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5279 } else {
5280 if (arbitrary_bytes) {
5281 if (m_phdr_pmem_ptr)
5282 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5283 else
5284 free_input_buffer(nPortIndex,NULL);
5285 } else
5286 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005287 }
Arun Menon906de572013-06-18 17:01:40 -07005288 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305289 if(release_input_done())
5290 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005291 /*Free the Buffer Header*/
5292 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005293 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005294 free_input_buffer_header();
5295 }
5296 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005297 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298 eRet = OMX_ErrorBadPortIndex;
5299 }
5300
Arun Menon906de572013-06-18 17:01:40 -07005301 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5302 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005303 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005304 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5305 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005306 OMX_CORE_INPUT_PORT_INDEX,
5307 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005308 }
Arun Menon906de572013-06-18 17:01:40 -07005309 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005310 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005311 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005312 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005313 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005314 // Clear the bit associated with it.
5315 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5316 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005317 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005318
Surajit Podder12aefac2013-08-06 18:43:32 +05305319 if(release_output_done()) {
5320 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5321 }
Arun Menon906de572013-06-18 17:01:40 -07005322 if (release_output_done()) {
5323 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324 }
Arun Menon906de572013-06-18 17:01:40 -07005325 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005326 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327 eRet = OMX_ErrorBadPortIndex;
5328 }
Arun Menon906de572013-06-18 17:01:40 -07005329 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5330 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005331 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005332
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005333 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005334 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005335#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005336 if (m_enable_android_native_buffers) {
5337 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5338 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5339 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005340#endif
5341
Arun Menon906de572013-06-18 17:01:40 -07005342 post_event(OMX_CommandPortDisable,
5343 OMX_CORE_OUTPUT_PORT_INDEX,
5344 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345 }
Arun Menon906de572013-06-18 17:01:40 -07005346 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005347 eRet = OMX_ErrorBadPortIndex;
5348 }
Arun Menon906de572013-06-18 17:01:40 -07005349 if ((eRet == OMX_ErrorNone) &&
5350 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5351 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005352 // Send the callback now
5353 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5354 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005355 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005356 }
5357 }
5358 return eRet;
5359}
5360
5361
5362/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005363 FUNCTION
5364 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365
Arun Menon906de572013-06-18 17:01:40 -07005366 DESCRIPTION
5367 This routine is used to push the encoded video frames to
5368 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369
Arun Menon906de572013-06-18 17:01:40 -07005370 PARAMETERS
5371 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005372
Arun Menon906de572013-06-18 17:01:40 -07005373 RETURN VALUE
5374 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005375
Arun Menon906de572013-06-18 17:01:40 -07005376 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005377OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005378 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005379{
Arun Menon906de572013-06-18 17:01:40 -07005380 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5381 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005382
Arun Menon906de572013-06-18 17:01:40 -07005383 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005384 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005385 return OMX_ErrorInvalidState;
5386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005387
Arun Menon906de572013-06-18 17:01:40 -07005388 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005389 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005390 return OMX_ErrorBadParameter;
5391 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005392
Arun Menon906de572013-06-18 17:01:40 -07005393 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005394 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005395 return OMX_ErrorIncorrectStateOperation;
5396 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005397
Arun Menon906de572013-06-18 17:01:40 -07005398 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005399 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005400 return OMX_ErrorBadPortIndex;
5401 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005402
5403#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005404 if (iDivXDrmDecrypt) {
5405 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5406 if (drmErr != OMX_ErrorNone) {
5407 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005408 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005412 if (perf_flag) {
5413 if (!latency) {
5414 dec_time.stop();
5415 latency = dec_time.processing_time_us();
5416 dec_time.start();
5417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005418 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005419
Arun Menon906de572013-06-18 17:01:40 -07005420 if (arbitrary_bytes) {
5421 nBufferIndex = buffer - m_inp_heap_ptr;
5422 } else {
5423 if (input_use_buffer == true) {
5424 nBufferIndex = buffer - m_inp_heap_ptr;
5425 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5426 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5427 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5428 buffer = &m_inp_mem_ptr[nBufferIndex];
5429 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5430 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5431 } else {
5432 nBufferIndex = buffer - m_inp_mem_ptr;
5433 }
5434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005435
Arun Menon906de572013-06-18 17:01:40 -07005436 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005437 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005438 return OMX_ErrorBadParameter;
5439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005440
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005441 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5442 codec_config_flag = true;
5443 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5444 }
5445
Arun Menon906de572013-06-18 17:01:40 -07005446 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5447 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5448 if (arbitrary_bytes) {
5449 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005450 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005451 } else {
Arun Menon906de572013-06-18 17:01:40 -07005452 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5453 }
5454 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455}
5456
5457/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005458 FUNCTION
5459 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460
Arun Menon906de572013-06-18 17:01:40 -07005461 DESCRIPTION
5462 This routine is used to push the encoded video frames to
5463 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005464
Arun Menon906de572013-06-18 17:01:40 -07005465 PARAMETERS
5466 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467
Arun Menon906de572013-06-18 17:01:40 -07005468 RETURN VALUE
5469 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470
Arun Menon906de572013-06-18 17:01:40 -07005471 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005473 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474{
Arun Menon906de572013-06-18 17:01:40 -07005475 int push_cnt = 0,i=0;
5476 unsigned nPortIndex = 0;
5477 OMX_ERRORTYPE ret = OMX_ErrorNone;
5478 struct vdec_input_frameinfo frameinfo;
5479 struct vdec_bufferpayload *temp_buffer;
5480 struct vdec_seqheader seq_header;
5481 bool port_setting_changed = true;
5482 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005483
Arun Menon906de572013-06-18 17:01:40 -07005484 /*Should we generate a Aync error event*/
5485 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005486 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005487 return OMX_ErrorBadParameter;
5488 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005489
Arun Menon906de572013-06-18 17:01:40 -07005490 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005491
Arun Menon906de572013-06-18 17:01:40 -07005492 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005493 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005494 nPortIndex);
5495 return OMX_ErrorBadParameter;
5496 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497
Arun Menon906de572013-06-18 17:01:40 -07005498 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005499
Arun Menon906de572013-06-18 17:01:40 -07005500 /* return zero length and not an EOS buffer */
5501 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5502 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005503 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005504 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5505 OMX_COMPONENT_GENERATE_EBD);
5506 return OMX_ErrorNone;
5507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005508
5509
Arun Menon906de572013-06-18 17:01:40 -07005510 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5511 mp4StreamType psBits;
5512 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5513 psBits.numBytes = buffer->nFilledLen;
5514 mp4_headerparser.parseHeader(&psBits);
5515 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5516 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5517 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005518 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005519 buffer->nFilledLen,frame_count);
5520 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005521 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005522 not_coded_vop = false;
5523 buffer->nFilledLen = 0;
5524 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525 }
5526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527
Arun Menon906de572013-06-18 17:01:40 -07005528 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005529
Arun Menon906de572013-06-18 17:01:40 -07005530 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005531
Arun Menon906de572013-06-18 17:01:40 -07005532 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005533 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005534 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5535 OMX_COMPONENT_GENERATE_EBD);
5536 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005537 }
5538
Arun Menon906de572013-06-18 17:01:40 -07005539 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540
Surajit Podderd2644d52013-08-28 17:59:06 +05305541 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005542 return OMX_ErrorBadParameter;
5543 }
5544 /* If its first frame, H264 codec and reject is true, then parse the nal
5545 and get the profile. Based on this, reject the clip playback */
5546 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5547 m_reject_avc_1080p_mp) {
5548 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005549 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005550 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5551 NALU_TYPE_SPS);
5552 m_profile = h264_parser->get_profile();
5553 ret = is_video_session_supported();
5554 if (ret) {
5555 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5556 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5557 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5558 m_state = OMX_StateInvalid;
5559 return OMX_ErrorNone;
5560 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005561 }
5562
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005563 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005564 /*for use buffer we need to memcpy the data*/
5565 temp_buffer->buffer_len = buffer->nFilledLen;
5566
5567 if (input_use_buffer) {
5568 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5569 if (arbitrary_bytes) {
5570 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5571 } else {
5572 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5573 buffer->nFilledLen);
5574 }
5575 } else {
5576 return OMX_ErrorBadParameter;
5577 }
5578
5579 }
5580
Vikash Garodia3c47b182013-12-20 18:38:17 +05305581 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5582 set_frame_rate(buffer->nTimeStamp);
5583
Arun Menon906de572013-06-18 17:01:40 -07005584 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5585 frameinfo.client_data = (void *) buffer;
5586 frameinfo.datalen = temp_buffer->buffer_len;
5587 frameinfo.flags = 0;
5588 frameinfo.offset = buffer->nOffset;
5589 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5590 frameinfo.pmem_offset = temp_buffer->offset;
5591 frameinfo.timestamp = buffer->nTimeStamp;
5592 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5593 DEBUG_PRINT_LOW("ETB: dmx enabled");
5594 if (m_demux_entries == 0) {
5595 extract_demux_addr_offsets(buffer);
5596 }
5597
5598 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5599 handle_demux_data(buffer);
5600 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5601 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5602 } else {
5603 frameinfo.desc_addr = NULL;
5604 frameinfo.desc_size = 0;
5605 }
5606 if (!arbitrary_bytes) {
5607 frameinfo.flags |= buffer->nFlags;
5608 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005609
5610#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005611 if (m_debug_timestamp) {
5612 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005613 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005614 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5615 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005616 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005617 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5618 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005619 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620#endif
5621
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005622log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005623
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005624if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005625 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5626 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5627 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628
Arun Menon906de572013-06-18 17:01:40 -07005629 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005630 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005631 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5632 h264_scratch.nFilledLen = 0;
5633 nal_count = 0;
5634 look_ahead_nal = false;
5635 frame_count = 0;
5636 if (m_frame_parser.mutils)
5637 m_frame_parser.mutils->initialize_frame_checking_environment();
5638 m_frame_parser.flush();
5639 h264_last_au_ts = LLONG_MAX;
5640 h264_last_au_flags = 0;
5641 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5642 m_demux_entries = 0;
5643 }
5644 struct v4l2_buffer buf;
5645 struct v4l2_plane plane;
5646 memset( (void *)&buf, 0, sizeof(buf));
5647 memset( (void *)&plane, 0, sizeof(plane));
5648 int rc;
5649 unsigned long print_count;
5650 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005651 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005652 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005653 }
5654 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5655 buf.index = nPortIndex;
5656 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5657 buf.memory = V4L2_MEMORY_USERPTR;
5658 plane.bytesused = temp_buffer->buffer_len;
5659 plane.length = drv_ctx.ip_buf.buffer_size;
5660 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5661 (unsigned long)temp_buffer->offset;
5662 plane.reserved[0] = temp_buffer->pmem_fd;
5663 plane.reserved[1] = temp_buffer->offset;
5664 plane.data_offset = 0;
5665 buf.m.planes = &plane;
5666 buf.length = 1;
5667 if (frameinfo.timestamp >= LLONG_MAX) {
5668 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5669 }
5670 //assumption is that timestamp is in milliseconds
5671 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5672 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5673 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5674 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005675
Arun Menon906de572013-06-18 17:01:40 -07005676 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5677 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005678 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005679 return OMX_ErrorHardware;
5680 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005681 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5682 codec_config_flag = false;
5683 }
Arun Menon906de572013-06-18 17:01:40 -07005684 if (!streaming[OUTPUT_PORT]) {
5685 enum v4l2_buf_type buf_type;
5686 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005687
Arun Menon906de572013-06-18 17:01:40 -07005688 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005689 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005690 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5691 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005692 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005693 streaming[OUTPUT_PORT] = true;
5694 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005695 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005696 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5697 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5698 OMX_COMPONENT_GENERATE_EBD);
5699 return OMX_ErrorBadParameter;
5700 }
5701 }
5702 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5703 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5704 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005705
Arun Menon906de572013-06-18 17:01:40 -07005706 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005707}
5708
5709/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005710 FUNCTION
5711 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005712
Arun Menon906de572013-06-18 17:01:40 -07005713 DESCRIPTION
5714 IL client uses this method to release the frame buffer
5715 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005716
Arun Menon906de572013-06-18 17:01:40 -07005717 PARAMETERS
5718 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005719
Arun Menon906de572013-06-18 17:01:40 -07005720 RETURN VALUE
5721 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005722
Arun Menon906de572013-06-18 17:01:40 -07005723 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005724OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005725 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005726{
Arun Menonbdb80b02013-08-12 17:45:54 -07005727 if (dynamic_buf_mode) {
5728 private_handle_t *handle = NULL;
5729 struct VideoDecoderOutputMetaData *meta;
5730 OMX_U8 *buff = NULL;
5731 unsigned int nPortIndex = 0;
5732
5733 if (!buffer || !buffer->pBuffer) {
5734 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5735 return OMX_ErrorBadParameter;
5736 }
5737
5738 //get the buffer type and fd info
5739 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5740 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005741 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5742
5743 if (!handle) {
5744 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5745 return OMX_ErrorBadParameter;
5746 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005747
5748 //map the buffer handle based on the size set on output port definition.
5749 if (!secure_mode) {
5750 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5751 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5752 } else {
5753 buff = (OMX_U8*) buffer;
5754 }
5755
5756 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5757 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5758 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5759 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5760 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5761 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5762 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5763 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5764 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005765
5766 //Store private handle from GraphicBuffer
5767 native_buffer[nPortIndex].privatehandle = handle;
5768 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770
Arun Menon906de572013-06-18 17:01:40 -07005771 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005772 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005773 return OMX_ErrorInvalidState;
5774 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005775
Arun Menon906de572013-06-18 17:01:40 -07005776 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005777 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005778 return OMX_ErrorIncorrectStateOperation;
5779 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005780
Arun Menon906de572013-06-18 17:01:40 -07005781 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305782 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005783 return OMX_ErrorBadParameter;
5784 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785
Arun Menon906de572013-06-18 17:01:40 -07005786 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005787 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005788 return OMX_ErrorBadPortIndex;
5789 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5792 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5793 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794}
5795/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005796 FUNCTION
5797 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798
Arun Menon906de572013-06-18 17:01:40 -07005799 DESCRIPTION
5800 IL client uses this method to release the frame buffer
5801 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005802
Arun Menon906de572013-06-18 17:01:40 -07005803 PARAMETERS
5804 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005805
Arun Menon906de572013-06-18 17:01:40 -07005806 RETURN VALUE
5807 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808
Arun Menon906de572013-06-18 17:01:40 -07005809 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005810OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005811 OMX_IN OMX_HANDLETYPE hComp,
5812 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813{
Arun Menon906de572013-06-18 17:01:40 -07005814 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5815 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5816 unsigned nPortIndex = 0;
5817 struct vdec_fillbuffer_cmd fillbuffer;
5818 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5819 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005820
Arun Menon906de572013-06-18 17:01:40 -07005821 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822
Arun Menon906de572013-06-18 17:01:40 -07005823 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5824 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005825
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005826 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005827 bufferAdd, bufferAdd->pBuffer);
5828 /*Return back the output buffer to client*/
5829 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005830 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005831 buffer->nFilledLen = 0;
5832 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5833 return OMX_ErrorNone;
5834 }
5835 pending_output_buffers++;
5836 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5837 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5838 if (ptr_respbuffer) {
5839 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5840 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005841
Arun Menon906de572013-06-18 17:01:40 -07005842 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5843 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5844 buffer->nFilledLen = 0;
5845 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5846 pending_output_buffers--;
5847 return OMX_ErrorBadParameter;
5848 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005849
Arun Menon906de572013-06-18 17:01:40 -07005850 int rc = 0;
5851 struct v4l2_buffer buf;
5852 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5853 memset( (void *)&buf, 0, sizeof(buf));
5854 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5855 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005856
Arun Menon906de572013-06-18 17:01:40 -07005857 buf.index = nPortIndex;
5858 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5859 buf.memory = V4L2_MEMORY_USERPTR;
5860 plane[0].bytesused = buffer->nFilledLen;
5861 plane[0].length = drv_ctx.op_buf.buffer_size;
5862 plane[0].m.userptr =
5863 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5864 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5865 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5866 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5867 plane[0].data_offset = 0;
5868 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5869 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5870 plane[extra_idx].bytesused = 0;
5871 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5872 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005873#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005874 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005875#endif
Arun Menon906de572013-06-18 17:01:40 -07005876 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5877 plane[extra_idx].data_offset = 0;
5878 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005879 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005880 return OMX_ErrorBadParameter;
5881 }
5882 buf.m.planes = plane;
5883 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005884 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005885 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5886
Arun Menon906de572013-06-18 17:01:40 -07005887 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5888 if (rc) {
5889 /*TODO: How to handle this case */
5890 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5891 }
Arun Menon906de572013-06-18 17:01:40 -07005892return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005893}
5894
5895/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005896 FUNCTION
5897 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898
Arun Menon906de572013-06-18 17:01:40 -07005899 DESCRIPTION
5900 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901
Arun Menon906de572013-06-18 17:01:40 -07005902 PARAMETERS
5903 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005904
Arun Menon906de572013-06-18 17:01:40 -07005905 RETURN VALUE
5906 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005907
Arun Menon906de572013-06-18 17:01:40 -07005908 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005909OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005910 OMX_IN OMX_CALLBACKTYPE* callbacks,
5911 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912{
5913
Arun Menon906de572013-06-18 17:01:40 -07005914 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005915 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005916 m_cb.EventHandler,m_cb.FillBufferDone);
5917 m_app_data = appData;
5918 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919}
5920
5921/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005922 FUNCTION
5923 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924
Arun Menon906de572013-06-18 17:01:40 -07005925 DESCRIPTION
5926 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005927
Arun Menon906de572013-06-18 17:01:40 -07005928 PARAMETERS
5929 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005930
Arun Menon906de572013-06-18 17:01:40 -07005931 RETURN VALUE
5932 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005933
Arun Menon906de572013-06-18 17:01:40 -07005934 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005935OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5936{
5937#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005938 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005939 delete iDivXDrmDecrypt;
5940 iDivXDrmDecrypt=NULL;
5941 }
5942#endif //_ANDROID_
5943
Shalaj Jain286b0062013-02-21 20:35:48 -08005944 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005945 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005946 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07005947 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005948 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005949 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005950 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005951 }
5952
5953 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005954 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005955 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07005956 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5957 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005958 }
5959#ifdef _ANDROID_ICS_
5960 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5961#endif
5962 }
5963
5964 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005965 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005966 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07005967 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5968 if (m_inp_mem_ptr)
5969 free_input_buffer (i,&m_inp_mem_ptr[i]);
5970 else
5971 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005972 }
5973 }
5974 free_input_buffer_header();
5975 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005976 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005977 free(h264_scratch.pBuffer);
5978 h264_scratch.pBuffer = NULL;
5979 }
5980
Arun Menon906de572013-06-18 17:01:40 -07005981 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005982 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005983 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005984 }
5985
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005986 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005987 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005988 delete (m_frame_parser.mutils);
5989 m_frame_parser.mutils = NULL;
5990 }
5991
Arun Menon906de572013-06-18 17:01:40 -07005992 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005993 free(m_platform_list);
5994 m_platform_list = NULL;
5995 }
Arun Menon906de572013-06-18 17:01:40 -07005996 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997 free(m_vendor_config.pData);
5998 m_vendor_config.pData = NULL;
5999 }
6000
6001 // Reset counters in mesg queues
6002 m_ftb_q.m_size=0;
6003 m_cmd_q.m_size=0;
6004 m_etb_q.m_size=0;
6005 m_ftb_q.m_read = m_ftb_q.m_write =0;
6006 m_cmd_q.m_read = m_cmd_q.m_write =0;
6007 m_etb_q.m_read = m_etb_q.m_write =0;
6008#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006009 if (m_debug_timestamp) {
6010 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006011 }
6012#endif
6013
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006014 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006016 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006017 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006018
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006019 if (m_debug.infile) {
6020 fclose(m_debug.infile);
6021 m_debug.infile = NULL;
6022 }
6023 if (m_debug.outfile) {
6024 fclose(m_debug.outfile);
6025 m_debug.outfile = NULL;
6026 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006028 if (outputExtradataFile)
6029 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006031 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006032 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033}
6034
6035/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006036 FUNCTION
6037 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006038
Arun Menon906de572013-06-18 17:01:40 -07006039 DESCRIPTION
6040 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006041
Arun Menon906de572013-06-18 17:01:40 -07006042 PARAMETERS
6043 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 RETURN VALUE
6046 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006047
Arun Menon906de572013-06-18 17:01:40 -07006048 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006050 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6051 OMX_IN OMX_U32 port,
6052 OMX_IN OMX_PTR appData,
6053 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054{
Arun Menon906de572013-06-18 17:01:40 -07006055 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6056 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6057 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006058
6059#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006060 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6061 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006062#else
Arun Menon906de572013-06-18 17:01:40 -07006063 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006064#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006065 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006066 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006067 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006068 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006070 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006071 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006073 }
6074 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6075 eglGetProcAddress("eglQueryImageKHR");
6076 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6077 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6078 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079#else //with OMX test app
6080 struct temp_egl {
6081 int pmem_fd;
6082 int offset;
6083 };
6084 struct temp_egl *temp_egl_id = NULL;
6085 void * pmemPtr = (void *) eglImage;
6086 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006087 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088 fd = temp_egl_id->pmem_fd;
6089 offset = temp_egl_id->offset;
6090 }
6091#endif
6092 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006093 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006094 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006095 }
6096 pmem_info.pmem_fd = (OMX_U32) fd;
6097 pmem_info.offset = (OMX_U32) offset;
6098 pmem_entry.entry = (void *) &pmem_info;
6099 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6100 pmem_list.entryList = &pmem_entry;
6101 pmem_list.nEntries = 1;
6102 ouput_egl_buffers = true;
6103 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6104 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6105 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006106 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006107 return OMX_ErrorInsufficientResources;
6108 }
6109 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006110}
6111
6112/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006113 FUNCTION
6114 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006115
Arun Menon906de572013-06-18 17:01:40 -07006116 DESCRIPTION
6117 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118
Arun Menon906de572013-06-18 17:01:40 -07006119 PARAMETERS
6120 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006121
Arun Menon906de572013-06-18 17:01:40 -07006122 RETURN VALUE
6123 OMX Error None if everything is successful.
6124 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006125OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006126 OMX_OUT OMX_U8* role,
6127 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006128{
Arun Menon906de572013-06-18 17:01:40 -07006129 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006130
Arun Menon906de572013-06-18 17:01:40 -07006131 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6132 if ((0 == index) && role) {
6133 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006134 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006135 } else {
6136 eRet = OMX_ErrorNoMore;
6137 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006138 }
Arun Menon906de572013-06-18 17:01:40 -07006139 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6140 if ((0 == index) && role) {
6141 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006142 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006143 } else {
6144 eRet = OMX_ErrorNoMore;
6145 }
6146 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6147 if ((0 == index) && role) {
6148 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006149 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006150 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006151 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006152 eRet = OMX_ErrorNoMore;
6153 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006155
Arun Menon906de572013-06-18 17:01:40 -07006156 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6157 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6158 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006159
Shalaj Jain273b3e02012-06-22 19:08:03 -07006160 {
Arun Menon906de572013-06-18 17:01:40 -07006161 if ((0 == index) && role) {
6162 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006163 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006164 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006165 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006166 eRet = OMX_ErrorNoMore;
6167 }
6168 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6169 if ((0 == index) && role) {
6170 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006171 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006172 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006173 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006174 eRet = OMX_ErrorNoMore;
6175 }
6176 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6177 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6178 ) {
6179 if ((0 == index) && role) {
6180 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006181 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006182 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006183 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006184 eRet = OMX_ErrorNoMore;
6185 }
6186 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6187 if ((0 == index) && role) {
6188 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006189 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006190 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006191 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006192 eRet = OMX_ErrorNoMore;
6193 }
6194 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006195 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006196 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006197 }
Arun Menon906de572013-06-18 17:01:40 -07006198 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006199}
6200
6201
6202
6203
6204/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006205 FUNCTION
6206 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006207
Arun Menon906de572013-06-18 17:01:40 -07006208 DESCRIPTION
6209 Checks if entire buffer pool is allocated by IL Client or not.
6210 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211
Arun Menon906de572013-06-18 17:01:40 -07006212 PARAMETERS
6213 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214
Arun Menon906de572013-06-18 17:01:40 -07006215 RETURN VALUE
6216 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006217
Arun Menon906de572013-06-18 17:01:40 -07006218 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219bool omx_vdec::allocate_done(void)
6220{
Arun Menon906de572013-06-18 17:01:40 -07006221 bool bRet = false;
6222 bool bRet_In = false;
6223 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006224
Arun Menon906de572013-06-18 17:01:40 -07006225 bRet_In = allocate_input_done();
6226 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006227
Arun Menon906de572013-06-18 17:01:40 -07006228 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229 bRet = true;
6230 }
Arun Menon906de572013-06-18 17:01:40 -07006231
6232 return bRet;
6233}
6234/* ======================================================================
6235 FUNCTION
6236 omx_vdec::AllocateInputDone
6237
6238 DESCRIPTION
6239 Checks if I/P buffer pool is allocated by IL Client or not.
6240
6241 PARAMETERS
6242 None.
6243
6244 RETURN VALUE
6245 true/false.
6246
6247 ========================================================================== */
6248bool omx_vdec::allocate_input_done(void)
6249{
6250 bool bRet = false;
6251 unsigned i=0;
6252
6253 if (m_inp_mem_ptr == NULL) {
6254 return bRet;
6255 }
6256 if (m_inp_mem_ptr ) {
6257 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6258 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6259 break;
6260 }
6261 }
6262 }
6263 if (i == drv_ctx.ip_buf.actualcount) {
6264 bRet = true;
6265 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6266 }
6267 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6268 m_inp_bPopulated = OMX_TRUE;
6269 }
6270 return bRet;
6271}
6272/* ======================================================================
6273 FUNCTION
6274 omx_vdec::AllocateOutputDone
6275
6276 DESCRIPTION
6277 Checks if entire O/P buffer pool is allocated by IL Client or not.
6278
6279 PARAMETERS
6280 None.
6281
6282 RETURN VALUE
6283 true/false.
6284
6285 ========================================================================== */
6286bool omx_vdec::allocate_output_done(void)
6287{
6288 bool bRet = false;
6289 unsigned j=0;
6290
6291 if (m_out_mem_ptr == NULL) {
6292 return bRet;
6293 }
6294
6295 if (m_out_mem_ptr) {
6296 for (; j < drv_ctx.op_buf.actualcount; j++) {
6297 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6298 break;
6299 }
6300 }
6301 }
6302
6303 if (j == drv_ctx.op_buf.actualcount) {
6304 bRet = true;
6305 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6306 if (m_out_bEnabled)
6307 m_out_bPopulated = OMX_TRUE;
6308 }
6309
6310 return bRet;
6311}
6312
6313/* ======================================================================
6314 FUNCTION
6315 omx_vdec::ReleaseDone
6316
6317 DESCRIPTION
6318 Checks if IL client has released all the buffers.
6319
6320 PARAMETERS
6321 None.
6322
6323 RETURN VALUE
6324 true/false
6325
6326 ========================================================================== */
6327bool omx_vdec::release_done(void)
6328{
6329 bool bRet = false;
6330
6331 if (release_input_done()) {
6332 if (release_output_done()) {
6333 bRet = true;
6334 }
6335 }
6336 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006337}
6338
6339
6340/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006341 FUNCTION
6342 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006343
Arun Menon906de572013-06-18 17:01:40 -07006344 DESCRIPTION
6345 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006346
Arun Menon906de572013-06-18 17:01:40 -07006347 PARAMETERS
6348 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006349
Arun Menon906de572013-06-18 17:01:40 -07006350 RETURN VALUE
6351 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006352
Arun Menon906de572013-06-18 17:01:40 -07006353 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006354bool omx_vdec::release_output_done(void)
6355{
Arun Menon906de572013-06-18 17:01:40 -07006356 bool bRet = false;
6357 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006358
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006359 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006360 if (m_out_mem_ptr) {
6361 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6362 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6363 break;
6364 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006365 }
Arun Menon906de572013-06-18 17:01:40 -07006366 if (j == drv_ctx.op_buf.actualcount) {
6367 m_out_bm_count = 0;
6368 bRet = true;
6369 }
6370 } else {
6371 m_out_bm_count = 0;
6372 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006373 }
Arun Menon906de572013-06-18 17:01:40 -07006374 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006375}
6376/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006377 FUNCTION
6378 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006379
Arun Menon906de572013-06-18 17:01:40 -07006380 DESCRIPTION
6381 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006382
Arun Menon906de572013-06-18 17:01:40 -07006383 PARAMETERS
6384 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006385
Arun Menon906de572013-06-18 17:01:40 -07006386 RETURN VALUE
6387 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006388
Arun Menon906de572013-06-18 17:01:40 -07006389 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006390bool omx_vdec::release_input_done(void)
6391{
Arun Menon906de572013-06-18 17:01:40 -07006392 bool bRet = false;
6393 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006394
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006395 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006396 if (m_inp_mem_ptr) {
6397 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6398 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6399 break;
6400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006401 }
Arun Menon906de572013-06-18 17:01:40 -07006402 if (j==drv_ctx.ip_buf.actualcount) {
6403 bRet = true;
6404 }
6405 } else {
6406 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006407 }
Arun Menon906de572013-06-18 17:01:40 -07006408 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006409}
6410
6411OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006412 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006413{
Arun Menon906de572013-06-18 17:01:40 -07006414 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306415 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006416 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006417 return OMX_ErrorBadParameter;
6418 } else if (output_flush_progress) {
6419 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6420 buffer->nFilledLen = 0;
6421 buffer->nTimeStamp = 0;
6422 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6423 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6424 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006425 }
6426
Arun Menon906de572013-06-18 17:01:40 -07006427 if (m_debug_extradata) {
6428 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006429 DEBUG_PRINT_HIGH("");
6430 DEBUG_PRINT_HIGH("***************************************************");
6431 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6432 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006433 }
6434
6435 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006436 DEBUG_PRINT_HIGH("");
6437 DEBUG_PRINT_HIGH("***************************************************");
6438 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6439 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006440 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006441 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006442
6443
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006444 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006445 buffer, buffer->pBuffer);
6446 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006447
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006448 if (dynamic_buf_mode) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006449 unsigned int nPortIndex = 0;
6450 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006451
6452 if (!secure_mode) {
6453 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6454 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6455 }
6456
6457 //Clear graphic buffer handles in dynamic mode
6458 native_buffer[nPortIndex].privatehandle = NULL;
6459 native_buffer[nPortIndex].nativehandle = NULL;
Arun Menonbdb80b02013-08-12 17:45:54 -07006460 }
Arun Menon906de572013-06-18 17:01:40 -07006461 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006462 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006463 if (!output_flush_progress)
6464 post_event((unsigned)NULL, (unsigned)NULL,
6465 OMX_COMPONENT_GENERATE_EOS_DONE);
6466
6467 if (psource_frame) {
6468 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6469 psource_frame = NULL;
6470 }
6471 if (pdest_frame) {
6472 pdest_frame->nFilledLen = 0;
6473 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6474 (unsigned)NULL);
6475 pdest_frame = NULL;
6476 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006478
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006479 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006480 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006481
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006482 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6483 DEBUG_PRINT_LOW("Processing extradata");
6484 handle_extradata(buffer);
6485 }
6486
Arun Menon906de572013-06-18 17:01:40 -07006487 /* For use buffer we need to copy the data */
6488 if (!output_flush_progress) {
6489 /* This is the error check for non-recoverable errros */
6490 bool is_duplicate_ts_valid = true;
6491 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006492
Arun Menon906de572013-06-18 17:01:40 -07006493 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6494 output_capability == V4L2_PIX_FMT_MPEG2 ||
6495 output_capability == V4L2_PIX_FMT_DIVX ||
6496 output_capability == V4L2_PIX_FMT_DIVX_311)
6497 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006498
Arun Menon906de572013-06-18 17:01:40 -07006499 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6500 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6501 if (mbaff) {
6502 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306503 }
Arun Menon906de572013-06-18 17:01:40 -07006504 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306505
Arun Menon906de572013-06-18 17:01:40 -07006506 if (buffer->nFilledLen > 0) {
6507 time_stamp_dts.get_next_timestamp(buffer,
6508 is_interlaced && is_duplicate_ts_valid);
6509 if (m_debug_timestamp) {
6510 {
6511 OMX_TICKS expected_ts = 0;
6512 m_timestamp_list.pop_min_ts(expected_ts);
6513 if (is_interlaced && is_duplicate_ts_valid) {
6514 m_timestamp_list.pop_min_ts(expected_ts);
6515 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006516 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006517 buffer->nTimeStamp, expected_ts);
6518
6519 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006520 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006521 }
6522 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306523 }
Arun Menon906de572013-06-18 17:01:40 -07006524 } else {
6525 m_inp_err_count++;
6526 time_stamp_dts.remove_time_stamp(
6527 buffer->nTimeStamp,
6528 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306529 }
Arun Menon906de572013-06-18 17:01:40 -07006530
6531
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006532 }
Arun Menon906de572013-06-18 17:01:40 -07006533 if (m_cb.FillBufferDone) {
6534 if (buffer->nFilledLen > 0) {
Arun Menon906de572013-06-18 17:01:40 -07006535 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6536 set_frame_rate(buffer->nTimeStamp);
6537 else if (arbitrary_bytes)
6538 adjust_timestamp(buffer->nTimeStamp);
6539 if (perf_flag) {
6540 if (!proc_frms) {
6541 dec_time.stop();
6542 latency = dec_time.processing_time_us() - latency;
6543 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6544 dec_time.start();
6545 fps_metrics.start();
6546 }
6547 proc_frms++;
6548 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6549 OMX_U64 proc_time = 0;
6550 fps_metrics.stop();
6551 proc_time = fps_metrics.processing_time_us();
6552 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006553 proc_frms, (float)proc_time / 1e6,
6554 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006555 proc_frms = 0;
6556 }
6557 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006558
6559#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006560 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006561
Arun Menon906de572013-06-18 17:01:40 -07006562 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6563 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6564 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6565 buffer->nFilledLen + 3)&(~3));
6566 while (p_extra &&
6567 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006568 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006569 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6570 if (p_extra->eType == OMX_ExtraDataNone) {
6571 break;
6572 }
6573 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6574 }
6575 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006576#endif
Arun Menon906de572013-06-18 17:01:40 -07006577 }
6578 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6579 prev_ts = LLONG_MAX;
6580 rst_prev_ts = true;
6581 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006582
Arun Menon906de572013-06-18 17:01:40 -07006583 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6584 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6585 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006586 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006587 OMX_BUFFERHEADERTYPE *il_buffer;
6588 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6589 if (il_buffer)
6590 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6591 else {
6592 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6593 return OMX_ErrorBadParameter;
6594 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006595 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006596 } else {
6597 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006598 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006599
Praveen Chavancf924182013-12-06 23:16:23 -08006600#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6601 if (m_smoothstreaming_mode) {
6602 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6603 BufferDim_t dim;
6604 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6605 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6606 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6607 if (private_handle) {
6608 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6609 dim.sliceWidth, dim.sliceHeight);
6610 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6611 }
6612 }
6613#endif
6614
Arun Menon906de572013-06-18 17:01:40 -07006615 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006616}
6617
6618OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006619 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006620{
6621
Surajit Podderd2644d52013-08-28 17:59:06 +05306622 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006623 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006624 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006625 }
6626
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006627 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006628 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006629 pending_input_buffers--;
6630
Arun Menon906de572013-06-18 17:01:40 -07006631 if (arbitrary_bytes) {
6632 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006633 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006634 pdest_frame = buffer;
6635 buffer->nFilledLen = 0;
6636 buffer->nTimeStamp = LLONG_MAX;
6637 push_input_buffer (hComp);
6638 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006639 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006640 buffer->nFilledLen = 0;
6641 if (!m_input_free_q.insert_entry((unsigned)buffer,
6642 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006643 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006644 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006645 }
Arun Menon906de572013-06-18 17:01:40 -07006646 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006647 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006648 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006649 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6650 }
6651 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6652 }
6653 return OMX_ErrorNone;
6654}
6655
Shalaj Jain273b3e02012-06-22 19:08:03 -07006656int omx_vdec::async_message_process (void *context, void* message)
6657{
Arun Menon906de572013-06-18 17:01:40 -07006658 omx_vdec* omx = NULL;
6659 struct vdec_msginfo *vdec_msg = NULL;
6660 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6661 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6662 struct vdec_output_frameinfo *output_respbuf = NULL;
6663 int rc=1;
6664 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006665 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006666 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006667 }
Arun Menon906de572013-06-18 17:01:40 -07006668 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006669
Arun Menon906de572013-06-18 17:01:40 -07006670 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006671
Arun Menon906de572013-06-18 17:01:40 -07006672 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006673
Arun Menon906de572013-06-18 17:01:40 -07006674 case VDEC_MSG_EVT_HW_ERROR:
6675 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6676 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6677 break;
6678
6679 case VDEC_MSG_RESP_START_DONE:
6680 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6681 OMX_COMPONENT_GENERATE_START_DONE);
6682 break;
6683
6684 case VDEC_MSG_RESP_STOP_DONE:
6685 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6686 OMX_COMPONENT_GENERATE_STOP_DONE);
6687 break;
6688
6689 case VDEC_MSG_RESP_RESUME_DONE:
6690 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6691 OMX_COMPONENT_GENERATE_RESUME_DONE);
6692 break;
6693
6694 case VDEC_MSG_RESP_PAUSE_DONE:
6695 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6696 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6697 break;
6698
6699 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6700 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6701 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6702 break;
6703 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6704 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6705 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6706 break;
6707 case VDEC_MSG_RESP_INPUT_FLUSHED:
6708 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6709
6710 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6711 vdec_msg->msgdata.input_frame_clientdata; */
6712
6713 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6714 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6715 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306716 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006717 omxhdr = NULL;
6718 vdec_msg->status_code = VDEC_S_EFATAL;
6719 }
6720 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6721 DEBUG_PRINT_HIGH("Unsupported input");
6722 omx->omx_report_error ();
6723 }
6724 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6725 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6726 }
6727 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6728 OMX_COMPONENT_GENERATE_EBD);
6729 break;
6730 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6731 int64_t *timestamp;
6732 timestamp = (int64_t *) malloc(sizeof(int64_t));
6733 if (timestamp) {
6734 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6735 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6736 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006737 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006738 vdec_msg->msgdata.output_frame.time_stamp);
6739 }
6740 break;
6741 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6742 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6743
6744 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6745 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6746 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6747 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6748 vdec_msg->msgdata.output_frame.pic_type);
6749
6750 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306751 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006752 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306753 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006754 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6755 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6756 }
Arun Menon906de572013-06-18 17:01:40 -07006757 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6758 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6759 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6760 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6761 omxhdr->nFlags = 0;
6762
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006763 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006764 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6765 //rc = -1;
6766 }
6767 if (omxhdr->nFilledLen) {
6768 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6769 }
6770 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6771 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6772 } else {
6773 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6774 }
6775 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6776 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6777 }
6778 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6779 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6780 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006781 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006782 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006783 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6784 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6785 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006786 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6787 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6788 omxhdr->nOffset);
6789 }
Arun Menon906de572013-06-18 17:01:40 -07006790 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6791 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006792 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006793 omx->time_stamp_dts.remove_time_stamp(
6794 omxhdr->nTimeStamp,
6795 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6796 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006797 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6798 OMX_COMPONENT_GENERATE_FTB);
6799 break;
6800 }
6801 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6802 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6803 }
6804 vdec_msg->msgdata.output_frame.bufferaddr =
6805 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6806 int format_notably_changed = 0;
6807 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306808 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006809 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6810 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006811 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006812 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6813 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6814 format_notably_changed = 1;
6815 }
6816 }
6817 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6818 vdec_msg->msgdata.output_frame.framesize.left)
6819 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6820 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6821 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6822 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6823 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6824 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6825 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006826 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006827 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6828 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6829 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006830 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006831 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6832 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006833 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6834 omx->drv_ctx.video_resolution.frame_width) {
6835 vdec_msg->msgdata.output_frame.framesize.left = 0;
6836 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6837 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6838 }
6839 }
6840 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6841 omx->drv_ctx.video_resolution.frame_height) {
6842 vdec_msg->msgdata.output_frame.framesize.top = 0;
6843 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6844 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6845 }
6846 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006847 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006848 vdec_msg->msgdata.output_frame.framesize.left,
6849 vdec_msg->msgdata.output_frame.framesize.top,
6850 vdec_msg->msgdata.output_frame.framesize.right,
6851 vdec_msg->msgdata.output_frame.framesize.bottom,
6852 omx->drv_ctx.video_resolution.frame_width,
6853 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006854 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6855 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6856 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6857 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6858 format_notably_changed = 1;
6859 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006860 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006861 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6862 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006863 if (format_notably_changed) {
6864 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306865 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006866 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6867 } else {
6868 if (!omx->client_buffers.update_buffer_req()) {
6869 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6870 }
6871 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6872 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6873 }
6874 }
6875 if (omxhdr->nFilledLen)
6876 omx->prev_n_filled_len = omxhdr->nFilledLen;
6877
6878 output_respbuf = (struct vdec_output_frameinfo *)\
6879 omxhdr->pOutputPortPrivate;
6880 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6881 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6882 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6883 output_respbuf->pic_type = PICTURE_TYPE_I;
6884 }
6885 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6886 output_respbuf->pic_type = PICTURE_TYPE_P;
6887 }
6888 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6889 output_respbuf->pic_type = PICTURE_TYPE_B;
6890 }
6891
6892 if (omx->output_use_buffer)
6893 memcpy ( omxhdr->pBuffer, (void *)
6894 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6895 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6896 vdec_msg->msgdata.output_frame.len);
6897 } else
6898 omxhdr->nFilledLen = 0;
6899 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6900 OMX_COMPONENT_GENERATE_FBD);
6901 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6902 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6903 OMX_COMPONENT_GENERATE_EOS_DONE);
6904 else
6905 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6906 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6907 break;
6908 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006909 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07006910 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6911 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6912 break;
6913 default:
6914 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006915 }
Arun Menon906de572013-06-18 17:01:40 -07006916 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006917}
6918
6919OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006920 OMX_HANDLETYPE hComp,
6921 OMX_BUFFERHEADERTYPE *buffer
6922 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006923{
Arun Menon906de572013-06-18 17:01:40 -07006924 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006925 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006926
Arun Menon906de572013-06-18 17:01:40 -07006927 if (buffer == NULL) {
6928 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006929 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006930 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6931 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07006932 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6933
6934 /* return zero length and not an EOS buffer */
6935 /* return buffer if input flush in progress */
6936 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6937 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006938 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07006939 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6940 return OMX_ErrorNone;
6941 }
6942
6943 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006944 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07006945 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006946 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07006947 push_input_buffer (hComp);
6948 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006949 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006950 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6951 (unsigned)NULL)) {
6952 return OMX_ErrorBadParameter;
6953 }
6954 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006955
6956
Arun Menon906de572013-06-18 17:01:40 -07006957 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006958}
6959
6960OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6961{
Arun Menon906de572013-06-18 17:01:40 -07006962 unsigned address,p2,id;
6963 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006964
Arun Menon906de572013-06-18 17:01:40 -07006965 if (pdest_frame == NULL || psource_frame == NULL) {
6966 /*Check if we have a destination buffer*/
6967 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006968 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006969 if (m_input_free_q.m_size) {
6970 m_input_free_q.pop_entry(&address,&p2,&id);
6971 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6972 pdest_frame->nFilledLen = 0;
6973 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006974 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07006975 }
6976 }
6977
6978 /*Check if we have a destination buffer*/
6979 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006980 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006981 if (m_input_pending_q.m_size) {
6982 m_input_pending_q.pop_entry(&address,&p2,&id);
6983 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006984 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07006985 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006986 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07006987 psource_frame->nFlags,psource_frame->nFilledLen);
6988
6989 }
6990 }
6991
Shalaj Jain273b3e02012-06-22 19:08:03 -07006992 }
6993
Arun Menon906de572013-06-18 17:01:40 -07006994 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6995 switch (codec_type_parse) {
6996 case CODEC_TYPE_MPEG4:
6997 case CODEC_TYPE_H263:
6998 case CODEC_TYPE_MPEG2:
6999 ret = push_input_sc_codec(hComp);
7000 break;
7001 case CODEC_TYPE_H264:
7002 ret = push_input_h264(hComp);
7003 break;
7004 case CODEC_TYPE_VC1:
7005 ret = push_input_vc1(hComp);
7006 break;
7007 default:
7008 break;
7009 }
7010 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007011 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007012 omx_report_error ();
7013 break;
7014 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007015 }
7016
Arun Menon906de572013-06-18 17:01:40 -07007017 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007018}
7019
7020OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7021{
Arun Menon906de572013-06-18 17:01:40 -07007022 OMX_U32 partial_frame = 1;
7023 OMX_BOOL generate_ebd = OMX_TRUE;
7024 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007025
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007026 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007027 psource_frame,psource_frame->nTimeStamp);
7028 if (m_frame_parser.parse_sc_frame(psource_frame,
7029 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007030 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007031 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007032 }
Arun Menon906de572013-06-18 17:01:40 -07007033
7034 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007035 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007036 pdest_frame->nFilledLen,psource_frame,frame_count);
7037
7038
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007039 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007040 /*First Parsed buffer will have only header Hence skip*/
7041 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007042 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007043
7044 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7045 codec_type_parse == CODEC_TYPE_DIVX) {
7046 mp4StreamType psBits;
7047 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7048 psBits.numBytes = pdest_frame->nFilledLen;
7049 mp4_headerparser.parseHeader(&psBits);
7050 }
7051
7052 frame_count++;
7053 } else {
7054 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7055 if (pdest_frame->nFilledLen) {
7056 /*Push the frame to the Decoder*/
7057 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7058 return OMX_ErrorBadParameter;
7059 }
7060 frame_count++;
7061 pdest_frame = NULL;
7062
7063 if (m_input_free_q.m_size) {
7064 m_input_free_q.pop_entry(&address,&p2,&id);
7065 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7066 pdest_frame->nFilledLen = 0;
7067 }
7068 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007069 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007070 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7071 (unsigned)NULL);
7072 pdest_frame = NULL;
7073 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007074 }
Arun Menon906de572013-06-18 17:01:40 -07007075 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007076 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007077 /*Check if Destination Buffer is full*/
7078 if (pdest_frame->nAllocLen ==
7079 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007080 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007081 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007082 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007083 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007084
Arun Menon906de572013-06-18 17:01:40 -07007085 if (psource_frame->nFilledLen == 0) {
7086 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7087 if (pdest_frame) {
7088 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007089 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007090 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007091 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007092 pdest_frame->nFilledLen,frame_count++);
7093 /*Push the frame to the Decoder*/
7094 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7095 return OMX_ErrorBadParameter;
7096 }
7097 frame_count++;
7098 pdest_frame = NULL;
7099 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007100 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007101 generate_ebd = OMX_FALSE;
7102 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007103 }
Arun Menon906de572013-06-18 17:01:40 -07007104 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007105 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007106 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7107 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007108
Arun Menon906de572013-06-18 17:01:40 -07007109 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007110 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007111 m_input_pending_q.pop_entry(&address,&p2,&id);
7112 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007113 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007114 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007115 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007116 psource_frame->nFlags,psource_frame->nFilledLen);
7117 }
7118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007119 }
Arun Menon906de572013-06-18 17:01:40 -07007120 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007121}
7122
7123OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7124{
Arun Menon906de572013-06-18 17:01:40 -07007125 OMX_U32 partial_frame = 1;
7126 unsigned address = 0, p2 = 0, id = 0;
7127 OMX_BOOL isNewFrame = OMX_FALSE;
7128 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007129
Arun Menon906de572013-06-18 17:01:40 -07007130 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007131 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007132 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007133 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007134 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007135 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007136 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007137 if (h264_scratch.nFilledLen && look_ahead_nal) {
7138 look_ahead_nal = false;
7139 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7140 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007141 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7142 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7143 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007144 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007145 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007146 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007147 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007148 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007149 }
Arun Menon906de572013-06-18 17:01:40 -07007150 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007151
7152 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7153 in EOS flag getting associated with the destination
7154 */
7155 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7156 pdest_frame->nFilledLen) {
7157 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7158 generate_ebd = OMX_FALSE;
7159 }
7160
Arun Menon906de572013-06-18 17:01:40 -07007161 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007162 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007163 if (m_frame_parser.parse_sc_frame(psource_frame,
7164 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007165 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007166 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007167 }
Arun Menon906de572013-06-18 17:01:40 -07007168 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007169 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007170 if (m_frame_parser.parse_h264_nallength(psource_frame,
7171 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007172 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007173 return OMX_ErrorBadParameter;
7174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007176
Arun Menon906de572013-06-18 17:01:40 -07007177 if (partial_frame == 0) {
7178 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007179 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007180 nal_count++;
7181 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7182 h264_scratch.nFlags = psource_frame->nFlags;
7183 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007184 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007185 if (h264_scratch.nFilledLen) {
7186 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7187 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007188#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007189 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7190 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7191 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7192 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7193 // If timeinfo is present frame info from SEI is already processed
7194 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7195 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007196#endif
Arun Menon906de572013-06-18 17:01:40 -07007197 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7198 nal_count++;
7199 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7200 pdest_frame->nTimeStamp = h264_last_au_ts;
7201 pdest_frame->nFlags = h264_last_au_flags;
7202#ifdef PANSCAN_HDLR
7203 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7204 h264_parser->update_panscan_data(h264_last_au_ts);
7205#endif
7206 }
7207 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7208 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7209 h264_last_au_ts = h264_scratch.nTimeStamp;
7210 h264_last_au_flags = h264_scratch.nFlags;
7211#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7212 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7213 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7214 if (!VALID_TS(h264_last_au_ts))
7215 h264_last_au_ts = ts_in_sei;
7216 }
7217#endif
7218 } else
7219 h264_last_au_ts = LLONG_MAX;
7220 }
7221
7222 if (!isNewFrame) {
7223 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7224 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007225 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007226 h264_scratch.nFilledLen);
7227 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7228 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7229 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7230 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7231 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7232 h264_scratch.nFilledLen = 0;
7233 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007234 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007235 return OMX_ErrorBadParameter;
7236 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007237 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007238 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007240 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007241 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007242 pdest_frame->nFilledLen,frame_count++);
7243
7244 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007245 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007246 look_ahead_nal = false;
7247 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7248 h264_scratch.nFilledLen) {
7249 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7250 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7251 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7252 h264_scratch.nFilledLen = 0;
7253 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007254 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007255 return OMX_ErrorBadParameter;
7256 }
7257 } else {
7258 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007259 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007260 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7261 }
7262 /*Push the frame to the Decoder*/
7263 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7264 return OMX_ErrorBadParameter;
7265 }
7266 //frame_count++;
7267 pdest_frame = NULL;
7268 if (m_input_free_q.m_size) {
7269 m_input_free_q.pop_entry(&address,&p2,&id);
7270 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007271 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007272 pdest_frame->nFilledLen = 0;
7273 pdest_frame->nFlags = 0;
7274 pdest_frame->nTimeStamp = LLONG_MAX;
7275 }
7276 }
7277 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007278 }
Arun Menon906de572013-06-18 17:01:40 -07007279 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007280 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007281 /*Check if Destination Buffer is full*/
7282 if (h264_scratch.nAllocLen ==
7283 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007284 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007285 return OMX_ErrorStreamCorrupt;
7286 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007287 }
Arun Menon906de572013-06-18 17:01:40 -07007288
7289 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007290 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007291
7292 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7293 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007294 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007295 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7296 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007297 if(pdest_frame->nFilledLen == 0) {
7298 /* No residual frame from before, send whatever
7299 * we have left */
7300 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7301 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7302 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7303 h264_scratch.nFilledLen = 0;
7304 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7305 } else {
7306 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7307 if(!isNewFrame) {
7308 /* Have a residual frame, but we know that the
7309 * AU in this frame is belonging to whatever
7310 * frame we had left over. So append it */
7311 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7312 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7313 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7314 h264_scratch.nFilledLen = 0;
7315 pdest_frame->nTimeStamp = h264_last_au_ts;
7316 } else {
7317 /* Completely new frame, let's just push what
7318 * we have now. The resulting EBD would trigger
7319 * another push */
7320 generate_ebd = OMX_FALSE;
7321 pdest_frame->nTimeStamp = h264_last_au_ts;
7322 h264_last_au_ts = h264_scratch.nTimeStamp;
7323 }
7324 }
Arun Menon906de572013-06-18 17:01:40 -07007325 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007326 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007327 return OMX_ErrorBadParameter;
7328 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007329
7330 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7331 if(generate_ebd == OMX_TRUE) {
7332 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7333 }
Arun Menon906de572013-06-18 17:01:40 -07007334
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007335 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007336 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007337 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007338#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7339 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7340 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7341 if (!VALID_TS(pdest_frame->nTimeStamp))
7342 pdest_frame->nTimeStamp = ts_in_sei;
7343 }
7344#endif
7345 /*Push the frame to the Decoder*/
7346 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7347 return OMX_ErrorBadParameter;
7348 }
7349 frame_count++;
7350 pdest_frame = NULL;
7351 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007352 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007353 pdest_frame,h264_scratch.nFilledLen);
7354 generate_ebd = OMX_FALSE;
7355 }
7356 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007357 }
Arun Menon906de572013-06-18 17:01:40 -07007358 if (generate_ebd && !psource_frame->nFilledLen) {
7359 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7360 psource_frame = NULL;
7361 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007362 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007363 m_input_pending_q.pop_entry(&address,&p2,&id);
7364 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007365 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007366 psource_frame->nFlags,psource_frame->nFilledLen);
7367 }
7368 }
7369 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007370}
7371
7372OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7373{
7374 OMX_U8 *buf, *pdest;
7375 OMX_U32 partial_frame = 1;
7376 OMX_U32 buf_len, dest_len;
7377
Arun Menon906de572013-06-18 17:01:40 -07007378 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007379 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007380 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007381 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007382 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007383 buf = psource_frame->pBuffer;
7384 buf_len = psource_frame->nFilledLen;
7385
7386 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007387 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007388 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007389 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007391 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007392 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007393 return OMX_ErrorStreamCorrupt;
7394 }
Arun Menon906de572013-06-18 17:01:40 -07007395 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007396 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7397 pdest_frame->nOffset;
7398 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007399 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007400
Arun Menon906de572013-06-18 17:01:40 -07007401 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007402 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007403 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007404 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007405 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7406 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7407 }
7408 }
7409 }
7410
Arun Menon906de572013-06-18 17:01:40 -07007411 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007412 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007413 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007414 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007415 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007416 return OMX_ErrorBadParameter;
7417 }
Arun Menon906de572013-06-18 17:01:40 -07007418 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007419
7420 case VC1_SP_MP_RCV:
7421 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007422 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007423 return OMX_ErrorBadParameter;
7424 }
7425 return OMX_ErrorNone;
7426}
7427
David Ng38e2d232013-03-15 20:05:58 -07007428#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007429bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007430 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007431{
Arun Menon906de572013-06-18 17:01:40 -07007432 struct pmem_allocation allocation;
7433 allocation.size = buffer_size;
7434 allocation.align = clip2(alignment);
7435 if (allocation.align < 4096) {
7436 allocation.align = 4096;
7437 }
7438 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007439 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007440 allocation.align, allocation.size);
7441 return false;
7442 }
7443 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007444}
David Ng38e2d232013-03-15 20:05:58 -07007445#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446#ifdef USE_ION
7447int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007448 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7449 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450{
Arun Menon906de572013-06-18 17:01:40 -07007451 int fd = -EINVAL;
7452 int rc = -EINVAL;
7453 int ion_dev_flag;
7454 struct vdec_ion ion_buf_info;
7455 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007457 return -EINVAL;
7458 }
7459 ion_dev_flag = O_RDONLY;
7460 fd = open (MEM_DEVICE, ion_dev_flag);
7461 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007462 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007463 return fd;
7464 }
7465 alloc_data->flags = 0;
7466 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7467 alloc_data->flags |= ION_FLAG_CACHED;
7468 }
7469 alloc_data->len = buffer_size;
7470 alloc_data->align = clip2(alignment);
7471 if (alloc_data->align < 4096) {
7472 alloc_data->align = 4096;
7473 }
7474 if ((secure_mode) && (flag & ION_SECURE))
7475 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007476
Arun Menon906de572013-06-18 17:01:40 -07007477 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307478 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007479 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7480 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7481 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007482 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007483 alloc_data->handle = NULL;
7484 close(fd);
7485 fd = -ENOMEM;
7486 return fd;
7487 }
7488 fd_data->handle = alloc_data->handle;
7489 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7490 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007491 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007492 ion_buf_info.ion_alloc_data = *alloc_data;
7493 ion_buf_info.ion_device_fd = fd;
7494 ion_buf_info.fd_ion_data = *fd_data;
7495 free_ion_memory(&ion_buf_info);
7496 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007497 fd = -ENOMEM;
7498 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007499
Arun Menon906de572013-06-18 17:01:40 -07007500 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007501}
7502
Arun Menon906de572013-06-18 17:01:40 -07007503void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7504{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007505
Arun Menon906de572013-06-18 17:01:40 -07007506 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007507 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007508 return;
7509 }
7510 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7511 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007512 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007513 }
7514 close(buf_ion_info->ion_device_fd);
7515 buf_ion_info->ion_device_fd = -1;
7516 buf_ion_info->ion_alloc_data.handle = NULL;
7517 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518}
7519#endif
7520void omx_vdec::free_output_buffer_header()
7521{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007522 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007523 output_use_buffer = false;
7524 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007525
Arun Menon906de572013-06-18 17:01:40 -07007526 if (m_out_mem_ptr) {
7527 free (m_out_mem_ptr);
7528 m_out_mem_ptr = NULL;
7529 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007530
Arun Menon906de572013-06-18 17:01:40 -07007531 if (m_platform_list) {
7532 free(m_platform_list);
7533 m_platform_list = NULL;
7534 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007535
Arun Menon906de572013-06-18 17:01:40 -07007536 if (drv_ctx.ptr_respbuffer) {
7537 free (drv_ctx.ptr_respbuffer);
7538 drv_ctx.ptr_respbuffer = NULL;
7539 }
7540 if (drv_ctx.ptr_outputbuffer) {
7541 free (drv_ctx.ptr_outputbuffer);
7542 drv_ctx.ptr_outputbuffer = NULL;
7543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544#ifdef USE_ION
7545 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007546 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007547 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007548 drv_ctx.op_buf_ion_info = NULL;
7549 }
7550#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007551 if (out_dynamic_list) {
7552 free(out_dynamic_list);
7553 out_dynamic_list = NULL;
7554 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007555}
7556
7557void omx_vdec::free_input_buffer_header()
7558{
7559 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007560 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007561 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007562 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007563 free (m_inp_heap_ptr);
7564 m_inp_heap_ptr = NULL;
7565 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007566
Arun Menon906de572013-06-18 17:01:40 -07007567 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007568 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007569 free (m_phdr_pmem_ptr);
7570 m_phdr_pmem_ptr = NULL;
7571 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007572 }
Arun Menon906de572013-06-18 17:01:40 -07007573 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007574 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007575 free (m_inp_mem_ptr);
7576 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007577 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007578 /* We just freed all the buffer headers, every thing in m_input_free_q,
7579 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007580 while (m_input_free_q.m_size) {
7581 unsigned address, p2, id;
7582 m_input_free_q.pop_entry(&address, &p2, &id);
7583 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007584 while (m_input_pending_q.m_size) {
7585 unsigned address, p2, id;
7586 m_input_pending_q.pop_entry(&address, &p2, &id);
7587 }
7588 pdest_frame = NULL;
7589 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007590 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007591 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007592 free (drv_ctx.ptr_inputbuffer);
7593 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007594 }
7595#ifdef USE_ION
7596 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007597 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007598 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007599 drv_ctx.ip_buf_ion_info = NULL;
7600 }
7601#endif
7602}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007603
7604int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007605{
Arun Menon906de572013-06-18 17:01:40 -07007606 enum v4l2_buf_type btype;
7607 int rc = 0;
7608 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007609
Arun Menon906de572013-06-18 17:01:40 -07007610 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7611 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7612 v4l2_port = OUTPUT_PORT;
7613 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7614 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7615 v4l2_port = CAPTURE_PORT;
7616 } else if (port == OMX_ALL) {
7617 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7618 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007619
Arun Menon906de572013-06-18 17:01:40 -07007620 if (!rc_input)
7621 return rc_input;
7622 else
7623 return rc_output;
7624 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007625
Arun Menon906de572013-06-18 17:01:40 -07007626 if (!streaming[v4l2_port]) {
7627 // already streamed off, warn and move on
7628 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7629 " which is already streamed off", v4l2_port);
7630 return 0;
7631 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007632
Arun Menon906de572013-06-18 17:01:40 -07007633 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007634
Arun Menon906de572013-06-18 17:01:40 -07007635 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7636 if (rc) {
7637 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007638 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007639 } else {
7640 streaming[v4l2_port] = false;
7641 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007642
Arun Menon906de572013-06-18 17:01:40 -07007643 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007644}
7645
7646OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7647{
Arun Menon906de572013-06-18 17:01:40 -07007648 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7649 struct v4l2_requestbuffers bufreq;
7650 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7651 struct v4l2_format fmt;
7652 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007653 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007654 buffer_prop->actualcount, buffer_prop->buffer_size);
7655 bufreq.memory = V4L2_MEMORY_USERPTR;
7656 bufreq.count = 1;
7657 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7658 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7659 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7660 fmt.fmt.pix_mp.pixelformat = output_capability;
7661 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7662 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7663 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7664 fmt.fmt.pix_mp.pixelformat = capture_capability;
7665 } else {
7666 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007667 }
Arun Menon906de572013-06-18 17:01:40 -07007668 if (eRet==OMX_ErrorNone) {
7669 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007670 }
Arun Menon906de572013-06-18 17:01:40 -07007671 if (ret) {
7672 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7673 /*TODO: How to handle this case */
7674 eRet = OMX_ErrorInsufficientResources;
7675 return eRet;
7676 } else {
7677 buffer_prop->actualcount = bufreq.count;
7678 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007679 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007680 }
Arun Menon906de572013-06-18 17:01:40 -07007681 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7682 buffer_prop->actualcount, buffer_prop->buffer_size);
7683
7684 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7685 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7686
7687 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7688
7689 update_resolution(fmt.fmt.pix_mp.width,
7690 fmt.fmt.pix_mp.height,
7691 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7692 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7693 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7694 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007695 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007696
7697 if (ret) {
7698 /*TODO: How to handle this case */
7699 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7700 eRet = OMX_ErrorInsufficientResources;
7701 } else {
7702 int extra_idx = 0;
7703
7704 eRet = is_video_session_supported();
7705 if (eRet)
7706 return eRet;
7707
7708 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7709 buf_size = buffer_prop->buffer_size;
7710 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7711 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7712 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7713 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007714 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007715 return OMX_ErrorBadParameter;
7716 }
7717 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7718 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7719 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7720 }
7721 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7722 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7723 }
7724 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7725 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007726 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007727 client_extra_data_size);
7728 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307729 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7730 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7731 DEBUG_PRINT_HIGH("framepack extradata enabled");
7732 }
Arun Menon906de572013-06-18 17:01:40 -07007733 if (client_extra_data_size) {
7734 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7735 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7736 }
7737 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7738 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7739 drv_ctx.extradata_info.buffer_size = extra_data_size;
7740 buf_size += client_extra_data_size;
7741 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7742 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7743 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7744 if (in_reconfig) // BufReq will be set to driver when port is disabled
7745 buffer_prop->buffer_size = buf_size;
7746 else if (buf_size != buffer_prop->buffer_size) {
7747 buffer_prop->buffer_size = buf_size;
7748 eRet = set_buffer_req(buffer_prop);
7749 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007750 }
Arun Menon906de572013-06-18 17:01:40 -07007751 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7752 buffer_prop->actualcount, buffer_prop->buffer_size);
7753 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007754}
7755
7756OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7757{
Arun Menon906de572013-06-18 17:01:40 -07007758 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7759 unsigned buf_size = 0;
7760 struct v4l2_format fmt;
7761 struct v4l2_requestbuffers bufreq;
7762 int ret;
7763 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7764 buffer_prop->actualcount, buffer_prop->buffer_size);
7765 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7766 if (buf_size != buffer_prop->buffer_size) {
7767 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7768 buffer_prop->buffer_size, buf_size);
7769 eRet = OMX_ErrorBadParameter;
7770 } else {
7771 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7772 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007773
Arun Menon906de572013-06-18 17:01:40 -07007774 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7775 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7776 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007777 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007778 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7779 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7780 fmt.fmt.pix_mp.pixelformat = capture_capability;
7781 } else {
7782 eRet = OMX_ErrorBadParameter;
7783 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007784
Arun Menon906de572013-06-18 17:01:40 -07007785 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7786 if (ret) {
7787 /*TODO: How to handle this case */
7788 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7789 eRet = OMX_ErrorInsufficientResources;
7790 }
7791
7792 bufreq.memory = V4L2_MEMORY_USERPTR;
7793 bufreq.count = buffer_prop->actualcount;
7794 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7795 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7796 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7797 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7798 } else {
7799 eRet = OMX_ErrorBadParameter;
7800 }
7801
7802 if (eRet==OMX_ErrorNone) {
7803 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7804 }
7805
7806 if (ret) {
7807 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7808 /*TODO: How to handle this case */
7809 eRet = OMX_ErrorInsufficientResources;
7810 } else if (bufreq.count < buffer_prop->actualcount) {
7811 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7812 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7813 buffer_prop->actualcount, bufreq.count);
7814 eRet = OMX_ErrorInsufficientResources;
7815 } else {
7816 if (!client_buffers.update_buffer_req()) {
7817 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7818 eRet = OMX_ErrorInsufficientResources;
7819 }
7820 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007821 }
Arun Menon906de572013-06-18 17:01:40 -07007822 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007823}
7824
Shalaj Jain273b3e02012-06-22 19:08:03 -07007825OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7826{
Arun Menon906de572013-06-18 17:01:40 -07007827 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7828 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007829}
7830
7831OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7832{
Arun Menon906de572013-06-18 17:01:40 -07007833 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7834 if (!portDefn) {
7835 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007836 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007837 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007838 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7839 portDefn->nSize = sizeof(portDefn);
7840 portDefn->eDomain = OMX_PortDomainVideo;
7841 if (drv_ctx.frame_rate.fps_denominator > 0)
7842 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7843 drv_ctx.frame_rate.fps_denominator;
7844 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007845 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007846 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007847 }
Arun Menon906de572013-06-18 17:01:40 -07007848 if (0 == portDefn->nPortIndex) {
7849 portDefn->eDir = OMX_DirInput;
7850 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7851 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7852 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7853 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7854 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7855 portDefn->bEnabled = m_inp_bEnabled;
7856 portDefn->bPopulated = m_inp_bPopulated;
7857 } else if (1 == portDefn->nPortIndex) {
7858 unsigned int buf_size = 0;
7859 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007860 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007861 return OMX_ErrorHardware;
7862 }
7863 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007864 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007865 return OMX_ErrorHardware;
7866 }
7867 portDefn->nBufferSize = buf_size;
7868 portDefn->eDir = OMX_DirOutput;
7869 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7870 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7871 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7872 portDefn->bEnabled = m_out_bEnabled;
7873 portDefn->bPopulated = m_out_bPopulated;
7874 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007875 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007876 return OMX_ErrorHardware;
7877 }
7878 } else {
7879 portDefn->eDir = OMX_DirMax;
7880 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7881 (int)portDefn->nPortIndex);
7882 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007883 }
Arun Menon906de572013-06-18 17:01:40 -07007884 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7885 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7886 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7887 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307888 if (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) {
7889 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
7890 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
7891 }
7892 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
7893 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
7894 portDefn->nPortIndex,
7895 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07007896 portDefn->format.video.nFrameHeight,
7897 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307898 portDefn->format.video.nSliceHeight,
7899 portDefn->format.video.eColorFormat,
7900 portDefn->nBufferSize,
7901 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007902
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307903 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007904}
7905
7906OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7907{
Arun Menon906de572013-06-18 17:01:40 -07007908 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7909 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7910 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007911
Arun Menon906de572013-06-18 17:01:40 -07007912 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007913 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07007914 int nBufHdrSize = 0;
7915 int nPlatformEntrySize = 0;
7916 int nPlatformListSize = 0;
7917 int nPMEMInfoSize = 0;
7918 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7919 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7920 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007921
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007922 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007923 drv_ctx.op_buf.actualcount);
7924 nBufHdrSize = drv_ctx.op_buf.actualcount *
7925 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007926
Arun Menon906de572013-06-18 17:01:40 -07007927 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7928 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7929 nPlatformListSize = drv_ctx.op_buf.actualcount *
7930 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7931 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7932 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007933
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007934 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07007935 sizeof(OMX_BUFFERHEADERTYPE),
7936 nPMEMInfoSize,
7937 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007938 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07007939 m_out_bm_count);
7940 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7941 // Alloc mem for platform specific info
7942 char *pPtr=NULL;
7943 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7944 nPMEMInfoSize,1);
7945 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7946 calloc (sizeof(struct vdec_bufferpayload),
7947 drv_ctx.op_buf.actualcount);
7948 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7949 calloc (sizeof (struct vdec_output_frameinfo),
7950 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007951#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007952 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7953 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007954#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007955 if (dynamic_buf_mode) {
7956 out_dynamic_list = (struct dynamic_buf_list *) \
7957 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7958 }
Arun Menon906de572013-06-18 17:01:40 -07007959 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7960 && drv_ctx.ptr_respbuffer) {
7961 bufHdr = m_out_mem_ptr;
7962 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7963 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7964 (((char *) m_platform_list) + nPlatformListSize);
7965 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7966 (((char *) m_platform_entry) + nPlatformEntrySize);
7967 pPlatformList = m_platform_list;
7968 pPlatformEntry = m_platform_entry;
7969 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007970
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007971 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007972
Arun Menon906de572013-06-18 17:01:40 -07007973 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007974 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07007975 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007976 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07007977 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7978 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7979 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7980 // Set the values when we determine the right HxW param
7981 bufHdr->nAllocLen = 0;
7982 bufHdr->nFilledLen = 0;
7983 bufHdr->pAppPrivate = NULL;
7984 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7985 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7986 pPlatformEntry->entry = pPMEMInfo;
7987 // Initialize the Platform List
7988 pPlatformList->nEntries = 1;
7989 pPlatformList->entryList = pPlatformEntry;
7990 // Keep pBuffer NULL till vdec is opened
7991 bufHdr->pBuffer = NULL;
7992 pPMEMInfo->offset = 0;
7993 pPMEMInfo->pmem_fd = 0;
7994 bufHdr->pPlatformPrivate = pPlatformList;
7995 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007996#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007997 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998#endif
Arun Menon906de572013-06-18 17:01:40 -07007999 /*Create a mapping between buffers*/
8000 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8001 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8002 &drv_ctx.ptr_outputbuffer[i];
8003 // Move the buffer and buffer header pointers
8004 bufHdr++;
8005 pPMEMInfo++;
8006 pPlatformEntry++;
8007 pPlatformList++;
8008 }
8009 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008010 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008011 m_out_mem_ptr, pPtr);
8012 if (m_out_mem_ptr) {
8013 free(m_out_mem_ptr);
8014 m_out_mem_ptr = NULL;
8015 }
8016 if (pPtr) {
8017 free(pPtr);
8018 pPtr = NULL;
8019 }
8020 if (drv_ctx.ptr_outputbuffer) {
8021 free(drv_ctx.ptr_outputbuffer);
8022 drv_ctx.ptr_outputbuffer = NULL;
8023 }
8024 if (drv_ctx.ptr_respbuffer) {
8025 free(drv_ctx.ptr_respbuffer);
8026 drv_ctx.ptr_respbuffer = NULL;
8027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008028#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008029 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008030 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008031 free(drv_ctx.op_buf_ion_info);
8032 drv_ctx.op_buf_ion_info = NULL;
8033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008034#endif
Arun Menon906de572013-06-18 17:01:40 -07008035 eRet = OMX_ErrorInsufficientResources;
8036 }
8037 } else {
8038 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008039 }
Arun Menon906de572013-06-18 17:01:40 -07008040 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008041}
8042
8043void omx_vdec::complete_pending_buffer_done_cbs()
8044{
Arun Menon906de572013-06-18 17:01:40 -07008045 unsigned p1;
8046 unsigned p2;
8047 unsigned ident;
8048 omx_cmd_queue tmp_q, pending_bd_q;
8049 pthread_mutex_lock(&m_lock);
8050 // pop all pending GENERATE FDB from ftb queue
8051 while (m_ftb_q.m_size) {
8052 m_ftb_q.pop_entry(&p1,&p2,&ident);
8053 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8054 pending_bd_q.insert_entry(p1,p2,ident);
8055 } else {
8056 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008057 }
Arun Menon906de572013-06-18 17:01:40 -07008058 }
8059 //return all non GENERATE FDB to ftb queue
8060 while (tmp_q.m_size) {
8061 tmp_q.pop_entry(&p1,&p2,&ident);
8062 m_ftb_q.insert_entry(p1,p2,ident);
8063 }
8064 // pop all pending GENERATE EDB from etb queue
8065 while (m_etb_q.m_size) {
8066 m_etb_q.pop_entry(&p1,&p2,&ident);
8067 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8068 pending_bd_q.insert_entry(p1,p2,ident);
8069 } else {
8070 tmp_q.insert_entry(p1,p2,ident);
8071 }
8072 }
8073 //return all non GENERATE FDB to etb queue
8074 while (tmp_q.m_size) {
8075 tmp_q.pop_entry(&p1,&p2,&ident);
8076 m_etb_q.insert_entry(p1,p2,ident);
8077 }
8078 pthread_mutex_unlock(&m_lock);
8079 // process all pending buffer dones
8080 while (pending_bd_q.m_size) {
8081 pending_bd_q.pop_entry(&p1,&p2,&ident);
8082 switch (ident) {
8083 case OMX_COMPONENT_GENERATE_EBD:
8084 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008085 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008086 omx_report_error ();
8087 }
8088 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008089
Arun Menon906de572013-06-18 17:01:40 -07008090 case OMX_COMPONENT_GENERATE_FBD:
8091 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008092 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008093 omx_report_error ();
8094 }
8095 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008096 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008098}
8099
8100void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8101{
Arun Menon906de572013-06-18 17:01:40 -07008102 OMX_U32 new_frame_interval = 0;
8103 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8104 && llabs(act_timestamp - prev_ts) > 2000) {
8105 new_frame_interval = client_set_fps ? frm_int :
8106 llabs(act_timestamp - prev_ts);
8107 if (new_frame_interval < frm_int || frm_int == 0) {
8108 frm_int = new_frame_interval;
8109 if (frm_int) {
8110 drv_ctx.frame_rate.fps_numerator = 1e6;
8111 drv_ctx.frame_rate.fps_denominator = frm_int;
8112 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8113 frm_int, drv_ctx.frame_rate.fps_numerator /
8114 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008115
Arun Menon906de572013-06-18 17:01:40 -07008116 /* We need to report the difference between this FBD and the previous FBD
8117 * back to the driver for clock scaling purposes. */
8118 struct v4l2_outputparm oparm;
8119 /*XXX: we're providing timing info as seconds per frame rather than frames
8120 * per second.*/
8121 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8122 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008123
Arun Menon906de572013-06-18 17:01:40 -07008124 struct v4l2_streamparm sparm;
8125 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8126 sparm.parm.output = oparm;
8127 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8128 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8129 performance might be affected");
8130 }
8131
8132 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008133 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008134 }
Arun Menon906de572013-06-18 17:01:40 -07008135 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008136}
8137
8138void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8139{
Arun Menon906de572013-06-18 17:01:40 -07008140 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8141 prev_ts = act_timestamp;
8142 rst_prev_ts = false;
8143 } else if (VALID_TS(prev_ts)) {
8144 bool codec_cond = (drv_ctx.timestamp_adjust)?
8145 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8146 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8147 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8148 if (frm_int > 0 && codec_cond) {
8149 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8150 act_timestamp = prev_ts + frm_int;
8151 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8152 prev_ts = act_timestamp;
8153 } else
8154 set_frame_rate(act_timestamp);
8155 } else if (frm_int > 0) // In this case the frame rate was set along
8156 { // with the port definition, start ts with 0
8157 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8158 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008159 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008160}
8161
8162void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8163{
Arun Menon906de572013-06-18 17:01:40 -07008164 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8165 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308166 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008167 OMX_U32 frame_rate = 0;
8168 int consumed_len = 0;
8169 OMX_U32 num_MB_in_frame;
8170 OMX_U32 recovery_sei_flags = 1;
8171 int enable = 0;
8172 OMX_U32 mbaff = 0;
8173 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008174 if (buf_index >= drv_ctx.extradata_info.count) {
8175 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8176 buf_index, drv_ctx.extradata_info.count);
8177 return;
8178 }
Arun Menon906de572013-06-18 17:01:40 -07008179 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8180 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8181 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308182
Arun Menon906de572013-06-18 17:01:40 -07008183 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308184 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008185 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008186 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308187 if (!secure_mode)
8188 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008189 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308190 else
8191 p_extra = m_other_extradata;
8192
Arun Menon906de572013-06-18 17:01:40 -07008193 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308194
8195 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008196 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308197 return;
8198 }
Arun Menon906de572013-06-18 17:01:40 -07008199 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8200 if (data) {
8201 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8202 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308203 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008204 DEBUG_PRINT_LOW("Invalid extra data size");
8205 break;
8206 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308207 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008208 switch ((unsigned long)data->eType) {
8209 case EXTRADATA_INTERLACE_VIDEO:
8210 struct msm_vidc_interlace_payload *payload;
8211 payload = (struct msm_vidc_interlace_payload *)data->data;
8212 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8213 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8214 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008215 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8216 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8217 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8218 enable = 1;
8219 } else {
Arun Menon906de572013-06-18 17:01:40 -07008220 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8221 enable = 1;
8222 }
8223 if (m_enable_android_native_buffers)
8224 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8225 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308226 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008227 append_interlace_extradata(p_extra, payload->format);
8228 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8229 }
8230 break;
8231 case EXTRADATA_FRAME_RATE:
8232 struct msm_vidc_framerate_payload *frame_rate_payload;
8233 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8234 frame_rate = frame_rate_payload->frame_rate;
8235 break;
8236 case EXTRADATA_TIMESTAMP:
8237 struct msm_vidc_ts_payload *time_stamp_payload;
8238 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308239 time_stamp = time_stamp_payload->timestamp_lo;
8240 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8241 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008242 break;
8243 case EXTRADATA_NUM_CONCEALED_MB:
8244 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8245 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8246 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8247 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8248 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8249 break;
8250 case EXTRADATA_INDEX:
8251 int *etype;
8252 etype = (int *)(data->data);
8253 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8254 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8255 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8256 if (aspect_ratio_payload) {
8257 ((struct vdec_output_frameinfo *)
8258 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8259 ((struct vdec_output_frameinfo *)
8260 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8261 }
8262 }
8263 break;
8264 case EXTRADATA_RECOVERY_POINT_SEI:
8265 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8266 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8267 recovery_sei_flags = recovery_sei_payload->flags;
8268 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8269 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008270 DEBUG_PRINT_HIGH("");
8271 DEBUG_PRINT_HIGH("***************************************************");
8272 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8273 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008274 }
8275 break;
8276 case EXTRADATA_PANSCAN_WINDOW:
8277 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8278 break;
8279 case EXTRADATA_MPEG2_SEQDISP:
8280 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8281 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8282 if (seqdisp_payload) {
8283 m_disp_hor_size = seqdisp_payload->disp_width;
8284 m_disp_vert_size = seqdisp_payload->disp_height;
8285 }
8286 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308287 case EXTRADATA_S3D_FRAME_PACKING:
8288 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8289 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
8290 if (!secure_mode && (client_extradata & OMX_FRAMEPACK_EXTRADATA)) {
8291 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8292 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8293 }
8294 break;
Arun Menon906de572013-06-18 17:01:40 -07008295 default:
8296 goto unrecognized_extradata;
8297 }
8298 consumed_len += data->nSize;
8299 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8300 }
8301 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8302 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8303 append_frame_info_extradata(p_extra,
8304 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308305 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008306 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008307 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008308 }
8309 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008310unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008311 if (!secure_mode && client_extradata)
8312 append_terminator_extradata(p_extra);
8313 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008314}
8315
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008316OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008317 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008318{
Arun Menon906de572013-06-18 17:01:40 -07008319 OMX_ERRORTYPE ret = OMX_ErrorNone;
8320 struct v4l2_control control;
8321 if (m_state != OMX_StateLoaded) {
8322 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8323 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008324 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008325 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008326 client_extradata, requested_extradata, enable, is_internal);
8327
8328 if (!is_internal) {
8329 if (enable)
8330 client_extradata |= requested_extradata;
8331 else
8332 client_extradata = client_extradata & ~requested_extradata;
8333 }
8334
8335 if (enable) {
8336 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8337 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8338 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8339 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8340 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008341 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008342 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308343 }
8344 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008345 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8346 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8347 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008348 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008349 }
8350 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8351 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8352 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008353 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008354 }
8355 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8356 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8357 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008358 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008359 }
8360 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8361 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8362 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008363 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008364 }
8365 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8366 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8367 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008368 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008369 }
8370 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8371 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8372 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8373 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008374 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008375 }
8376 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308377 }
8378 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008379 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8380 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8381 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008382 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008383 }
8384 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308385 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8386 if (output_capability == V4L2_PIX_FMT_H264) {
8387 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8388 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8389 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8390 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8391 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8392 }
8393 } else {
8394 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8395 }
8396 }
Arun Menon906de572013-06-18 17:01:40 -07008397 }
8398 ret = get_buffer_req(&drv_ctx.op_buf);
8399 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008400}
8401
8402OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8403{
Arun Menon906de572013-06-18 17:01:40 -07008404 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8405 OMX_U8 *data_ptr = extra->data, data = 0;
8406 while (byte_count < extra->nDataSize) {
8407 data = *data_ptr;
8408 while (data) {
8409 num_MB += (data&0x01);
8410 data >>= 1;
8411 }
8412 data_ptr++;
8413 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008414 }
Arun Menon906de572013-06-18 17:01:40 -07008415 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8416 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8417 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008418}
8419
8420void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8421{
Arun Menon906de572013-06-18 17:01:40 -07008422 if (!m_debug_extradata)
8423 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008424
8425 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308426 "============== Extra Data ==============\n"
8427 " Size: %lu\n"
8428 " Version: %lu\n"
8429 " PortIndex: %lu\n"
8430 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008431 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008432 extra->nSize, extra->nVersion.nVersion,
8433 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008434
Arun Menon906de572013-06-18 17:01:40 -07008435 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8436 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8437 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308438 "------ Interlace Format ------\n"
8439 " Size: %lu\n"
8440 " Version: %lu\n"
8441 " PortIndex: %lu\n"
8442 " Is Interlace Format: %d\n"
8443 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008444 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008445 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8446 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8447 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8448 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8449
8450 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308451 "-------- Frame Format --------\n"
8452 " Picture Type: %d\n"
8453 " Interlace Type: %d\n"
8454 " Pan Scan Total Frame Num: %lu\n"
8455 " Concealed Macro Blocks: %lu\n"
8456 " frame rate: %lu\n"
8457 " Time Stamp: %llu\n"
8458 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008459 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008460 fminfo->ePicType,
8461 fminfo->interlaceType,
8462 fminfo->panScan.numWindows,
8463 fminfo->nConcealedMacroblocks,
8464 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308465 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008466 fminfo->aspectRatio.aspectRatioX,
8467 fminfo->aspectRatio.aspectRatioY);
8468
8469 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8470 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008471 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308472 " Pan Scan Frame Num: %lu\n"
8473 " Rectangle x: %ld\n"
8474 " Rectangle y: %ld\n"
8475 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008476 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008477 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8478 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8479 }
8480
8481 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308482 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8483 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8484 DEBUG_PRINT_HIGH(
8485 "------------------ Framepack Format ----------\n"
8486 " id: %lu \n"
8487 " cancel_flag: %lu \n"
8488 " type: %lu \n"
8489 " quincunx_sampling_flagFormat: %lu \n"
8490 " content_interpretation_type: %lu \n"
8491 " content_interpretation_type: %lu \n"
8492 " spatial_flipping_flag: %lu \n"
8493 " frame0_flipped_flag: %lu \n"
8494 " field_views_flag: %lu \n"
8495 " current_frame_is_frame0_flag: %lu \n"
8496 " frame0_self_contained_flag: %lu \n"
8497 " frame1_self_contained_flag: %lu \n"
8498 " frame0_grid_position_x: %lu \n"
8499 " frame0_grid_position_y: %lu \n"
8500 " frame1_grid_position_x: %lu \n"
8501 " frame1_grid_position_y: %lu \n"
8502 " reserved_byte: %lu \n"
8503 " repetition_period: %lu \n"
8504 " extension_flag: %lu \n"
8505 "================== End of Framepack ===========",
8506 framepack->id,
8507 framepack->cancel_flag,
8508 framepack->type,
8509 framepack->quincunx_sampling_flag,
8510 framepack->content_interpretation_type,
8511 framepack->spatial_flipping_flag,
8512 framepack->frame0_flipped_flag,
8513 framepack->field_views_flag,
8514 framepack->current_frame_is_frame0_flag,
8515 framepack->frame0_self_contained_flag,
8516 framepack->frame1_self_contained_flag,
8517 framepack->frame0_grid_position_x,
8518 framepack->frame0_grid_position_y,
8519 framepack->frame1_grid_position_x,
8520 framepack->frame1_grid_position_y,
8521 framepack->reserved_byte,
8522 framepack->repetition_period,
8523 framepack->extension_flag);
Arun Menon906de572013-06-18 17:01:40 -07008524 } else if (extra->eType == OMX_ExtraDataNone) {
8525 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8526 } else {
8527 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008528 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008529}
8530
8531void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008532 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008533{
Arun Menon906de572013-06-18 17:01:40 -07008534 OMX_STREAMINTERLACEFORMAT *interlace_format;
8535 OMX_U32 mbaff = 0;
8536 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8537 return;
8538 }
8539 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8540 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8541 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8542 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8543 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8544 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8545 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8546 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8547 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8548 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8549 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8550 interlace_format->bInterlaceFormat = OMX_FALSE;
8551 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8552 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008553 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8554 interlace_format->bInterlaceFormat = OMX_TRUE;
8555 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8556 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8557 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8558 interlace_format->bInterlaceFormat = OMX_TRUE;
8559 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8560 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008561 } else {
8562 interlace_format->bInterlaceFormat = OMX_TRUE;
8563 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8564 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8565 }
8566 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008567}
8568
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008569void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008570 struct vdec_aspectratioinfo *aspect_ratio_info,
8571 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008572{
Arun Menon906de572013-06-18 17:01:40 -07008573 m_extradata = frame_info;
8574 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8575 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308576 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008577 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008578}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008579
8580void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008581 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308582 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008583 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008584{
Arun Menon906de572013-06-18 17:01:40 -07008585 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8586 struct msm_vidc_panscan_window *panscan_window;
8587 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008588 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008589 }
Arun Menon906de572013-06-18 17:01:40 -07008590 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8591 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8592 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8593 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8594 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8595 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8596 switch (picture_type) {
8597 case PICTURE_TYPE_I:
8598 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8599 break;
8600 case PICTURE_TYPE_P:
8601 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8602 break;
8603 case PICTURE_TYPE_B:
8604 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8605 break;
8606 default:
8607 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8608 }
8609 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8610 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8611 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8612 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8613 else
8614 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8615 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8616 frame_info->nConcealedMacroblocks = num_conceal_mb;
8617 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308618 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008619 frame_info->panScan.numWindows = 0;
8620 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8621 if (m_disp_hor_size && m_disp_vert_size) {
8622 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8623 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8624 }
8625 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008626
Arun Menon906de572013-06-18 17:01:40 -07008627 if (panscan_payload) {
8628 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8629 panscan_window = &panscan_payload->wnd[0];
8630 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8631 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8632 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8633 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8634 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8635 panscan_window++;
8636 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008637 }
Arun Menon906de572013-06-18 17:01:40 -07008638 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8639 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008640}
8641
8642void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8643{
Arun Menon906de572013-06-18 17:01:40 -07008644 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8645 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8646 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8647 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8648 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8649 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8650 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8651 *portDefn = m_port_def;
8652 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008653 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008654 portDefn->format.video.nFrameWidth,
8655 portDefn->format.video.nStride,
8656 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008657}
8658
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308659void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8660 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8661{
8662 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8663 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8664 DEBUG_PRINT_ERROR("frame packing size mismatch");
8665 return;
8666 }
8667 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8668 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8669 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8670 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8671 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8672 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8673 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8674 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8675 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8676 memcpy(&framepack->id, s3d_frame_packing_payload,
8677 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8678 memcpy(&m_frame_pack_arrangement, framepack,
8679 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8680 print_debug_extradata(extra);
8681}
8682
Shalaj Jain273b3e02012-06-22 19:08:03 -07008683void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8684{
Arun Menon906de572013-06-18 17:01:40 -07008685 if (!client_extradata) {
8686 return;
8687 }
8688 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8689 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8690 extra->eType = OMX_ExtraDataNone;
8691 extra->nDataSize = 0;
8692 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008693
Arun Menon906de572013-06-18 17:01:40 -07008694 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008695}
8696
8697OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8698{
Arun Menon906de572013-06-18 17:01:40 -07008699 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8700 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008701 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008702 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008703 }
Arun Menon906de572013-06-18 17:01:40 -07008704 if (m_desc_buffer_ptr == NULL) {
8705 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8706 calloc( (sizeof(desc_buffer_hdr)),
8707 drv_ctx.ip_buf.actualcount);
8708 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008709 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008710 return OMX_ErrorInsufficientResources;
8711 }
8712 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008713
Arun Menon906de572013-06-18 17:01:40 -07008714 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8715 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008716 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008717 return OMX_ErrorInsufficientResources;
8718 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008719
Arun Menon906de572013-06-18 17:01:40 -07008720 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008721}
8722
8723void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8724{
Arun Menon906de572013-06-18 17:01:40 -07008725 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8726 if (m_demux_entries < 8192) {
8727 m_demux_offsets[m_demux_entries++] = address_offset;
8728 }
8729 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008730}
8731
8732void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8733{
Arun Menon906de572013-06-18 17:01:40 -07008734 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8735 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8736 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008737
Arun Menon906de572013-06-18 17:01:40 -07008738 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008739
Arun Menon906de572013-06-18 17:01:40 -07008740 while (index < bytes_to_parse) {
8741 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8742 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8743 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8744 (buf[index+2] == 0x01)) ) {
8745 //Found start code, insert address offset
8746 insert_demux_addr_offset(index);
8747 if (buf[index+2] == 0x01) // 3 byte start code
8748 index += 3;
8749 else //4 byte start code
8750 index += 4;
8751 } else
8752 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008753 }
Arun Menon906de572013-06-18 17:01:40 -07008754 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8755 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008756}
8757
8758OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8759{
Arun Menon906de572013-06-18 17:01:40 -07008760 //fix this, handle 3 byte start code, vc1 terminator entry
8761 OMX_U8 *p_demux_data = NULL;
8762 OMX_U32 desc_data = 0;
8763 OMX_U32 start_addr = 0;
8764 OMX_U32 nal_size = 0;
8765 OMX_U32 suffix_byte = 0;
8766 OMX_U32 demux_index = 0;
8767 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008768
Arun Menon906de572013-06-18 17:01:40 -07008769 if (m_desc_buffer_ptr == NULL) {
8770 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8771 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008772 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008773
Arun Menon906de572013-06-18 17:01:40 -07008774 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8775 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8776 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8777 return OMX_ErrorBadParameter;
8778 }
8779
8780 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8781
8782 if ( ((OMX_U8*)p_demux_data == NULL) ||
8783 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8784 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8785 return OMX_ErrorBadParameter;
8786 } else {
8787 for (; demux_index < m_demux_entries; demux_index++) {
8788 desc_data = 0;
8789 start_addr = m_demux_offsets[demux_index];
8790 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8791 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8792 } else {
8793 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8794 }
8795 if (demux_index < (m_demux_entries - 1)) {
8796 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8797 } else {
8798 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8799 }
8800 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8801 (void *)start_addr,
8802 suffix_byte,
8803 nal_size,
8804 demux_index);
8805 desc_data = (start_addr >> 3) << 1;
8806 desc_data |= (start_addr & 7) << 21;
8807 desc_data |= suffix_byte << 24;
8808
8809 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8810 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8811 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8812 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8813
8814 p_demux_data += 16;
8815 }
8816 if (codec_type_parse == CODEC_TYPE_VC1) {
8817 DEBUG_PRINT_LOW("VC1 terminator entry");
8818 desc_data = 0;
8819 desc_data = 0x82 << 24;
8820 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8821 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8822 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8823 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8824 p_demux_data += 16;
8825 m_demux_entries++;
8826 }
8827 //Add zero word to indicate end of descriptors
8828 memset(p_demux_data, 0, sizeof(OMX_U32));
8829
8830 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8831 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8832 }
8833 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8834 m_demux_entries = 0;
8835 DEBUG_PRINT_LOW("Demux table complete!");
8836 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008837}
8838
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008839OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008840{
Arun Menon906de572013-06-18 17:01:40 -07008841 OMX_ERRORTYPE err = OMX_ErrorNone;
8842 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8843 if (iDivXDrmDecrypt) {
8844 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8845 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008846 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008847 delete iDivXDrmDecrypt;
8848 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008849 }
8850 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008851 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07008852 err = OMX_ErrorUndefined;
8853 }
8854 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008855}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008856
Vinay Kaliada4f4422013-01-09 10:45:03 -08008857omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8858{
Arun Menon906de572013-06-18 17:01:40 -07008859 enabled = false;
8860 omx = NULL;
8861 init_members();
8862 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008863}
8864
8865void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8866{
Arun Menon906de572013-06-18 17:01:40 -07008867 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008868}
8869
Arun Menon906de572013-06-18 17:01:40 -07008870void omx_vdec::allocate_color_convert_buf::init_members()
8871{
8872 allocated_count = 0;
8873 buffer_size_req = 0;
8874 buffer_alignment_req = 0;
8875 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8876 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8877 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8878 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008879#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008880 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008881#endif
Arun Menon906de572013-06-18 17:01:40 -07008882 for (int i = 0; i < MAX_COUNT; i++)
8883 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008884}
8885
Arun Menon906de572013-06-18 17:01:40 -07008886omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8887{
8888 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008889}
8890
8891bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8892{
Arun Menon906de572013-06-18 17:01:40 -07008893 bool status = true;
8894 unsigned int src_size = 0, destination_size = 0;
8895 OMX_COLOR_FORMATTYPE drv_color_format;
8896 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008897 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008898 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008899 }
Arun Menon906de572013-06-18 17:01:40 -07008900 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008901 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07008902 return status;
8903 }
8904 pthread_mutex_lock(&omx->c_lock);
8905 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8906 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008907 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07008908 status = false;
8909 goto fail_update_buf_req;
8910 }
8911 c2d.close();
8912 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8913 omx->drv_ctx.video_resolution.frame_width,
8914 NV12_128m,YCbCr420P);
8915 if (status) {
8916 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8917 if (status)
8918 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8919 }
8920 if (status) {
8921 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8922 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008923 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07008924 "driver size %d destination size %d",
8925 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8926 status = false;
8927 c2d.close();
8928 buffer_size_req = 0;
8929 } else {
8930 buffer_size_req = destination_size;
8931 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8932 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8933 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8934 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8935 }
8936 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008937fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008938 pthread_mutex_unlock(&omx->c_lock);
8939 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008940}
8941
8942bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008943 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008944{
Arun Menon906de572013-06-18 17:01:40 -07008945 bool status = true;
8946 OMX_COLOR_FORMATTYPE drv_color_format;
8947 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008948 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008949 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008950 }
Arun Menon906de572013-06-18 17:01:40 -07008951 pthread_mutex_lock(&omx->c_lock);
8952 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8953 drv_color_format = (OMX_COLOR_FORMATTYPE)
8954 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8955 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008956 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07008957 status = false;
8958 }
8959 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008960 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07008961 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008962 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008963 status = false;
8964 } else {
8965 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8966 if (enabled)
8967 c2d.destroy();
8968 enabled = false;
8969 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008970 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008971 status = false;
8972 } else
8973 enabled = true;
8974 }
8975 } else {
8976 if (enabled)
8977 c2d.destroy();
8978 enabled = false;
8979 }
8980 pthread_mutex_unlock(&omx->c_lock);
8981 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008982}
8983
8984OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8985{
Arun Menon906de572013-06-18 17:01:40 -07008986 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008987 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008988 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008989 }
Arun Menon906de572013-06-18 17:01:40 -07008990 if (!enabled)
8991 return omx->m_out_mem_ptr;
8992 return m_out_mem_ptr_client;
8993}
8994
8995 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8996(OMX_BUFFERHEADERTYPE *bufadd)
8997{
8998 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008999 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009000 return NULL;
9001 }
9002 if (!enabled)
9003 return bufadd;
9004
9005 unsigned index = 0;
9006 index = bufadd - omx->m_out_mem_ptr;
9007 if (index < omx->drv_ctx.op_buf.actualcount) {
9008 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9009 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9010 bool status;
9011 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9012 pthread_mutex_lock(&omx->c_lock);
9013 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9014 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9015 pmem_baseaddress[index], pmem_baseaddress[index]);
9016 pthread_mutex_unlock(&omx->c_lock);
9017 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9018 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009019 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009020 m_out_mem_ptr_client[index].nFilledLen = 0;
9021 return &m_out_mem_ptr_client[index];
9022 }
9023 } else
9024 m_out_mem_ptr_client[index].nFilledLen = 0;
9025 return &m_out_mem_ptr_client[index];
9026 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009027 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009028 return NULL;
9029}
9030
9031 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9032(OMX_BUFFERHEADERTYPE *bufadd)
9033{
9034 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009035 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009036 return NULL;
9037 }
9038 if (!enabled)
9039 return bufadd;
9040 unsigned index = 0;
9041 index = bufadd - m_out_mem_ptr_client;
9042 if (index < omx->drv_ctx.op_buf.actualcount) {
9043 return &omx->m_out_mem_ptr[index];
9044 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009045 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009046 return NULL;
9047}
9048 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9049(unsigned int &buffer_size)
9050{
9051 bool status = true;
9052 pthread_mutex_lock(&omx->c_lock);
9053 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009054 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009055 else {
9056 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009057 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009058 status = false;
9059 goto fail_get_buffer_size;
9060 }
9061 }
9062 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9063 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9064 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9065 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009066fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009067 pthread_mutex_unlock(&omx->c_lock);
9068 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009069}
9070OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009071 OMX_BUFFERHEADERTYPE *bufhdr)
9072{
9073 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009074
Arun Menon906de572013-06-18 17:01:40 -07009075 if (!enabled)
9076 return omx->free_output_buffer(bufhdr);
9077 if (enabled && omx->is_component_secure())
9078 return OMX_ErrorNone;
9079 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009080 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009081 return OMX_ErrorBadParameter;
9082 }
9083 index = bufhdr - m_out_mem_ptr_client;
9084 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009085 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009086 return OMX_ErrorBadParameter;
9087 }
9088 if (pmem_fd[index] > 0) {
9089 munmap(pmem_baseaddress[index], buffer_size_req);
9090 close(pmem_fd[index]);
9091 }
9092 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009093#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009094 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009095#endif
Arun Menon906de572013-06-18 17:01:40 -07009096 m_heap_ptr[index].video_heap_ptr = NULL;
9097 if (allocated_count > 0)
9098 allocated_count--;
9099 else
9100 allocated_count = 0;
9101 if (!allocated_count) {
9102 pthread_mutex_lock(&omx->c_lock);
9103 c2d.close();
9104 init_members();
9105 pthread_mutex_unlock(&omx->c_lock);
9106 }
9107 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009108}
9109
9110OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009111 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009112{
Arun Menon906de572013-06-18 17:01:40 -07009113 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9114 if (!enabled) {
9115 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9116 return eRet;
9117 }
9118 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009119 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009120 omx->is_component_secure());
9121 return OMX_ErrorUnsupportedSetting;
9122 }
9123 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009124 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9125 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009126 buffer_size_req,bytes);
9127 return OMX_ErrorBadParameter;
9128 }
9129 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009130 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009131 return OMX_ErrorInsufficientResources;
9132 }
9133 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9134 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9135 port,appData,omx->drv_ctx.op_buf.buffer_size);
9136 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009137 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009138 return eRet;
9139 }
9140 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309141 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009142 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009143 (temp_bufferHdr - omx->m_out_mem_ptr));
9144 return OMX_ErrorUndefined;
9145 }
9146 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009147#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009148 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9149 buffer_size_req,buffer_alignment_req,
9150 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9151 0);
9152 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9153 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009154 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009155 return OMX_ErrorInsufficientResources;
9156 }
9157 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9158 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009159
Arun Menon906de572013-06-18 17:01:40 -07009160 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009161 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009162 close(pmem_fd[i]);
9163 omx->free_ion_memory(&op_buf_ion_info[i]);
9164 return OMX_ErrorInsufficientResources;
9165 }
9166 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9167 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9168 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009169#endif
Arun Menon906de572013-06-18 17:01:40 -07009170 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9171 m_pmem_info_client[i].offset = 0;
9172 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9173 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9174 m_platform_list_client[i].nEntries = 1;
9175 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9176 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9177 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9178 m_out_mem_ptr_client[i].nFilledLen = 0;
9179 m_out_mem_ptr_client[i].nFlags = 0;
9180 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9181 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9182 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9183 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9184 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9185 m_out_mem_ptr_client[i].pAppPrivate = appData;
9186 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009187 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009188 allocated_count++;
9189 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009190}
9191
9192bool omx_vdec::is_component_secure()
9193{
Arun Menon906de572013-06-18 17:01:40 -07009194 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009195}
9196
9197bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9198{
Arun Menon906de572013-06-18 17:01:40 -07009199 bool status = true;
9200 if (!enabled) {
9201 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9202 dest_color_format = (OMX_COLOR_FORMATTYPE)
9203 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9204 else
9205 status = false;
9206 } else {
9207 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9208 status = false;
9209 } else
9210 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9211 }
9212 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009213}
Arun Menonbdb80b02013-08-12 17:45:54 -07009214
Arun Menonbdb80b02013-08-12 17:45:54 -07009215void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9216{
9217 int i = 0;
9218 bool buf_present = false;
9219 pthread_mutex_lock(&m_lock);
9220 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9221 //check the buffer fd, offset, uv addr with list contents
9222 //If present increment reference.
9223 if ((out_dynamic_list[i].fd == fd) &&
9224 (out_dynamic_list[i].offset == offset)) {
9225 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009226 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009227 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9228 buf_present = true;
9229 break;
9230 }
9231 }
9232 if (!buf_present) {
9233 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9234 //search for a entry to insert details of the new buffer
9235 if (out_dynamic_list[i].dup_fd == 0) {
9236 out_dynamic_list[i].fd = fd;
9237 out_dynamic_list[i].offset = offset;
9238 out_dynamic_list[i].dup_fd = dup(fd);
9239 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009240 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009241 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9242 break;
9243 }
9244 }
9245 }
9246 pthread_mutex_unlock(&m_lock);
9247}
9248
9249void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9250{
9251 int i = 0;
9252 pthread_mutex_lock(&m_lock);
9253 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9254 //check the buffer fd, offset, uv addr with list contents
9255 //If present decrement reference.
9256 if ((out_dynamic_list[i].fd == fd) &&
9257 (out_dynamic_list[i].offset == offset)) {
9258 out_dynamic_list[i].ref_count--;
9259 if (out_dynamic_list[i].ref_count == 0) {
9260 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009261 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009262 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9263 out_dynamic_list[i].dup_fd = 0;
9264 out_dynamic_list[i].fd = 0;
9265 out_dynamic_list[i].offset = 0;
9266 }
9267 break;
9268 }
9269 }
9270 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009271 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009272 }
9273 pthread_mutex_unlock(&m_lock);
9274}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009275
9276#ifdef _MSM8974_
9277void omx_vdec::send_codec_config() {
9278 if (codec_config_flag) {
9279 unsigned p1 = 0; // Parameter - 1
9280 unsigned p2 = 0; // Parameter - 2
9281 unsigned ident = 0;
9282 pthread_mutex_lock(&m_lock);
9283 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9284 while (m_etb_q.m_size) {
9285 m_etb_q.pop_entry(&p1,&p2,&ident);
9286 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9287 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9288 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9289 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9290 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9291 omx_report_error();
9292 }
9293 } else {
9294 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9295 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9296 }
9297 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9298 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9299 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9300 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9301 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9302 omx_report_error ();
9303 }
9304 } else {
9305 pending_input_buffers++;
9306 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9307 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9308 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9309 }
9310 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9311 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9312 (OMX_BUFFERHEADERTYPE *)p1);
9313 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9314 }
9315 }
9316 pthread_mutex_unlock(&m_lock);
9317 }
9318}
9319#endif