blob: 658280a6dde62a259d25c2a61629d052e4b6616e [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -08002Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
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);
2200 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2201 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2202 }
2203 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2204 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2205 }
2206 if (!sem_posted) {
2207 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002208 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002209 sem_post (&m_cmd_lock);
2210 execute_omx_flush(param1);
2211 }
2212 bFlag = 0;
2213 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002214 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002215 "with param1: %lu", param1);
2216 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2217 m_inp_bEnabled = OMX_TRUE;
2218
2219 if ( (m_state == OMX_StateLoaded &&
2220 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2221 || allocate_input_done()) {
2222 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2223 OMX_COMPONENT_GENERATE_EVENT);
2224 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002225 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002226 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2227 // Skip the event notification
2228 bFlag = 0;
2229 }
2230 }
2231 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002232 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002233 m_out_bEnabled = OMX_TRUE;
2234
2235 if ( (m_state == OMX_StateLoaded &&
2236 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2237 || (allocate_output_done())) {
2238 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2239 OMX_COMPONENT_GENERATE_EVENT);
2240
2241 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002242 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002243 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2244 // Skip the event notification
2245 bFlag = 0;
2246 }
2247 }
2248 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002249 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002250 "with param1: %lu", param1);
2251 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2252 m_inp_bEnabled = OMX_FALSE;
2253 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2254 && release_input_done()) {
2255 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2256 OMX_COMPONENT_GENERATE_EVENT);
2257 } else {
2258 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2259 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2260 if (!sem_posted) {
2261 sem_posted = 1;
2262 sem_post (&m_cmd_lock);
2263 }
2264 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2265 }
2266
2267 // Skip the event notification
2268 bFlag = 0;
2269 }
2270 }
2271 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2272 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002273 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002274 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2275 && release_output_done()) {
2276 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2277 OMX_COMPONENT_GENERATE_EVENT);
2278 } else {
2279 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2280 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2281 if (!sem_posted) {
2282 sem_posted = 1;
2283 sem_post (&m_cmd_lock);
2284 }
2285 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2286 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2287 }
2288 // Skip the event notification
2289 bFlag = 0;
2290
2291 }
2292 }
2293 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002294 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002295 eRet = OMX_ErrorNotImplemented;
2296 }
2297 if (eRet == OMX_ErrorNone && bFlag) {
2298 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2299 }
2300 if (!sem_posted) {
2301 sem_post(&m_cmd_lock);
2302 }
2303
2304 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002305}
2306
2307/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002308 FUNCTION
2309 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002310
Arun Menon906de572013-06-18 17:01:40 -07002311 DESCRIPTION
2312 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002313
Arun Menon906de572013-06-18 17:01:40 -07002314 PARAMETERS
2315 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002316
Arun Menon906de572013-06-18 17:01:40 -07002317 RETURN VALUE
2318 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002319
Arun Menon906de572013-06-18 17:01:40 -07002320 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002321bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2322{
Arun Menon906de572013-06-18 17:01:40 -07002323 bool bRet = false;
2324 struct v4l2_plane plane;
2325 struct v4l2_buffer v4l2_buf;
2326 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302327 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002328 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2329 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002330
Arun Menon906de572013-06-18 17:01:40 -07002331 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002332
Arun Menon906de572013-06-18 17:01:40 -07002333 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2334 output_flush_progress = true;
2335 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2336 } else {
2337 /* XXX: The driver/hardware does not support flushing of individual ports
2338 * in all states. So we pretty much need to flush both ports internally,
2339 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2340 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2341 * we automatically omit sending the FLUSH done for the "opposite" port. */
2342 input_flush_progress = true;
2343 output_flush_progress = true;
2344 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2345 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002346
Arun Menon906de572013-06-18 17:01:40 -07002347 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002348 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002349 bRet = false;
2350 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002351
Arun Menon906de572013-06-18 17:01:40 -07002352 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002353}
2354/*=========================================================================
2355FUNCTION : execute_output_flush
2356
2357DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002358Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002359
2360PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002361None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002362
2363RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002364true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002365==========================================================================*/
2366bool omx_vdec::execute_output_flush()
2367{
Arun Menon906de572013-06-18 17:01:40 -07002368 unsigned p1 = 0; // Parameter - 1
2369 unsigned p2 = 0; // Parameter - 2
2370 unsigned ident = 0;
2371 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002372
Arun Menon906de572013-06-18 17:01:40 -07002373 /*Generate FBD for all Buffers in the FTBq*/
2374 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002375 DEBUG_PRINT_LOW("Initiate Output Flush");
Arun Menon906de572013-06-18 17:01:40 -07002376 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002377 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002378 m_ftb_q.m_size,pending_output_buffers);
2379 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002380 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002381 if (ident == m_fill_output_msg ) {
2382 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2383 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2384 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002386 }
Arun Menon906de572013-06-18 17:01:40 -07002387 pthread_mutex_unlock(&m_lock);
2388 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002389
Arun Menon906de572013-06-18 17:01:40 -07002390 if (arbitrary_bytes) {
2391 prev_ts = LLONG_MAX;
2392 rst_prev_ts = true;
2393 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002394 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002395 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002396}
2397/*=========================================================================
2398FUNCTION : execute_input_flush
2399
2400DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002401Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002402
2403PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002404None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002405
2406RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002407true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002408==========================================================================*/
2409bool omx_vdec::execute_input_flush()
2410{
Arun Menon906de572013-06-18 17:01:40 -07002411 unsigned i =0;
2412 unsigned p1 = 0; // Parameter - 1
2413 unsigned p2 = 0; // Parameter - 2
2414 unsigned ident = 0;
2415 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002416
Arun Menon906de572013-06-18 17:01:40 -07002417 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002418 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419
Arun Menon906de572013-06-18 17:01:40 -07002420 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002421 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002422 while (m_etb_q.m_size) {
2423 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002424
Arun Menon906de572013-06-18 17:01:40 -07002425 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002426 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002427 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2428 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2429 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002430 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002431 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2432 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2433 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002434 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002435 (OMX_BUFFERHEADERTYPE *)p1);
2436 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2437 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002438 }
Arun Menon906de572013-06-18 17:01:40 -07002439 time_stamp_dts.flush_timestamp();
2440 /*Check if Heap Buffers are to be flushed*/
2441 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002442 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002443 h264_scratch.nFilledLen = 0;
2444 nal_count = 0;
2445 look_ahead_nal = false;
2446 frame_count = 0;
2447 h264_last_au_ts = LLONG_MAX;
2448 h264_last_au_flags = 0;
2449 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2450 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002451 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002452 if (m_frame_parser.mutils) {
2453 m_frame_parser.mutils->initialize_frame_checking_environment();
2454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002455
Arun Menon906de572013-06-18 17:01:40 -07002456 while (m_input_pending_q.m_size) {
2457 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2458 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2459 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002460
Arun Menon906de572013-06-18 17:01:40 -07002461 if (psource_frame) {
2462 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2463 psource_frame = NULL;
2464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002465
Arun Menon906de572013-06-18 17:01:40 -07002466 if (pdest_frame) {
2467 pdest_frame->nFilledLen = 0;
2468 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2469 (unsigned int)NULL);
2470 pdest_frame = NULL;
2471 }
2472 m_frame_parser.flush();
2473 } else if (codec_config_flag) {
2474 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2475 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002476 }
Arun Menon906de572013-06-18 17:01:40 -07002477 pthread_mutex_unlock(&m_lock);
2478 input_flush_progress = false;
2479 if (!arbitrary_bytes) {
2480 prev_ts = LLONG_MAX;
2481 rst_prev_ts = true;
2482 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002484 if (m_debug_timestamp) {
2485 m_timestamp_list.reset_ts_list();
2486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002488 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002489 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002490}
2491
2492
2493/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002494 FUNCTION
2495 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002496
Arun Menon906de572013-06-18 17:01:40 -07002497 DESCRIPTION
2498 Send the event to decoder pipe. This is needed to generate the callbacks
2499 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002500
Arun Menon906de572013-06-18 17:01:40 -07002501 PARAMETERS
2502 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503
Arun Menon906de572013-06-18 17:01:40 -07002504 RETURN VALUE
2505 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002506
Arun Menon906de572013-06-18 17:01:40 -07002507 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002508bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002509 unsigned int p2,
2510 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002511{
Arun Menon906de572013-06-18 17:01:40 -07002512 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002513
2514
Arun Menon906de572013-06-18 17:01:40 -07002515 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002516
Arun Menon906de572013-06-18 17:01:40 -07002517 if (id == m_fill_output_msg ||
2518 id == OMX_COMPONENT_GENERATE_FBD) {
2519 m_ftb_q.insert_entry(p1,p2,id);
2520 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2521 id == OMX_COMPONENT_GENERATE_EBD ||
2522 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2523 m_etb_q.insert_entry(p1,p2,id);
2524 } else {
2525 m_cmd_q.insert_entry(p1,p2,id);
2526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002527
Arun Menon906de572013-06-18 17:01:40 -07002528 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002529 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002530 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531
Arun Menon906de572013-06-18 17:01:40 -07002532 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002533
Arun Menon906de572013-06-18 17:01:40 -07002534 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002535}
2536
2537OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2538{
Arun Menon906de572013-06-18 17:01:40 -07002539 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2540 if (!profileLevelType)
2541 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002542
Arun Menon906de572013-06-18 17:01:40 -07002543 if (profileLevelType->nPortIndex == 0) {
2544 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2545 if (profileLevelType->nProfileIndex == 0) {
2546 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2547 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002548
Arun Menon906de572013-06-18 17:01:40 -07002549 } else if (profileLevelType->nProfileIndex == 1) {
2550 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2551 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2552 } else if (profileLevelType->nProfileIndex == 2) {
2553 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2554 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2555 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002556 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002557 profileLevelType->nProfileIndex);
2558 eRet = OMX_ErrorNoMore;
2559 }
2560 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2561 if (profileLevelType->nProfileIndex == 0) {
2562 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2563 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2564 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002565 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002566 eRet = OMX_ErrorNoMore;
2567 }
2568 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2569 if (profileLevelType->nProfileIndex == 0) {
2570 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2571 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2572 } else if (profileLevelType->nProfileIndex == 1) {
2573 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2574 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2575 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002576 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002577 eRet = OMX_ErrorNoMore;
2578 }
2579 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2580 eRet = OMX_ErrorNoMore;
2581 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2582 if (profileLevelType->nProfileIndex == 0) {
2583 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2584 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2585 } else if (profileLevelType->nProfileIndex == 1) {
2586 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2587 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2588 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002589 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002590 eRet = OMX_ErrorNoMore;
2591 }
2592 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002593 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
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 should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002598 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002599 }
Arun Menon906de572013-06-18 17:01:40 -07002600 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002601}
2602
2603/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002604 FUNCTION
2605 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002606
Arun Menon906de572013-06-18 17:01:40 -07002607 DESCRIPTION
2608 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002609
Arun Menon906de572013-06-18 17:01:40 -07002610 PARAMETERS
2611 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002612
Arun Menon906de572013-06-18 17:01:40 -07002613 RETURN VALUE
2614 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002615
Arun Menon906de572013-06-18 17:01:40 -07002616 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002617OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002618 OMX_IN OMX_INDEXTYPE paramIndex,
2619 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002620{
2621 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2622
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002623 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002624 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002625 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002626 return OMX_ErrorInvalidState;
2627 }
Arun Menon906de572013-06-18 17:01:40 -07002628 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002629 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630 return OMX_ErrorBadParameter;
2631 }
Arun Menon906de572013-06-18 17:01:40 -07002632 switch ((unsigned long)paramIndex) {
2633 case OMX_IndexParamPortDefinition: {
2634 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2635 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002636 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002637 eRet = update_portdef(portDefn);
2638 if (eRet == OMX_ErrorNone)
2639 m_port_def = *portDefn;
2640 break;
2641 }
2642 case OMX_IndexParamVideoInit: {
2643 OMX_PORT_PARAM_TYPE *portParamType =
2644 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002645 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002646
Arun Menon906de572013-06-18 17:01:40 -07002647 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2648 portParamType->nSize = sizeof(portParamType);
2649 portParamType->nPorts = 2;
2650 portParamType->nStartPortNumber = 0;
2651 break;
2652 }
2653 case OMX_IndexParamVideoPortFormat: {
2654 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2655 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002656 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002657
Arun Menon906de572013-06-18 17:01:40 -07002658 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2659 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002660
Arun Menon906de572013-06-18 17:01:40 -07002661 if (0 == portFmt->nPortIndex) {
2662 if (0 == portFmt->nIndex) {
2663 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2664 portFmt->eCompressionFormat = eCompressionFormat;
2665 } else {
2666 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002667 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002668 eRet = OMX_ErrorNoMore;
2669 }
2670 } else if (1 == portFmt->nPortIndex) {
2671 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002672
Arun Menon906de572013-06-18 17:01:40 -07002673 if (0 == portFmt->nIndex)
2674 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2675 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2676 else if (1 == portFmt->nIndex)
2677 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2678 else {
2679 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002680 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002681 eRet = OMX_ErrorNoMore;
2682 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002683 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002684 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002685 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002686 (int)portFmt->nPortIndex);
2687 eRet = OMX_ErrorBadPortIndex;
2688 }
2689 break;
2690 }
2691 /*Component should support this port definition*/
2692 case OMX_IndexParamAudioInit: {
2693 OMX_PORT_PARAM_TYPE *audioPortParamType =
2694 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002695 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002696 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2697 audioPortParamType->nSize = sizeof(audioPortParamType);
2698 audioPortParamType->nPorts = 0;
2699 audioPortParamType->nStartPortNumber = 0;
2700 break;
2701 }
2702 /*Component should support this port definition*/
2703 case OMX_IndexParamImageInit: {
2704 OMX_PORT_PARAM_TYPE *imagePortParamType =
2705 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002706 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002707 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2708 imagePortParamType->nSize = sizeof(imagePortParamType);
2709 imagePortParamType->nPorts = 0;
2710 imagePortParamType->nStartPortNumber = 0;
2711 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002712
Arun Menon906de572013-06-18 17:01:40 -07002713 }
2714 /*Component should support this port definition*/
2715 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002716 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002717 paramIndex);
2718 eRet =OMX_ErrorUnsupportedIndex;
2719 break;
2720 }
2721 case OMX_IndexParamStandardComponentRole: {
2722 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2723 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2724 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2725 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002726
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002727 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002728 paramIndex);
2729 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2730 OMX_MAX_STRINGNAME_SIZE);
2731 break;
2732 }
2733 /* Added for parameter test */
2734 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002735
Arun Menon906de572013-06-18 17:01:40 -07002736 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2737 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002738 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002739 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2740 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002741
Arun Menon906de572013-06-18 17:01:40 -07002742 break;
2743 }
2744 /* Added for parameter test */
2745 case OMX_IndexParamCompBufferSupplier: {
2746 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2747 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002748 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002749
Arun Menon906de572013-06-18 17:01:40 -07002750 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2751 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2752 if (0 == bufferSupplierType->nPortIndex)
2753 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2754 else if (1 == bufferSupplierType->nPortIndex)
2755 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2756 else
2757 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002758
2759
Arun Menon906de572013-06-18 17:01:40 -07002760 break;
2761 }
2762 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002763 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002764 paramIndex);
2765 break;
2766 }
2767 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002768 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002769 paramIndex);
2770 break;
2771 }
2772 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002773 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002774 paramIndex);
2775 break;
2776 }
2777 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002778 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002779 paramIndex);
2780 break;
2781 }
2782 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002783 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002784 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2785 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2786 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2787 break;
2788 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002790 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002791 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002792 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2793 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002794
Arun Menon906de572013-06-18 17:01:40 -07002795 if (secure_mode) {
2796 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2797 GRALLOC_USAGE_PRIVATE_UNCACHED);
2798 } else {
2799 nativeBuffersUsage->nUsage =
2800 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2801 GRALLOC_USAGE_PRIVATE_UNCACHED);
2802 }
2803 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002804 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002805 eRet = OMX_ErrorBadParameter;
2806 }
2807 }
2808 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002809#endif
2810
Arun Menon906de572013-06-18 17:01:40 -07002811 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002812 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002813 eRet =OMX_ErrorUnsupportedIndex;
2814 }
2815
Shalaj Jain273b3e02012-06-22 19:08:03 -07002816 }
2817
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002818 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002819 drv_ctx.video_resolution.frame_width,
2820 drv_ctx.video_resolution.frame_height,
2821 drv_ctx.video_resolution.stride,
2822 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002823
Arun Menon906de572013-06-18 17:01:40 -07002824 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002825}
2826
2827#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2828OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2829{
2830 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2831 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2832 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2833
Arun Menon906de572013-06-18 17:01:40 -07002834 if ((params == NULL) ||
2835 (params->nativeBuffer == NULL) ||
2836 (params->nativeBuffer->handle == NULL) ||
2837 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002838 return OMX_ErrorBadParameter;
2839 m_use_android_native_buffers = OMX_TRUE;
2840 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2841 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002842 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 -07002843 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002844 if (!secure_mode) {
2845 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002846 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002847 if (buffer == MAP_FAILED) {
2848 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2849 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002850 }
2851 }
2852 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2853 } else {
2854 eRet = OMX_ErrorBadParameter;
2855 }
2856 return eRet;
2857}
2858#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002859
2860OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2861 struct v4l2_control control;
2862 struct v4l2_format fmt;
2863 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2864 control.value = 1;
2865 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2866 if (rc < 0) {
2867 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2868 return OMX_ErrorHardware;
2869 }
2870 m_smoothstreaming_mode = true;
2871 return OMX_ErrorNone;
2872}
2873
Shalaj Jain273b3e02012-06-22 19:08:03 -07002874/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002875 FUNCTION
2876 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002877
Arun Menon906de572013-06-18 17:01:40 -07002878 DESCRIPTION
2879 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002880
Arun Menon906de572013-06-18 17:01:40 -07002881 PARAMETERS
2882 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002883
Arun Menon906de572013-06-18 17:01:40 -07002884 RETURN VALUE
2885 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002886
Arun Menon906de572013-06-18 17:01:40 -07002887 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002888OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002889 OMX_IN OMX_INDEXTYPE paramIndex,
2890 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002891{
2892 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002893 int ret=0;
2894 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002895 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002896 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002897 return OMX_ErrorInvalidState;
2898 }
Arun Menon906de572013-06-18 17:01:40 -07002899 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002900 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002901 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002902 }
Arun Menon906de572013-06-18 17:01:40 -07002903 if ((m_state != OMX_StateLoaded) &&
2904 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2905 (m_out_bEnabled == OMX_TRUE) &&
2906 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2907 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002908 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002909 return OMX_ErrorIncorrectStateOperation;
2910 }
Arun Menon906de572013-06-18 17:01:40 -07002911 switch ((unsigned long)paramIndex) {
2912 case OMX_IndexParamPortDefinition: {
2913 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2914 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2915 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2916 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002917 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002918 (int)portDefn->format.video.nFrameHeight,
2919 (int)portDefn->format.video.nFrameWidth);
2920 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002921 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002922 m_display_id = portDefn->format.video.pNativeWindow;
2923 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002924 /* update output port resolution with client supplied dimensions
2925 in case scaling is enabled, else it follows input resolution set
2926 */
2927 if (is_down_scalar_enabled) {
2928 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002929 portDefn->format.video.nFrameWidth,
2930 portDefn->format.video.nFrameHeight);
2931 if (portDefn->format.video.nFrameHeight != 0x0 &&
2932 portDefn->format.video.nFrameWidth != 0x0) {
2933 update_resolution(portDefn->format.video.nFrameWidth,
2934 portDefn->format.video.nFrameHeight,
2935 portDefn->format.video.nFrameWidth,
2936 portDefn->format.video.nFrameHeight);
2937 eRet = is_video_session_supported();
2938 if (eRet)
2939 break;
2940 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2941 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2942 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2943 fmt.fmt.pix_mp.pixelformat = capture_capability;
2944 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);
2945 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2946 if (ret) {
2947 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2948 eRet = OMX_ErrorUnsupportedSetting;
2949 } else
2950 eRet = get_buffer_req(&drv_ctx.op_buf);
2951 }
Praveen Chavane78460c2013-12-06 23:16:04 -08002952 }
Arun Menon906de572013-06-18 17:01:40 -07002953 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002954 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07002955 eRet = OMX_ErrorBadParameter;
2956 } else {
2957 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2958 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2959 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2960 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2961 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2962 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2963 drv_ctx.extradata_info.buffer_size;
2964 eRet = set_buffer_req(&drv_ctx.op_buf);
2965 if (eRet == OMX_ErrorNone)
2966 m_port_def = *portDefn;
2967 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002968 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07002969 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2970 portDefn->nBufferCountActual, portDefn->nBufferSize);
2971 eRet = OMX_ErrorBadParameter;
2972 }
2973 }
2974 } else if (OMX_DirInput == portDefn->eDir) {
2975 bool port_format_changed = false;
2976 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2977 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2978 // Frame rate only should be set if this is a "known value" or to
2979 // activate ts prediction logic (arbitrary mode only) sending input
2980 // timestamps with max value (LLONG_MAX).
2981 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2982 portDefn->format.video.xFramerate >> 16);
2983 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2984 drv_ctx.frame_rate.fps_denominator);
2985 if (!drv_ctx.frame_rate.fps_numerator) {
2986 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2987 drv_ctx.frame_rate.fps_numerator = 30;
2988 }
2989 if (drv_ctx.frame_rate.fps_denominator)
2990 drv_ctx.frame_rate.fps_numerator = (int)
2991 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2992 drv_ctx.frame_rate.fps_denominator = 1;
2993 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2994 drv_ctx.frame_rate.fps_numerator;
2995 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2996 frm_int, drv_ctx.frame_rate.fps_numerator /
2997 (float)drv_ctx.frame_rate.fps_denominator);
2998 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002999 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003000 if (drv_ctx.video_resolution.frame_height !=
3001 portDefn->format.video.nFrameHeight ||
3002 drv_ctx.video_resolution.frame_width !=
3003 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003004 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003005 portDefn->format.video.nFrameWidth,
3006 portDefn->format.video.nFrameHeight);
3007 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003008 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3009 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3010 if (frameHeight != 0x0 && frameWidth != 0x0) {
3011 if (m_smoothstreaming_mode &&
3012 ((frameWidth * frameHeight) <
3013 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3014 frameWidth = m_smoothstreaming_width;
3015 frameHeight = m_smoothstreaming_height;
3016 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3017 frameWidth, frameHeight);
3018 }
3019 update_resolution(frameWidth, frameHeight,
3020 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003021 eRet = is_video_session_supported();
3022 if (eRet)
3023 break;
3024 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3025 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3026 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3027 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003028 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 -07003029 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3030 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003031 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003032 eRet = OMX_ErrorUnsupportedSetting;
3033 } else
3034 eRet = get_buffer_req(&drv_ctx.op_buf);
3035 }
3036 }
3037 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3038 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3039 port_format_changed = true;
3040 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3041 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3042 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3043 (~(buffer_prop->alignment - 1));
3044 eRet = set_buffer_req(buffer_prop);
3045 }
3046 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003047 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003048 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3049 portDefn->nBufferCountActual, portDefn->nBufferSize);
3050 eRet = OMX_ErrorBadParameter;
3051 }
3052 } else if (portDefn->eDir == OMX_DirMax) {
3053 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3054 (int)portDefn->nPortIndex);
3055 eRet = OMX_ErrorBadPortIndex;
3056 }
3057 }
3058 break;
3059 case OMX_IndexParamVideoPortFormat: {
3060 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3061 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3062 int ret=0;
3063 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003064 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003065 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003066
Arun Menon906de572013-06-18 17:01:40 -07003067 if (1 == portFmt->nPortIndex) {
3068 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3069 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3070 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3071 fmt.fmt.pix_mp.pixelformat = capture_capability;
3072 enum vdec_output_fromat op_format;
3073 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3074 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3075 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3076 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3077 else if (portFmt->eColorFormat ==
3078 (OMX_COLOR_FORMATTYPE)
3079 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3080 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3081 else
3082 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003083
Arun Menon906de572013-06-18 17:01:40 -07003084 if (eRet == OMX_ErrorNone) {
3085 drv_ctx.output_format = op_format;
3086 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3087 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003088 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003089 eRet = OMX_ErrorUnsupportedSetting;
3090 /*TODO: How to handle this case */
3091 } else {
3092 eRet = get_buffer_req(&drv_ctx.op_buf);
3093 }
3094 }
3095 if (eRet == OMX_ErrorNone) {
3096 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003097 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003098 eRet = OMX_ErrorBadParameter;
3099 }
3100 }
3101 }
3102 }
3103 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003104
Arun Menon906de572013-06-18 17:01:40 -07003105 case OMX_QcomIndexPortDefn: {
3106 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3107 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003108 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003109 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003110
Arun Menon906de572013-06-18 17:01:40 -07003111 /* Input port */
3112 if (portFmt->nPortIndex == 0) {
3113 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3114 if (secure_mode) {
3115 arbitrary_bytes = false;
3116 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3117 eRet = OMX_ErrorUnsupportedSetting;
3118 } else {
3119 arbitrary_bytes = true;
3120 }
3121 } else if (portFmt->nFramePackingFormat ==
3122 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3123 arbitrary_bytes = false;
3124 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003125 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003126 portFmt->nFramePackingFormat);
3127 eRet = OMX_ErrorUnsupportedSetting;
3128 }
3129 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003130 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003131 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3132 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3133 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3134 m_out_mem_region_smi = OMX_TRUE;
3135 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003136 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003137 m_use_output_pmem = OMX_TRUE;
3138 }
3139 }
3140 }
3141 }
3142 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003143
Arun Menon906de572013-06-18 17:01:40 -07003144 case OMX_IndexParamStandardComponentRole: {
3145 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3146 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003147 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003148 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003149
Arun Menon906de572013-06-18 17:01:40 -07003150 if ((m_state == OMX_StateLoaded)&&
3151 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3152 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3153 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003154 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003155 return OMX_ErrorIncorrectStateOperation;
3156 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003157
Arun Menon906de572013-06-18 17:01:40 -07003158 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3159 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3160 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3161 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003162 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003163 eRet =OMX_ErrorUnsupportedSetting;
3164 }
3165 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3166 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3167 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3168 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003169 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003170 eRet = OMX_ErrorUnsupportedSetting;
3171 }
3172 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3173 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3174 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3175 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003176 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003177 eRet =OMX_ErrorUnsupportedSetting;
3178 }
3179 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3180 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3181 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3182 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003183 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003184 eRet = OMX_ErrorUnsupportedSetting;
3185 }
3186 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3187 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3188 ) {
3189 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3190 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3191 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003192 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003193 eRet =OMX_ErrorUnsupportedSetting;
3194 }
3195 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3196 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3197 ) {
3198 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3199 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3200 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003201 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003202 eRet =OMX_ErrorUnsupportedSetting;
3203 }
3204 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3205 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3206 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3207 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3208 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003209 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003210 eRet = OMX_ErrorUnsupportedSetting;
3211 }
3212 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003213 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003214 eRet = OMX_ErrorInvalidComponentName;
3215 }
3216 break;
3217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003218
Arun Menon906de572013-06-18 17:01:40 -07003219 case OMX_IndexParamPriorityMgmt: {
3220 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003221 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003222 return OMX_ErrorIncorrectStateOperation;
3223 }
3224 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003225 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003226 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003227
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003228 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003229 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003230
Arun Menon906de572013-06-18 17:01:40 -07003231 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3232 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003233
Arun Menon906de572013-06-18 17:01:40 -07003234 break;
3235 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003236
Arun Menon906de572013-06-18 17:01:40 -07003237 case OMX_IndexParamCompBufferSupplier: {
3238 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003239 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003240 bufferSupplierType->eBufferSupplier);
3241 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3242 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003243
Arun Menon906de572013-06-18 17:01:40 -07003244 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003245
Arun Menon906de572013-06-18 17:01:40 -07003246 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247
Arun Menon906de572013-06-18 17:01:40 -07003248 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003249
Arun Menon906de572013-06-18 17:01:40 -07003250 }
3251 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003252 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003253 paramIndex);
3254 break;
3255 }
3256 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003257 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003258 paramIndex);
3259 break;
3260 }
3261 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003262 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003263 paramIndex);
3264 break;
3265 }
3266 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003267 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003268 paramIndex);
3269 break;
3270 }
3271 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3272 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3273 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3274 struct v4l2_control control;
3275 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003276 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003277 pictureOrder->eOutputPictureOrder);
3278 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3279 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3280 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3281 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3282 time_stamp_dts.set_timestamp_reorder_mode(false);
3283 } else
3284 eRet = OMX_ErrorBadParameter;
3285 if (eRet == OMX_ErrorNone) {
3286 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3287 control.value = pic_order;
3288 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3289 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003290 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003291 eRet = OMX_ErrorUnsupportedSetting;
3292 }
3293 }
3294 break;
3295 }
3296 case OMX_QcomIndexParamConcealMBMapExtraData:
3297 if (!secure_mode)
3298 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3299 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3300 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003301 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003302 eRet = OMX_ErrorUnsupportedSetting;
3303 }
3304 break;
3305 case OMX_QcomIndexParamFrameInfoExtraData: {
3306 if (!secure_mode)
3307 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3308 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3309 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003310 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003311 eRet = OMX_ErrorUnsupportedSetting;
3312 }
3313 break;
3314 }
3315 case OMX_QcomIndexParamInterlaceExtraData:
3316 if (!secure_mode)
3317 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3318 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3319 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003320 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003321 eRet = OMX_ErrorUnsupportedSetting;
3322 }
3323 break;
3324 case OMX_QcomIndexParamH264TimeInfo:
3325 if (!secure_mode)
3326 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3327 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3328 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003329 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003330 eRet = OMX_ErrorUnsupportedSetting;
3331 }
3332 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303333 case OMX_QcomIndexParamVideoFramePackingExtradata:
3334 if (!secure_mode)
3335 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3336 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3337 else {
3338 DEBUG_PRINT_ERROR("\n Setting extradata in secure mode is not supported");
3339 eRet = OMX_ErrorUnsupportedSetting;
3340 }
3341 break;
Arun Menon906de572013-06-18 17:01:40 -07003342 case OMX_QcomIndexParamVideoDivx: {
3343 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3344 }
3345 break;
3346 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003347 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003348 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3349 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3350 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3351 eRet = OMX_ErrorUnsupportedSetting;
3352 } else {
3353 m_out_pvt_entry_pmem = OMX_TRUE;
3354 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003355 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003356 m_use_output_pmem = OMX_TRUE;
3357 }
3358 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003359
Arun Menon906de572013-06-18 17:01:40 -07003360 }
3361 break;
3362 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3363 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3364 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3365 struct v4l2_control control;
3366 int rc;
3367 drv_ctx.idr_only_decoding = 1;
3368 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3369 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3370 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3371 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003372 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003373 eRet = OMX_ErrorUnsupportedSetting;
3374 } else {
3375 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3376 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3377 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3378 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003379 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003380 eRet = OMX_ErrorUnsupportedSetting;
3381 }
3382 /*Setting sync frame decoding on driver might change buffer
3383 * requirements so update them here*/
3384 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003385 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003386 eRet = OMX_ErrorUnsupportedSetting;
3387 }
3388 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003389 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003390 eRet = OMX_ErrorUnsupportedSetting;
3391 }
3392 }
3393 }
3394 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003395
Arun Menon906de572013-06-18 17:01:40 -07003396 case OMX_QcomIndexParamIndexExtraDataType: {
3397 if (!secure_mode) {
3398 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3399 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3400 (extradataIndexType->bEnabled == OMX_TRUE) &&
3401 (extradataIndexType->nPortIndex == 1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003402 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
Arun Menon906de572013-06-18 17:01:40 -07003403 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003404
Arun Menon906de572013-06-18 17:01:40 -07003405 }
3406 }
3407 }
3408 break;
3409 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003410#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003411 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003412#else
Arun Menon906de572013-06-18 17:01:40 -07003413 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003414#endif
Arun Menon906de572013-06-18 17:01:40 -07003415 }
3416 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003417#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003418 /* Need to allow following two set_parameters even in Idle
3419 * state. This is ANDROID architecture which is not in sync
3420 * with openmax standard. */
3421 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3422 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3423 if (enableNativeBuffers) {
3424 m_enable_android_native_buffers = enableNativeBuffers->enable;
3425 }
3426 }
3427 break;
3428 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3429 eRet = use_android_native_buffer(hComp, paramData);
3430 }
3431 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003432#endif
Arun Menon906de572013-06-18 17:01:40 -07003433 case OMX_QcomIndexParamEnableTimeStampReorder: {
3434 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3435 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3436 if (reorder->bEnable == OMX_TRUE) {
3437 frm_int =0;
3438 time_stamp_dts.set_timestamp_reorder_mode(true);
3439 } else
3440 time_stamp_dts.set_timestamp_reorder_mode(false);
3441 } else {
3442 time_stamp_dts.set_timestamp_reorder_mode(false);
3443 if (reorder->bEnable == OMX_TRUE) {
3444 eRet = OMX_ErrorUnsupportedSetting;
3445 }
3446 }
3447 }
3448 break;
3449 case OMX_IndexParamVideoProfileLevelCurrent: {
3450 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3451 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3452 if (pParam) {
3453 m_profile_lvl.eProfile = pParam->eProfile;
3454 m_profile_lvl.eLevel = pParam->eLevel;
3455 }
3456 break;
Arun Menon888aa852013-05-30 11:24:42 -07003457
Arun Menon906de572013-06-18 17:01:40 -07003458 }
Arun Menone5652482013-08-04 13:33:05 -07003459 case OMX_QcomIndexParamVideoMetaBufferMode:
3460 {
3461 StoreMetaDataInBuffersParams *metabuffer =
3462 (StoreMetaDataInBuffersParams *)paramData;
3463 if (!metabuffer) {
3464 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3465 eRet = OMX_ErrorBadParameter;
3466 break;
3467 }
3468 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3469 //set property dynamic buffer mode to driver.
3470 struct v4l2_control control;
3471 struct v4l2_format fmt;
3472 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3473 if (metabuffer->bStoreMetaData == true) {
3474 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3475 } else {
3476 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3477 }
3478 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3479 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003480 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003481 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003482 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003483 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003484 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003485 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3486 eRet = OMX_ErrorUnsupportedSetting;
3487 }
3488 } else {
3489 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003490 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003491 metabuffer->nPortIndex);
3492 eRet = OMX_ErrorUnsupportedSetting;
3493 }
3494 break;
3495 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003496 case OMX_QcomIndexParamVideoDownScalar: {
3497 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3498 struct v4l2_control control;
3499 int rc;
3500 if (pParam) {
3501 is_down_scalar_enabled = pParam->bEnable;
3502 if (is_down_scalar_enabled) {
3503 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3504 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3505 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3506 pParam->bEnable);
3507 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3508 if (rc < 0) {
3509 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3510 eRet = OMX_ErrorUnsupportedSetting;
3511 }
3512 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3513 control.value = 1;
3514 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3515 if (rc < 0) {
3516 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3517 eRet = OMX_ErrorUnsupportedSetting;
3518 }
3519 }
3520 }
3521 break;
3522 }
Praveen Chavancf924182013-12-06 23:16:23 -08003523#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3524 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3525 {
3526 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3527 PrepareForAdaptivePlaybackParams* pParams =
3528 (PrepareForAdaptivePlaybackParams *) paramData;
3529 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3530 if (!pParams->bEnable) {
3531 return OMX_ErrorNone;
3532 }
3533 if (pParams->nMaxFrameWidth > kMaxSmoothStreamingWidth
3534 || pParams->nMaxFrameHeight > kMaxSmoothStreamingHeight) {
3535 DEBUG_PRINT_ERROR(
3536 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3537 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
3538 kMaxSmoothStreamingWidth, kMaxSmoothStreamingHeight);
3539 eRet = OMX_ErrorBadParameter;
3540 } else {
3541 eRet = enable_smoothstreaming();
3542 if (eRet != OMX_ErrorNone) {
3543 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3544 eRet = OMX_ErrorHardware;
3545 } else {
3546 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3547 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3548 m_smoothstreaming_mode = true;
3549 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3550 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3551 }
3552 }
3553 } else {
3554 DEBUG_PRINT_ERROR(
3555 "Prepare for adaptive playback supported only on output port");
3556 eRet = OMX_ErrorBadParameter;
3557 }
3558 break;
3559 }
3560
3561#endif
Arun Menon906de572013-06-18 17:01:40 -07003562 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003563 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003564 eRet = OMX_ErrorUnsupportedIndex;
3565 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003566 }
Arun Menon906de572013-06-18 17:01:40 -07003567 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003568}
3569
3570/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003571 FUNCTION
3572 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003573
Arun Menon906de572013-06-18 17:01:40 -07003574 DESCRIPTION
3575 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003576
Arun Menon906de572013-06-18 17:01:40 -07003577 PARAMETERS
3578 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003579
Arun Menon906de572013-06-18 17:01:40 -07003580 RETURN VALUE
3581 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003582
Arun Menon906de572013-06-18 17:01:40 -07003583 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003584OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003585 OMX_IN OMX_INDEXTYPE configIndex,
3586 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003587{
Arun Menon906de572013-06-18 17:01:40 -07003588 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003589
Arun Menon906de572013-06-18 17:01:40 -07003590 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003591 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003592 return OMX_ErrorInvalidState;
3593 }
Arun Menon906de572013-06-18 17:01:40 -07003594
3595 switch ((unsigned long)configIndex) {
3596 case OMX_QcomIndexConfigInterlaced: {
3597 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3598 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3599 if (configFmt->nPortIndex == 1) {
3600 if (configFmt->nIndex == 0) {
3601 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3602 } else if (configFmt->nIndex == 1) {
3603 configFmt->eInterlaceType =
3604 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3605 } else if (configFmt->nIndex == 2) {
3606 configFmt->eInterlaceType =
3607 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3608 } else {
3609 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003610 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003611 eRet = OMX_ErrorNoMore;
3612 }
3613
3614 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003615 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003616 (int)configFmt->nPortIndex);
3617 eRet = OMX_ErrorBadPortIndex;
3618 }
3619 break;
3620 }
3621 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3622 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3623 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3624 decoderinstances->nNumOfInstances = 16;
3625 /*TODO: How to handle this case */
3626 break;
3627 }
3628 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3629 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3630 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3631 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303632 memcpy(configFmt, &m_frame_pack_arrangement,
3633 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003634 } else {
3635 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3636 }
3637 break;
3638 }
3639 case OMX_IndexConfigCommonOutputCrop: {
3640 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3641 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3642 break;
3643 }
3644 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003645 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003646 eRet = OMX_ErrorBadParameter;
3647 }
3648
Shalaj Jain273b3e02012-06-22 19:08:03 -07003649 }
Arun Menon906de572013-06-18 17:01:40 -07003650
3651 return eRet;
3652}
3653
3654/* ======================================================================
3655 FUNCTION
3656 omx_vdec::SetConfig
3657
3658 DESCRIPTION
3659 OMX Set Config method implementation
3660
3661 PARAMETERS
3662 <TBD>.
3663
3664 RETURN VALUE
3665 OMX Error None if successful.
3666 ========================================================================== */
3667OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3668 OMX_IN OMX_INDEXTYPE configIndex,
3669 OMX_IN OMX_PTR configData)
3670{
3671 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003672 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003673 return OMX_ErrorInvalidState;
3674 }
3675
3676 OMX_ERRORTYPE ret = OMX_ErrorNone;
3677 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3678
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003679 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003680
3681 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3682 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003683 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003684 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003685 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003686 OMX_U32 extra_size;
3687 // Parsing done here for the AVC atom is definitely not generic
3688 // Currently this piece of code is working, but certainly
3689 // not tested with all .mp4 files.
3690 // Incase of failure, we might need to revisit this
3691 // for a generic piece of code.
3692
3693 // Retrieve size of NAL length field
3694 // byte #4 contains the size of NAL lenght field
3695 nal_length = (config->pData[4] & 0x03) + 1;
3696
3697 extra_size = 0;
3698 if (nal_length > 2) {
3699 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3700 extra_size = (nal_length - 2) * 2;
3701 }
3702
3703 // SPS starts from byte #6
3704 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3705 OMX_U8 *pDestBuf;
3706 m_vendor_config.nPortIndex = config->nPortIndex;
3707
3708 // minus 6 --> SPS starts from byte #6
3709 // minus 1 --> picture param set byte to be ignored from avcatom
3710 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3711 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3712 OMX_U32 len;
3713 OMX_U8 index = 0;
3714 // case where SPS+PPS is sent as part of set_config
3715 pDestBuf = m_vendor_config.pData;
3716
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003717 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003718 m_vendor_config.nPortIndex,
3719 m_vendor_config.nDataSize,
3720 m_vendor_config.pData);
3721 while (index < 2) {
3722 uint8 *psize;
3723 len = *pSrcBuf;
3724 len = len << 8;
3725 len |= *(pSrcBuf + 1);
3726 psize = (uint8 *) & len;
3727 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3728 for (unsigned int i = 0; i < nal_length; i++) {
3729 pDestBuf[i] = psize[nal_length - 1 - i];
3730 }
3731 //memcpy(pDestBuf,pSrcBuf,(len+2));
3732 pDestBuf += len + nal_length;
3733 pSrcBuf += len + 2;
3734 index++;
3735 pSrcBuf++; // skip picture param set
3736 len = 0;
3737 }
3738 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3739 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3740 m_vendor_config.nPortIndex = config->nPortIndex;
3741 m_vendor_config.nDataSize = config->nDataSize;
3742 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3743 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3744 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3745 if (m_vendor_config.pData) {
3746 free(m_vendor_config.pData);
3747 m_vendor_config.pData = NULL;
3748 m_vendor_config.nDataSize = 0;
3749 }
3750
3751 if (((*((OMX_U32 *) config->pData)) &
3752 VC1_SP_MP_START_CODE_MASK) ==
3753 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003754 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003755 m_vendor_config.nPortIndex = config->nPortIndex;
3756 m_vendor_config.nDataSize = config->nDataSize;
3757 m_vendor_config.pData =
3758 (OMX_U8 *) malloc(config->nDataSize);
3759 memcpy(m_vendor_config.pData, config->pData,
3760 config->nDataSize);
3761 m_vc1_profile = VC1_SP_MP_RCV;
3762 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003763 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003764 m_vendor_config.nPortIndex = config->nPortIndex;
3765 m_vendor_config.nDataSize = config->nDataSize;
3766 m_vendor_config.pData =
3767 (OMX_U8 *) malloc((config->nDataSize));
3768 memcpy(m_vendor_config.pData, config->pData,
3769 config->nDataSize);
3770 m_vc1_profile = VC1_AP;
3771 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003772 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003773 m_vendor_config.nPortIndex = config->nPortIndex;
3774 m_vendor_config.nDataSize = config->nDataSize;
3775 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3776 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3777 m_vc1_profile = VC1_SP_MP_RCV;
3778 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003779 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003780 }
3781 }
3782 return ret;
3783 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3784 struct v4l2_control temp;
3785 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3786
3787 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3788 switch (pNal->nNaluBytes) {
3789 case 0:
3790 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3791 break;
3792 case 2:
3793 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3794 break;
3795 case 4:
3796 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3797 break;
3798 default:
3799 return OMX_ErrorUnsupportedSetting;
3800 }
3801
3802 if (!arbitrary_bytes) {
3803 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3804 * with start code, so only need to notify driver in frame by frame mode */
3805 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3806 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3807 return OMX_ErrorHardware;
3808 }
3809 }
3810
3811 nal_length = pNal->nNaluBytes;
3812 m_frame_parser.init_nal_length(nal_length);
3813
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003814 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003815 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303816 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003817 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303818 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003819
3820 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3821 if (config->bEnabled) {
3822 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303823 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003824 config->nFps >> 16);
3825 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3826 drv_ctx.frame_rate.fps_denominator);
3827
3828 if (!drv_ctx.frame_rate.fps_numerator) {
3829 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3830 drv_ctx.frame_rate.fps_numerator = 30;
3831 }
3832
3833 if (drv_ctx.frame_rate.fps_denominator) {
3834 drv_ctx.frame_rate.fps_numerator = (int)
3835 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3836 }
3837
3838 drv_ctx.frame_rate.fps_denominator = 1;
3839 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3840 drv_ctx.frame_rate.fps_numerator;
3841
3842 struct v4l2_outputparm oparm;
3843 /*XXX: we're providing timing info as seconds per frame rather than frames
3844 * per second.*/
3845 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3846 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3847
3848 struct v4l2_streamparm sparm;
3849 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3850 sparm.parm.output = oparm;
3851 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3852 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3853 performance might be affected");
3854 ret = OMX_ErrorHardware;
3855 }
3856 client_set_fps = true;
3857 } else {
3858 DEBUG_PRINT_ERROR("Frame rate not supported.");
3859 ret = OMX_ErrorUnsupportedSetting;
3860 }
3861 } else {
3862 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3863 client_set_fps = false;
3864 }
3865 } else {
3866 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3867 (int)config->nPortIndex);
3868 ret = OMX_ErrorBadPortIndex;
3869 }
3870
3871 return ret;
3872 }
3873
3874 return OMX_ErrorNotImplemented;
3875}
3876
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303877#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3878
Arun Menon906de572013-06-18 17:01:40 -07003879/* ======================================================================
3880 FUNCTION
3881 omx_vdec::GetExtensionIndex
3882
3883 DESCRIPTION
3884 OMX GetExtensionIndex method implementaion. <TBD>
3885
3886 PARAMETERS
3887 <TBD>.
3888
3889 RETURN VALUE
3890 OMX Error None if everything successful.
3891
3892 ========================================================================== */
3893OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3894 OMX_IN OMX_STRING paramName,
3895 OMX_OUT OMX_INDEXTYPE* indexType)
3896{
3897 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003898 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003899 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303900 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003901 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303902 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003903 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303904 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3905 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3906 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3907 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003908 }
3909#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303910 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003911 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303912 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003913 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303914 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003915 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003916 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303917 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003918 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3919 }
3920#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303921 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07003922 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3923 }
Praveen Chavancf924182013-12-06 23:16:23 -08003924#if ADAPTIVE_PLAYBACK_SUPPORTED
3925 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
3926 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
3927 }
3928#endif
Arun Menon906de572013-06-18 17:01:40 -07003929 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003930 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003931 return OMX_ErrorNotImplemented;
3932 }
3933 return OMX_ErrorNone;
3934}
3935
3936/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003937 FUNCTION
3938 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003939
Arun Menon906de572013-06-18 17:01:40 -07003940 DESCRIPTION
3941 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003942
Arun Menon906de572013-06-18 17:01:40 -07003943 PARAMETERS
3944 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003945
Arun Menon906de572013-06-18 17:01:40 -07003946 RETURN VALUE
3947 Error None if everything is successful.
3948 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003949OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003950 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003951{
Arun Menon906de572013-06-18 17:01:40 -07003952 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003953 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07003954 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003955}
3956
3957/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003958 FUNCTION
3959 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003960
Arun Menon906de572013-06-18 17:01:40 -07003961 DESCRIPTION
3962 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003963
Arun Menon906de572013-06-18 17:01:40 -07003964 PARAMETERS
3965 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003966
Arun Menon906de572013-06-18 17:01:40 -07003967 RETURN VALUE
3968 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003969
Arun Menon906de572013-06-18 17:01:40 -07003970 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003971OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003972 OMX_IN OMX_U32 port,
3973 OMX_IN OMX_HANDLETYPE peerComponent,
3974 OMX_IN OMX_U32 peerPort,
3975 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003976{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003977 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07003978 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003979}
3980
3981/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003982 FUNCTION
3983 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003984
Arun Menon906de572013-06-18 17:01:40 -07003985 DESCRIPTION
3986 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003987
Arun Menon906de572013-06-18 17:01:40 -07003988 PARAMETERS
3989 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003990
Arun Menon906de572013-06-18 17:01:40 -07003991 RETURN VALUE
3992 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003993
Arun Menon906de572013-06-18 17:01:40 -07003994 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003995OMX_ERRORTYPE omx_vdec::allocate_extradata()
3996{
3997#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003998 if (drv_ctx.extradata_info.buffer_size) {
3999 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4000 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4001 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4002 free_ion_memory(&drv_ctx.extradata_info.ion);
4003 }
4004 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4005 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4006 drv_ctx.extradata_info.size, 4096,
4007 &drv_ctx.extradata_info.ion.ion_alloc_data,
4008 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4009 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004010 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004011 return OMX_ErrorInsufficientResources;
4012 }
4013 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4014 drv_ctx.extradata_info.size,
4015 PROT_READ|PROT_WRITE, MAP_SHARED,
4016 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4017 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004018 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004019 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4020 free_ion_memory(&drv_ctx.extradata_info.ion);
4021 return OMX_ErrorInsufficientResources;
4022 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004023 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004024#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304025 if (!m_other_extradata) {
4026 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4027 if (!m_other_extradata) {
4028 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4029 return OMX_ErrorInsufficientResources;
4030 }
4031 }
Arun Menon906de572013-06-18 17:01:40 -07004032 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004033}
4034
Arun Menon906de572013-06-18 17:01:40 -07004035void omx_vdec::free_extradata()
4036{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004037#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004038 if (drv_ctx.extradata_info.uaddr) {
4039 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4040 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4041 free_ion_memory(&drv_ctx.extradata_info.ion);
4042 }
4043 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004044#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304045 if (m_other_extradata) {
4046 free(m_other_extradata);
4047 m_other_extradata = NULL;
4048 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004049}
4050
Shalaj Jain273b3e02012-06-22 19:08:03 -07004051OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004052 OMX_IN OMX_HANDLETYPE hComp,
4053 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4054 OMX_IN OMX_U32 port,
4055 OMX_IN OMX_PTR appData,
4056 OMX_IN OMX_U32 bytes,
4057 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004058{
Arun Menon906de572013-06-18 17:01:40 -07004059 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4060 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4061 unsigned i= 0; // Temporary counter
4062 struct vdec_setbuffer_cmd setbuffers;
4063 OMX_PTR privateAppData = NULL;
4064 private_handle_t *handle = NULL;
4065 OMX_U8 *buff = buffer;
4066 struct v4l2_buffer buf;
4067 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4068 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004069
Arun Menon906de572013-06-18 17:01:40 -07004070 if (!m_out_mem_ptr) {
4071 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4072 eRet = allocate_output_headers();
4073 if (eRet == OMX_ErrorNone)
4074 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004075 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004076
Arun Menon906de572013-06-18 17:01:40 -07004077 if (eRet == OMX_ErrorNone) {
4078 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4079 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4080 break;
4081 }
4082 }
4083 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004084
Arun Menon906de572013-06-18 17:01:40 -07004085 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004086 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004087 eRet = OMX_ErrorInsufficientResources;
4088 }
4089
Arun Menonbdb80b02013-08-12 17:45:54 -07004090 if (dynamic_buf_mode) {
4091 *bufferHdr = (m_out_mem_ptr + i );
4092 (*bufferHdr)->pBuffer = NULL;
4093 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4094 enum v4l2_buf_type buf_type;
4095 int rr = 0;
4096 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4097 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4098 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4099 return OMX_ErrorInsufficientResources;
4100 } else {
4101 streaming[CAPTURE_PORT] = true;
4102 DEBUG_PRINT_LOW("STREAMON Successful");
4103 }
4104 }
4105 BITMASK_SET(&m_out_bm_count,i);
4106 (*bufferHdr)->pAppPrivate = appData;
4107 (*bufferHdr)->pBuffer = buffer;
4108 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4109 return eRet;
4110 }
Arun Menon906de572013-06-18 17:01:40 -07004111 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004112#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004113 if (m_enable_android_native_buffers) {
4114 if (m_use_android_native_buffers) {
4115 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4116 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4117 handle = (private_handle_t *)nBuf->handle;
4118 privateAppData = params->pAppPrivate;
4119 } else {
4120 handle = (private_handle_t *)buff;
4121 privateAppData = appData;
4122 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004123
Arun Menon906de572013-06-18 17:01:40 -07004124 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4125 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4126 " expected %u, got %lu",
4127 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4128 return OMX_ErrorBadParameter;
4129 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004130
Arun Menon906de572013-06-18 17:01:40 -07004131 if (!m_use_android_native_buffers) {
4132 if (!secure_mode) {
4133 buff = (OMX_U8*)mmap(0, handle->size,
4134 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4135 if (buff == MAP_FAILED) {
4136 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4137 return OMX_ErrorInsufficientResources;
4138 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004139 }
4140 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004141#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004142 native_buffer[i].nativehandle = handle;
4143 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004144#endif
Arun Menon906de572013-06-18 17:01:40 -07004145 if (!handle) {
4146 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4147 return OMX_ErrorBadParameter;
4148 }
4149 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4150 drv_ctx.ptr_outputbuffer[i].offset = 0;
4151 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4152 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4153 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4154 } else
4155#endif
4156
4157 if (!ouput_egl_buffers && !m_use_output_pmem) {
4158#ifdef USE_ION
4159 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4160 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4161 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4162 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4163 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004164 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 -07004165 return OMX_ErrorInsufficientResources;
4166 }
4167 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4168 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4169#else
4170 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4171 open (MEM_DEVICE,O_RDWR);
4172
4173 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004174 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004175 return OMX_ErrorInsufficientResources;
4176 }
4177
4178 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4179 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4180 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4181 open (MEM_DEVICE,O_RDWR);
4182 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004183 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004184 return OMX_ErrorInsufficientResources;
4185 }
4186 }
4187
4188 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4189 drv_ctx.op_buf.buffer_size,
4190 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004191 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004192 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4193 return OMX_ErrorInsufficientResources;
4194 }
4195#endif
4196 if (!secure_mode) {
4197 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4198 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4199 PROT_READ|PROT_WRITE, MAP_SHARED,
4200 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4201 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4202 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4203#ifdef USE_ION
4204 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4205#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004206 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004207 return OMX_ErrorInsufficientResources;
4208 }
4209 }
4210 drv_ctx.ptr_outputbuffer[i].offset = 0;
4211 privateAppData = appData;
4212 } else {
4213
4214 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4215 if (!appData || !bytes ) {
4216 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004217 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004218 return OMX_ErrorBadParameter;
4219 }
4220 }
4221
4222 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4223 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4224 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4225 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4226 !pmem_list->nEntries ||
4227 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004228 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004229 return OMX_ErrorBadParameter;
4230 }
4231 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4232 pmem_list->entryList->entry;
4233 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4234 pmem_info->pmem_fd);
4235 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4236 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4237 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4238 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4239 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4240 privateAppData = appData;
4241 }
4242 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4243 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304244 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4245 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4246 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004247
4248 *bufferHdr = (m_out_mem_ptr + i );
4249 if (secure_mode)
4250 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4251 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4252 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4253 sizeof (vdec_bufferpayload));
4254
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004255 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004256 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4257 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4258
4259 buf.index = i;
4260 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4261 buf.memory = V4L2_MEMORY_USERPTR;
4262 plane[0].length = drv_ctx.op_buf.buffer_size;
4263 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4264 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4265 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4266 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4267 plane[0].data_offset = 0;
4268 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4269 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4270 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4271 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4272#ifdef USE_ION
4273 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4274#endif
4275 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4276 plane[extra_idx].data_offset = 0;
4277 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004278 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004279 return OMX_ErrorBadParameter;
4280 }
Arun Menon906de572013-06-18 17:01:40 -07004281 buf.m.planes = plane;
4282 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004283
Arun Menon906de572013-06-18 17:01:40 -07004284 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004285 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004286 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004287 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288 }
4289
Arun Menon906de572013-06-18 17:01:40 -07004290 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4291 enum v4l2_buf_type buf_type;
4292 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4293 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4294 return OMX_ErrorInsufficientResources;
4295 } else {
4296 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004297 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004298 }
4299 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004300
Arun Menon906de572013-06-18 17:01:40 -07004301 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4302 if (m_enable_android_native_buffers) {
4303 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4304 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4305 } else {
4306 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004307 }
Arun Menon906de572013-06-18 17:01:40 -07004308 (*bufferHdr)->pAppPrivate = privateAppData;
4309 BITMASK_SET(&m_out_bm_count,i);
4310 }
4311 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004312}
4313
4314/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004315 FUNCTION
4316 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004317
Arun Menon906de572013-06-18 17:01:40 -07004318 DESCRIPTION
4319 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004320
Arun Menon906de572013-06-18 17:01:40 -07004321 PARAMETERS
4322 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004323
Arun Menon906de572013-06-18 17:01:40 -07004324 RETURN VALUE
4325 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004326
Arun Menon906de572013-06-18 17:01:40 -07004327 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004329 OMX_IN OMX_HANDLETYPE hComp,
4330 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4331 OMX_IN OMX_U32 port,
4332 OMX_IN OMX_PTR appData,
4333 OMX_IN OMX_U32 bytes,
4334 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004335{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004336 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004337 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4338 if (!m_inp_heap_ptr)
4339 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4340 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4341 drv_ctx.ip_buf.actualcount);
4342 if (!m_phdr_pmem_ptr)
4343 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4344 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4345 drv_ctx.ip_buf.actualcount);
4346 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4347 DEBUG_PRINT_ERROR("Insufficent memory");
4348 eRet = OMX_ErrorInsufficientResources;
4349 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4350 input_use_buffer = true;
4351 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4352 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4353 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4354 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4355 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4356 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4357 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4358 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004359 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 -07004360 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4361 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004362 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004363 return OMX_ErrorInsufficientResources;
4364 }
4365 m_in_alloc_cnt++;
4366 } else {
4367 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4368 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369 }
Arun Menon906de572013-06-18 17:01:40 -07004370 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004371}
4372
4373/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004374 FUNCTION
4375 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004376
Arun Menon906de572013-06-18 17:01:40 -07004377 DESCRIPTION
4378 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004379
Arun Menon906de572013-06-18 17:01:40 -07004380 PARAMETERS
4381 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004382
Arun Menon906de572013-06-18 17:01:40 -07004383 RETURN VALUE
4384 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004385
Arun Menon906de572013-06-18 17:01:40 -07004386 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004387OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004388 OMX_IN OMX_HANDLETYPE hComp,
4389 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4390 OMX_IN OMX_U32 port,
4391 OMX_IN OMX_PTR appData,
4392 OMX_IN OMX_U32 bytes,
4393 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004394{
Arun Menon906de572013-06-18 17:01:40 -07004395 OMX_ERRORTYPE error = OMX_ErrorNone;
4396 struct vdec_setbuffer_cmd setbuffers;
4397
4398 if (bufferHdr == NULL || bytes == 0) {
4399 if (!secure_mode && buffer == NULL) {
4400 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4401 return OMX_ErrorBadParameter;
4402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004403 }
Arun Menon906de572013-06-18 17:01:40 -07004404 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004405 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004406 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004407 }
Arun Menon906de572013-06-18 17:01:40 -07004408 if (port == OMX_CORE_INPUT_PORT_INDEX)
4409 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4410 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4411 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4412 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004413 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004414 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004415 }
Arun Menon906de572013-06-18 17:01:40 -07004416 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4417 if (error == OMX_ErrorNone) {
4418 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4419 // Send the callback now
4420 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4421 post_event(OMX_CommandStateSet,OMX_StateIdle,
4422 OMX_COMPONENT_GENERATE_EVENT);
4423 }
4424 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4425 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4426 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4427 post_event(OMX_CommandPortEnable,
4428 OMX_CORE_INPUT_PORT_INDEX,
4429 OMX_COMPONENT_GENERATE_EVENT);
4430 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4431 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4432 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4433 post_event(OMX_CommandPortEnable,
4434 OMX_CORE_OUTPUT_PORT_INDEX,
4435 OMX_COMPONENT_GENERATE_EVENT);
4436 }
4437 }
4438 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004439}
4440
4441OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004442 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004443{
Arun Menon906de572013-06-18 17:01:40 -07004444 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4445 if (m_inp_heap_ptr[bufferindex].pBuffer)
4446 free(m_inp_heap_ptr[bufferindex].pBuffer);
4447 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4448 }
4449 if (pmem_bufferHdr)
4450 free_input_buffer(pmem_bufferHdr);
4451 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004452}
4453
4454OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4455{
Arun Menon906de572013-06-18 17:01:40 -07004456 unsigned int index = 0;
4457 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4458 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004459 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004460
Arun Menon906de572013-06-18 17:01:40 -07004461 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004462 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004463
4464 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004465 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004466 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4467 struct vdec_setbuffer_cmd setbuffers;
4468 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4469 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4470 sizeof (vdec_bufferpayload));
4471 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004472 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004473 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004474 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004475 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4476 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4477 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4478 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4479 }
4480 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4481 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4482 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4483 free(m_desc_buffer_ptr[index].buf_addr);
4484 m_desc_buffer_ptr[index].buf_addr = NULL;
4485 m_desc_buffer_ptr[index].desc_data_size = 0;
4486 }
4487#ifdef USE_ION
4488 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4489#endif
4490 }
4491 }
4492
4493 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004494}
4495
4496OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4497{
Arun Menon906de572013-06-18 17:01:40 -07004498 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004499
Arun Menon906de572013-06-18 17:01:40 -07004500 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4501 return OMX_ErrorBadParameter;
4502 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004503
Arun Menon906de572013-06-18 17:01:40 -07004504 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004505 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004506
Arun Menon906de572013-06-18 17:01:40 -07004507 if (index < drv_ctx.op_buf.actualcount
4508 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004509 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004510 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004511
Arun Menon906de572013-06-18 17:01:40 -07004512 struct vdec_setbuffer_cmd setbuffers;
4513 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4514 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4515 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004516#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004517 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004518 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004519 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4520 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4521 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4522 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004523 }
Arun Menon906de572013-06-18 17:01:40 -07004524 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4525 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004526#endif
Arun Menon906de572013-06-18 17:01:40 -07004527 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4528 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004529 DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
Arun Menon906de572013-06-18 17:01:40 -07004530 drv_ctx.ptr_outputbuffer[0].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004531 DEBUG_PRINT_LOW("unmap the ouput buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004532 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4533 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4534 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4535 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4536 }
4537 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4538 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004539#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004540 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541#endif
Arun Menon906de572013-06-18 17:01:40 -07004542 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004543#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004544 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004545#endif
Arun Menon906de572013-06-18 17:01:40 -07004546 if (release_output_done()) {
4547 free_extradata();
4548 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004549 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004550
Arun Menon906de572013-06-18 17:01:40 -07004551 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552
4553}
4554
4555OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004556 OMX_BUFFERHEADERTYPE **bufferHdr,
4557 OMX_U32 port,
4558 OMX_PTR appData,
4559 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004560{
Arun Menon906de572013-06-18 17:01:40 -07004561 OMX_BUFFERHEADERTYPE *input = NULL;
4562 unsigned char *buf_addr = NULL;
4563 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4564 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565
Arun Menon906de572013-06-18 17:01:40 -07004566 /* Sanity Check*/
4567 if (bufferHdr == NULL) {
4568 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569 }
4570
Arun Menon906de572013-06-18 17:01:40 -07004571 if (m_inp_heap_ptr == NULL) {
4572 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4573 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4574 drv_ctx.ip_buf.actualcount);
4575 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4576 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4577 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004578
Arun Menon906de572013-06-18 17:01:40 -07004579 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004580 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004581 return OMX_ErrorInsufficientResources;
4582 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004583 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004584
Arun Menon906de572013-06-18 17:01:40 -07004585 /*Find a Free index*/
4586 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4587 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004588 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004589 break;
4590 }
4591 }
4592
4593 if (i < drv_ctx.ip_buf.actualcount) {
4594 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4595
4596 if (buf_addr == NULL) {
4597 return OMX_ErrorInsufficientResources;
4598 }
4599
4600 *bufferHdr = (m_inp_heap_ptr + i);
4601 input = *bufferHdr;
4602 BITMASK_SET(&m_heap_inp_bm_count,i);
4603
4604 input->pBuffer = (OMX_U8 *)buf_addr;
4605 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4606 input->nVersion.nVersion = OMX_SPEC_VERSION;
4607 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4608 input->pAppPrivate = appData;
4609 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004610 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004611 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004612 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004613 /*Add the Buffers to freeq*/
4614 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4615 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004616 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004617 return OMX_ErrorInsufficientResources;
4618 }
4619 } else {
4620 return OMX_ErrorBadParameter;
4621 }
4622
4623 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624
4625}
4626
4627
4628/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004629 FUNCTION
4630 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004631
Arun Menon906de572013-06-18 17:01:40 -07004632 DESCRIPTION
4633 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004634
Arun Menon906de572013-06-18 17:01:40 -07004635 PARAMETERS
4636 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004637
Arun Menon906de572013-06-18 17:01:40 -07004638 RETURN VALUE
4639 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004640
Arun Menon906de572013-06-18 17:01:40 -07004641 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004642OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004643 OMX_IN OMX_HANDLETYPE hComp,
4644 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4645 OMX_IN OMX_U32 port,
4646 OMX_IN OMX_PTR appData,
4647 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648{
4649
Arun Menon906de572013-06-18 17:01:40 -07004650 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4651 struct vdec_setbuffer_cmd setbuffers;
4652 OMX_BUFFERHEADERTYPE *input = NULL;
4653 unsigned i = 0;
4654 unsigned char *buf_addr = NULL;
4655 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004656
Arun Menon906de572013-06-18 17:01:40 -07004657 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004658 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004659 bytes, drv_ctx.ip_buf.buffer_size);
4660 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004661 }
4662
Arun Menon906de572013-06-18 17:01:40 -07004663 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004664 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004665 drv_ctx.ip_buf.actualcount,
4666 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004667
Arun Menon906de572013-06-18 17:01:40 -07004668 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4669 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4670
4671 if (m_inp_mem_ptr == NULL) {
4672 return OMX_ErrorInsufficientResources;
4673 }
4674
4675 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4676 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4677
4678 if (drv_ctx.ptr_inputbuffer == NULL) {
4679 return OMX_ErrorInsufficientResources;
4680 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004681#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004682 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4683 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004684
Arun Menon906de572013-06-18 17:01:40 -07004685 if (drv_ctx.ip_buf_ion_info == NULL) {
4686 return OMX_ErrorInsufficientResources;
4687 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688#endif
4689
Arun Menon906de572013-06-18 17:01:40 -07004690 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4691 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004692#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004693 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004694#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004695 }
4696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004697
Arun Menon906de572013-06-18 17:01:40 -07004698 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4699 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004700 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004701 break;
4702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004703 }
Arun Menon906de572013-06-18 17:01:40 -07004704
4705 if (i < drv_ctx.ip_buf.actualcount) {
4706 struct v4l2_buffer buf;
4707 struct v4l2_plane plane;
4708 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004709 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004710#ifdef USE_ION
4711 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4712 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4713 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4714 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4715 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4716 return OMX_ErrorInsufficientResources;
4717 }
4718 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4719#else
4720 pmem_fd = open (MEM_DEVICE,O_RDWR);
4721
4722 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004723 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004724 return OMX_ErrorInsufficientResources;
4725 }
4726
4727 if (pmem_fd == 0) {
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
4736 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4737 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004738 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004739 close(pmem_fd);
4740 return OMX_ErrorInsufficientResources;
4741 }
4742#endif
4743 if (!secure_mode) {
4744 buf_addr = (unsigned char *)mmap(NULL,
4745 drv_ctx.ip_buf.buffer_size,
4746 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4747
4748 if (buf_addr == MAP_FAILED) {
4749 close(pmem_fd);
4750#ifdef USE_ION
4751 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4752#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004753 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004754 return OMX_ErrorInsufficientResources;
4755 }
4756 }
4757 *bufferHdr = (m_inp_mem_ptr + i);
4758 if (secure_mode)
4759 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4760 else
4761 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4762 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4763 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4764 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4765 drv_ctx.ptr_inputbuffer [i].offset = 0;
4766
4767
4768 buf.index = i;
4769 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4770 buf.memory = V4L2_MEMORY_USERPTR;
4771 plane.bytesused = 0;
4772 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4773 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4774 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4775 plane.reserved[1] = 0;
4776 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4777 buf.m.planes = &plane;
4778 buf.length = 1;
4779
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004780 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004781 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4782
4783 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4784
4785 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004786 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004787 /*TODO: How to handle this case */
4788 return OMX_ErrorInsufficientResources;
4789 }
4790
4791 input = *bufferHdr;
4792 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004793 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004794 if (secure_mode)
4795 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4796 else
4797 input->pBuffer = (OMX_U8 *)buf_addr;
4798 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4799 input->nVersion.nVersion = OMX_SPEC_VERSION;
4800 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4801 input->pAppPrivate = appData;
4802 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4803 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4804
4805 if (drv_ctx.disable_dmx) {
4806 eRet = allocate_desc_buffer(i);
4807 }
4808 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004809 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004810 eRet = OMX_ErrorInsufficientResources;
4811 }
4812 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004813}
4814
4815
4816/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004817 FUNCTION
4818 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004819
Arun Menon906de572013-06-18 17:01:40 -07004820 DESCRIPTION
4821 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004822
Arun Menon906de572013-06-18 17:01:40 -07004823 PARAMETERS
4824 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004825
Arun Menon906de572013-06-18 17:01:40 -07004826 RETURN VALUE
4827 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004828
Arun Menon906de572013-06-18 17:01:40 -07004829 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004830OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004831 OMX_IN OMX_HANDLETYPE hComp,
4832 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4833 OMX_IN OMX_U32 port,
4834 OMX_IN OMX_PTR appData,
4835 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836{
Arun Menon906de572013-06-18 17:01:40 -07004837 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4838 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4839 unsigned i= 0; // Temporary counter
4840 struct vdec_setbuffer_cmd setbuffers;
4841 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004842#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004843 int ion_device_fd =-1;
4844 struct ion_allocation_data ion_alloc_data;
4845 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004846#endif
Arun Menon906de572013-06-18 17:01:40 -07004847 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004848 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004849 drv_ctx.op_buf.actualcount,
4850 drv_ctx.op_buf.buffer_size);
4851 int nBufHdrSize = 0;
4852 int nPlatformEntrySize = 0;
4853 int nPlatformListSize = 0;
4854 int nPMEMInfoSize = 0;
4855 int pmem_fd = -1;
4856 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004857
Arun Menon906de572013-06-18 17:01:40 -07004858 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4859 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4860 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004862 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004863 drv_ctx.op_buf.actualcount);
4864 nBufHdrSize = drv_ctx.op_buf.actualcount *
4865 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004866
Arun Menon906de572013-06-18 17:01:40 -07004867 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4868 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4869 nPlatformListSize = drv_ctx.op_buf.actualcount *
4870 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4871 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4872 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004873
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004874 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004875 sizeof(OMX_BUFFERHEADERTYPE),
4876 nPMEMInfoSize,
4877 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004878 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004879 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004880#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004881 ion_device_fd = alloc_map_ion_memory(
4882 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4883 drv_ctx.op_buf.alignment,
4884 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4885 if (ion_device_fd < 0) {
4886 return OMX_ErrorInsufficientResources;
4887 }
4888 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004889#else
Arun Menon906de572013-06-18 17:01:40 -07004890 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004891
Arun Menon906de572013-06-18 17:01:40 -07004892 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004893 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004894 drv_ctx.op_buf.buffer_size);
4895 return OMX_ErrorInsufficientResources;
4896 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004897
Arun Menon906de572013-06-18 17:01:40 -07004898 if (pmem_fd == 0) {
4899 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004900
Arun Menon906de572013-06-18 17:01:40 -07004901 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004902 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004903 drv_ctx.op_buf.buffer_size);
4904 return OMX_ErrorInsufficientResources;
4905 }
4906 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004907
Arun Menon906de572013-06-18 17:01:40 -07004908 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4909 drv_ctx.op_buf.actualcount,
4910 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004911 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004912 close(pmem_fd);
4913 return OMX_ErrorInsufficientResources;
4914 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915#endif
Arun Menon906de572013-06-18 17:01:40 -07004916 if (!secure_mode) {
4917 pmem_baseaddress = (unsigned char *)mmap(NULL,
4918 (drv_ctx.op_buf.buffer_size *
4919 drv_ctx.op_buf.actualcount),
4920 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4921 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004922 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07004923 drv_ctx.op_buf.buffer_size);
4924 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004925#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004926 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927#endif
Arun Menon906de572013-06-18 17:01:40 -07004928 return OMX_ErrorInsufficientResources;
4929 }
4930 }
4931 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4932 // Alloc mem for platform specific info
4933 char *pPtr=NULL;
4934 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4935 nPMEMInfoSize,1);
4936 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4937 calloc (sizeof(struct vdec_bufferpayload),
4938 drv_ctx.op_buf.actualcount);
4939 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4940 calloc (sizeof (struct vdec_output_frameinfo),
4941 drv_ctx.op_buf.actualcount);
4942#ifdef USE_ION
4943 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4944 calloc (sizeof(struct vdec_ion),
4945 drv_ctx.op_buf.actualcount);
4946#endif
4947
4948 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4949 && drv_ctx.ptr_respbuffer) {
4950 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4951 (drv_ctx.op_buf.buffer_size *
4952 drv_ctx.op_buf.actualcount);
4953 bufHdr = m_out_mem_ptr;
4954 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4955 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4956 (((char *) m_platform_list) + nPlatformListSize);
4957 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4958 (((char *) m_platform_entry) + nPlatformEntrySize);
4959 pPlatformList = m_platform_list;
4960 pPlatformEntry = m_platform_entry;
4961 pPMEMInfo = m_pmem_info;
4962
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004963 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07004964
4965 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004966 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
4967 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07004968 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4969 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4970 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4971 // Set the values when we determine the right HxW param
4972 bufHdr->nAllocLen = bytes;
4973 bufHdr->nFilledLen = 0;
4974 bufHdr->pAppPrivate = appData;
4975 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4976 // Platform specific PMEM Information
4977 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004978 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004979 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4980 pPlatformEntry->entry = pPMEMInfo;
4981 // Initialize the Platform List
4982 pPlatformList->nEntries = 1;
4983 pPlatformList->entryList = pPlatformEntry;
4984 // Keep pBuffer NULL till vdec is opened
4985 bufHdr->pBuffer = NULL;
4986 bufHdr->nOffset = 0;
4987
4988 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4989 pPMEMInfo->pmem_fd = 0;
4990 bufHdr->pPlatformPrivate = pPlatformList;
4991
4992 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4993 m_pmem_info[i].pmem_fd = pmem_fd;
4994#ifdef USE_ION
4995 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4996 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4997 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4998#endif
4999
5000 /*Create a mapping between buffers*/
5001 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5002 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5003 &drv_ctx.ptr_outputbuffer[i];
5004 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5005 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5006 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305007 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5008 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5009 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005010
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005011 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005012 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5013 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5014 // Move the buffer and buffer header pointers
5015 bufHdr++;
5016 pPMEMInfo++;
5017 pPlatformEntry++;
5018 pPlatformList++;
5019 }
5020 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005021 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005022 m_out_mem_ptr, pPtr);
5023 if (m_out_mem_ptr) {
5024 free(m_out_mem_ptr);
5025 m_out_mem_ptr = NULL;
5026 }
5027 if (pPtr) {
5028 free(pPtr);
5029 pPtr = NULL;
5030 }
5031 if (drv_ctx.ptr_outputbuffer) {
5032 free(drv_ctx.ptr_outputbuffer);
5033 drv_ctx.ptr_outputbuffer = NULL;
5034 }
5035 if (drv_ctx.ptr_respbuffer) {
5036 free(drv_ctx.ptr_respbuffer);
5037 drv_ctx.ptr_respbuffer = NULL;
5038 }
5039#ifdef USE_ION
5040 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005041 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005042 free(drv_ctx.op_buf_ion_info);
5043 drv_ctx.op_buf_ion_info = NULL;
5044 }
5045#endif
5046 eRet = OMX_ErrorInsufficientResources;
5047 }
5048 if (eRet == OMX_ErrorNone)
5049 eRet = allocate_extradata();
5050 }
5051
5052 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5053 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005054 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005055 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005056 }
5057 }
Arun Menon906de572013-06-18 17:01:40 -07005058
5059 if (eRet == OMX_ErrorNone) {
5060 if (i < drv_ctx.op_buf.actualcount) {
5061 struct v4l2_buffer buf;
5062 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5063 int rc;
5064 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5065
5066 drv_ctx.ptr_outputbuffer[i].buffer_len =
5067 drv_ctx.op_buf.buffer_size;
5068
5069 *bufferHdr = (m_out_mem_ptr + i );
5070 if (secure_mode) {
5071 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5072 }
5073 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5074
5075 buf.index = i;
5076 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5077 buf.memory = V4L2_MEMORY_USERPTR;
5078 plane[0].length = drv_ctx.op_buf.buffer_size;
5079 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5080 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005081#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005082 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005083#endif
Arun Menon906de572013-06-18 17:01:40 -07005084 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5085 plane[0].data_offset = 0;
5086 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5087 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5088 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5089 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 -07005090#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005091 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005092#endif
Arun Menon906de572013-06-18 17:01:40 -07005093 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5094 plane[extra_idx].data_offset = 0;
5095 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005096 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005097 return OMX_ErrorBadParameter;
5098 }
5099 buf.m.planes = plane;
5100 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005101 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 -07005102 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5103 if (rc) {
5104 /*TODO: How to handle this case */
5105 return OMX_ErrorInsufficientResources;
5106 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005107
Arun Menon906de572013-06-18 17:01:40 -07005108 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5109 enum v4l2_buf_type buf_type;
5110 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5111 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5112 if (rc) {
5113 return OMX_ErrorInsufficientResources;
5114 } else {
5115 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005116 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005117 }
5118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005119
Arun Menon906de572013-06-18 17:01:40 -07005120 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5121 (*bufferHdr)->pAppPrivate = appData;
5122 BITMASK_SET(&m_out_bm_count,i);
5123 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005124 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005125 eRet = OMX_ErrorInsufficientResources;
5126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005128
Arun Menon906de572013-06-18 17:01:40 -07005129 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005130}
5131
5132
5133// AllocateBuffer -- API Call
5134/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005135 FUNCTION
5136 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005137
Arun Menon906de572013-06-18 17:01:40 -07005138 DESCRIPTION
5139 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Arun Menon906de572013-06-18 17:01:40 -07005141 PARAMETERS
5142 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143
Arun Menon906de572013-06-18 17:01:40 -07005144 RETURN VALUE
5145 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005146
Arun Menon906de572013-06-18 17:01:40 -07005147 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005148OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005149 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5150 OMX_IN OMX_U32 port,
5151 OMX_IN OMX_PTR appData,
5152 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005153{
5154 unsigned i = 0;
5155 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5156
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005157 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005158 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005159 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005160 return OMX_ErrorInvalidState;
5161 }
5162
Arun Menon906de572013-06-18 17:01:40 -07005163 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5164 if (arbitrary_bytes) {
5165 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5166 } else {
5167 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5168 }
5169 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005170 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5171 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005172 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005173 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005174 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005175 }
5176 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005177 if (eRet == OMX_ErrorNone) {
5178 if (allocate_done()) {
5179 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005180 // Send the callback now
5181 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5182 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005183 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005184 }
5185 }
Arun Menon906de572013-06-18 17:01:40 -07005186 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5187 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5188 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5189 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005190 OMX_CORE_INPUT_PORT_INDEX,
5191 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005192 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005193 }
Arun Menon906de572013-06-18 17:01:40 -07005194 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5195 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5196 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005198 OMX_CORE_OUTPUT_PORT_INDEX,
5199 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005200 }
5201 }
5202 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005203 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204 return eRet;
5205}
5206
5207// Free Buffer - API call
5208/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005209 FUNCTION
5210 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211
Arun Menon906de572013-06-18 17:01:40 -07005212 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005213
Arun Menon906de572013-06-18 17:01:40 -07005214 PARAMETERS
5215 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005216
Arun Menon906de572013-06-18 17:01:40 -07005217 RETURN VALUE
5218 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005219
Arun Menon906de572013-06-18 17:01:40 -07005220 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005221OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005222 OMX_IN OMX_U32 port,
5223 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224{
5225 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5226 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005227 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 if (m_state == OMX_StateIdle &&
5230 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005231 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005232 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5233 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005234 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005235 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5236 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5237 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5238 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005239 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005240 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005241 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005242 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005243 OMX_ErrorPortUnpopulated,
5244 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245
5246 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005247 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005248 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005250 OMX_ErrorPortUnpopulated,
5251 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005252 }
5253
Arun Menon906de572013-06-18 17:01:40 -07005254 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5255 /*Check if arbitrary bytes*/
5256 if (!arbitrary_bytes && !input_use_buffer)
5257 nPortIndex = buffer - m_inp_mem_ptr;
5258 else
5259 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005260
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005261 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005262 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5263 // Clear the bit associated with it.
5264 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5265 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5266 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005268 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005269 if (m_phdr_pmem_ptr)
5270 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5271 } else {
5272 if (arbitrary_bytes) {
5273 if (m_phdr_pmem_ptr)
5274 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5275 else
5276 free_input_buffer(nPortIndex,NULL);
5277 } else
5278 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005279 }
Arun Menon906de572013-06-18 17:01:40 -07005280 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305281 if(release_input_done())
5282 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005283 /*Free the Buffer Header*/
5284 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005285 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005286 free_input_buffer_header();
5287 }
5288 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005289 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005290 eRet = OMX_ErrorBadPortIndex;
5291 }
5292
Arun Menon906de572013-06-18 17:01:40 -07005293 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5294 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005295 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005296 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5297 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005298 OMX_CORE_INPUT_PORT_INDEX,
5299 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005300 }
Arun Menon906de572013-06-18 17:01:40 -07005301 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005303 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005304 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005305 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005306 // Clear the bit associated with it.
5307 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5308 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005309 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005310
Surajit Podder12aefac2013-08-06 18:43:32 +05305311 if(release_output_done()) {
5312 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5313 }
Arun Menon906de572013-06-18 17:01:40 -07005314 if (release_output_done()) {
5315 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005316 }
Arun Menon906de572013-06-18 17:01:40 -07005317 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005318 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005319 eRet = OMX_ErrorBadPortIndex;
5320 }
Arun Menon906de572013-06-18 17:01:40 -07005321 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5322 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005323 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005325 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005326 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005328 if (m_enable_android_native_buffers) {
5329 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5330 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5331 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005332#endif
5333
Arun Menon906de572013-06-18 17:01:40 -07005334 post_event(OMX_CommandPortDisable,
5335 OMX_CORE_OUTPUT_PORT_INDEX,
5336 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005337 }
Arun Menon906de572013-06-18 17:01:40 -07005338 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005339 eRet = OMX_ErrorBadPortIndex;
5340 }
Arun Menon906de572013-06-18 17:01:40 -07005341 if ((eRet == OMX_ErrorNone) &&
5342 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5343 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005344 // Send the callback now
5345 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5346 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005347 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005348 }
5349 }
5350 return eRet;
5351}
5352
5353
5354/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005355 FUNCTION
5356 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005357
Arun Menon906de572013-06-18 17:01:40 -07005358 DESCRIPTION
5359 This routine is used to push the encoded video frames to
5360 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005361
Arun Menon906de572013-06-18 17:01:40 -07005362 PARAMETERS
5363 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005364
Arun Menon906de572013-06-18 17:01:40 -07005365 RETURN VALUE
5366 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005367
Arun Menon906de572013-06-18 17:01:40 -07005368 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005370 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005371{
Arun Menon906de572013-06-18 17:01:40 -07005372 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5373 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005374
Arun Menon906de572013-06-18 17:01:40 -07005375 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5376 codec_config_flag = true;
5377 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5378 } else {
5379 codec_config_flag = false;
5380 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005381
Arun Menon906de572013-06-18 17:01:40 -07005382 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005383 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005384 return OMX_ErrorInvalidState;
5385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005386
Arun Menon906de572013-06-18 17:01:40 -07005387 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005388 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005389 return OMX_ErrorBadParameter;
5390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391
Arun Menon906de572013-06-18 17:01:40 -07005392 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005393 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005394 return OMX_ErrorIncorrectStateOperation;
5395 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005396
Arun Menon906de572013-06-18 17:01:40 -07005397 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005398 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005399 return OMX_ErrorBadPortIndex;
5400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401
5402#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005403 if (iDivXDrmDecrypt) {
5404 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5405 if (drmErr != OMX_ErrorNone) {
5406 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005407 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005408 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005410#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005411 if (perf_flag) {
5412 if (!latency) {
5413 dec_time.stop();
5414 latency = dec_time.processing_time_us();
5415 dec_time.start();
5416 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005418
Arun Menon906de572013-06-18 17:01:40 -07005419 if (arbitrary_bytes) {
5420 nBufferIndex = buffer - m_inp_heap_ptr;
5421 } else {
5422 if (input_use_buffer == true) {
5423 nBufferIndex = buffer - m_inp_heap_ptr;
5424 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5425 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5426 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5427 buffer = &m_inp_mem_ptr[nBufferIndex];
5428 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5429 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5430 } else {
5431 nBufferIndex = buffer - m_inp_mem_ptr;
5432 }
5433 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005434
Arun Menon906de572013-06-18 17:01:40 -07005435 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005436 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005437 return OMX_ErrorBadParameter;
5438 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439
Arun Menon906de572013-06-18 17:01:40 -07005440 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5441 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5442 if (arbitrary_bytes) {
5443 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005444 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005445 } else {
5446 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5447 set_frame_rate(buffer->nTimeStamp);
5448 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5449 }
5450 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005451}
5452
5453/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005454 FUNCTION
5455 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005456
Arun Menon906de572013-06-18 17:01:40 -07005457 DESCRIPTION
5458 This routine is used to push the encoded video frames to
5459 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460
Arun Menon906de572013-06-18 17:01:40 -07005461 PARAMETERS
5462 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463
Arun Menon906de572013-06-18 17:01:40 -07005464 RETURN VALUE
5465 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005466
Arun Menon906de572013-06-18 17:01:40 -07005467 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005469 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470{
Arun Menon906de572013-06-18 17:01:40 -07005471 int push_cnt = 0,i=0;
5472 unsigned nPortIndex = 0;
5473 OMX_ERRORTYPE ret = OMX_ErrorNone;
5474 struct vdec_input_frameinfo frameinfo;
5475 struct vdec_bufferpayload *temp_buffer;
5476 struct vdec_seqheader seq_header;
5477 bool port_setting_changed = true;
5478 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005479
Arun Menon906de572013-06-18 17:01:40 -07005480 /*Should we generate a Aync error event*/
5481 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005482 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005483 return OMX_ErrorBadParameter;
5484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487
Arun Menon906de572013-06-18 17:01:40 -07005488 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005489 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005490 nPortIndex);
5491 return OMX_ErrorBadParameter;
5492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005493
Arun Menon906de572013-06-18 17:01:40 -07005494 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495
Arun Menon906de572013-06-18 17:01:40 -07005496 /* return zero length and not an EOS buffer */
5497 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5498 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005499 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005500 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5501 OMX_COMPONENT_GENERATE_EBD);
5502 return OMX_ErrorNone;
5503 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005504
5505
Arun Menon906de572013-06-18 17:01:40 -07005506 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5507 mp4StreamType psBits;
5508 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5509 psBits.numBytes = buffer->nFilledLen;
5510 mp4_headerparser.parseHeader(&psBits);
5511 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5512 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5513 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005514 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005515 buffer->nFilledLen,frame_count);
5516 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005517 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005518 not_coded_vop = false;
5519 buffer->nFilledLen = 0;
5520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005521 }
5522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523
Arun Menon906de572013-06-18 17:01:40 -07005524 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525
Arun Menon906de572013-06-18 17:01:40 -07005526 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527
Arun Menon906de572013-06-18 17:01:40 -07005528 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005529 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005530 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5531 OMX_COMPONENT_GENERATE_EBD);
5532 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533 }
5534
Arun Menon906de572013-06-18 17:01:40 -07005535 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536
Surajit Podderd2644d52013-08-28 17:59:06 +05305537 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005538 return OMX_ErrorBadParameter;
5539 }
5540 /* If its first frame, H264 codec and reject is true, then parse the nal
5541 and get the profile. Based on this, reject the clip playback */
5542 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5543 m_reject_avc_1080p_mp) {
5544 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005545 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005546 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5547 NALU_TYPE_SPS);
5548 m_profile = h264_parser->get_profile();
5549 ret = is_video_session_supported();
5550 if (ret) {
5551 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5552 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5553 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5554 m_state = OMX_StateInvalid;
5555 return OMX_ErrorNone;
5556 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005557 }
5558
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005559 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005560 /*for use buffer we need to memcpy the data*/
5561 temp_buffer->buffer_len = buffer->nFilledLen;
5562
5563 if (input_use_buffer) {
5564 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5565 if (arbitrary_bytes) {
5566 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5567 } else {
5568 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5569 buffer->nFilledLen);
5570 }
5571 } else {
5572 return OMX_ErrorBadParameter;
5573 }
5574
5575 }
5576
5577 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5578 frameinfo.client_data = (void *) buffer;
5579 frameinfo.datalen = temp_buffer->buffer_len;
5580 frameinfo.flags = 0;
5581 frameinfo.offset = buffer->nOffset;
5582 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5583 frameinfo.pmem_offset = temp_buffer->offset;
5584 frameinfo.timestamp = buffer->nTimeStamp;
5585 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5586 DEBUG_PRINT_LOW("ETB: dmx enabled");
5587 if (m_demux_entries == 0) {
5588 extract_demux_addr_offsets(buffer);
5589 }
5590
5591 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5592 handle_demux_data(buffer);
5593 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5594 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5595 } else {
5596 frameinfo.desc_addr = NULL;
5597 frameinfo.desc_size = 0;
5598 }
5599 if (!arbitrary_bytes) {
5600 frameinfo.flags |= buffer->nFlags;
5601 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602
5603#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005604 if (m_debug_timestamp) {
5605 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005606 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005607 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5608 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005609 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005610 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005613#endif
5614
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005615log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005616
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005617if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005618 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5619 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005621
Arun Menon906de572013-06-18 17:01:40 -07005622 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005623 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005624 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5625 h264_scratch.nFilledLen = 0;
5626 nal_count = 0;
5627 look_ahead_nal = false;
5628 frame_count = 0;
5629 if (m_frame_parser.mutils)
5630 m_frame_parser.mutils->initialize_frame_checking_environment();
5631 m_frame_parser.flush();
5632 h264_last_au_ts = LLONG_MAX;
5633 h264_last_au_flags = 0;
5634 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5635 m_demux_entries = 0;
5636 }
5637 struct v4l2_buffer buf;
5638 struct v4l2_plane plane;
5639 memset( (void *)&buf, 0, sizeof(buf));
5640 memset( (void *)&plane, 0, sizeof(plane));
5641 int rc;
5642 unsigned long print_count;
5643 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005644 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005645 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005646 }
5647 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5648 buf.index = nPortIndex;
5649 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5650 buf.memory = V4L2_MEMORY_USERPTR;
5651 plane.bytesused = temp_buffer->buffer_len;
5652 plane.length = drv_ctx.ip_buf.buffer_size;
5653 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5654 (unsigned long)temp_buffer->offset;
5655 plane.reserved[0] = temp_buffer->pmem_fd;
5656 plane.reserved[1] = temp_buffer->offset;
5657 plane.data_offset = 0;
5658 buf.m.planes = &plane;
5659 buf.length = 1;
5660 if (frameinfo.timestamp >= LLONG_MAX) {
5661 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5662 }
5663 //assumption is that timestamp is in milliseconds
5664 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5665 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5666 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5667 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005668
Arun Menon906de572013-06-18 17:01:40 -07005669 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5670 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005671 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005672 return OMX_ErrorHardware;
5673 }
5674 if (!streaming[OUTPUT_PORT]) {
5675 enum v4l2_buf_type buf_type;
5676 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005677
Arun Menon906de572013-06-18 17:01:40 -07005678 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005679 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005680 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5681 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005682 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005683 streaming[OUTPUT_PORT] = true;
5684 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005685 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005686 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5687 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5688 OMX_COMPONENT_GENERATE_EBD);
5689 return OMX_ErrorBadParameter;
5690 }
5691 }
5692 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5693 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5694 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005695
Arun Menon906de572013-06-18 17:01:40 -07005696 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697}
5698
5699/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005700 FUNCTION
5701 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702
Arun Menon906de572013-06-18 17:01:40 -07005703 DESCRIPTION
5704 IL client uses this method to release the frame buffer
5705 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005706
Arun Menon906de572013-06-18 17:01:40 -07005707 PARAMETERS
5708 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709
Arun Menon906de572013-06-18 17:01:40 -07005710 RETURN VALUE
5711 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005712
Arun Menon906de572013-06-18 17:01:40 -07005713 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005715 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005716{
Arun Menonbdb80b02013-08-12 17:45:54 -07005717 if (dynamic_buf_mode) {
5718 private_handle_t *handle = NULL;
5719 struct VideoDecoderOutputMetaData *meta;
5720 OMX_U8 *buff = NULL;
5721 unsigned int nPortIndex = 0;
5722
5723 if (!buffer || !buffer->pBuffer) {
5724 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5725 return OMX_ErrorBadParameter;
5726 }
5727
5728 //get the buffer type and fd info
5729 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5730 handle = (private_handle_t *)meta->pHandle;
5731 DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
5732
5733 //map the buffer handle based on the size set on output port definition.
5734 if (!secure_mode) {
5735 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5736 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5737 } else {
5738 buff = (OMX_U8*) buffer;
5739 }
5740
5741 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5742 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5743 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5744 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5745 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5746 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5747 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5748 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5749 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005750
5751 //Store private handle from GraphicBuffer
5752 native_buffer[nPortIndex].privatehandle = handle;
5753 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005754 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005755
Arun Menon906de572013-06-18 17:01:40 -07005756 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005757 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005758 return OMX_ErrorInvalidState;
5759 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005760
Arun Menon906de572013-06-18 17:01:40 -07005761 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005762 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005763 return OMX_ErrorIncorrectStateOperation;
5764 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005765
Arun Menon906de572013-06-18 17:01:40 -07005766 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305767 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005768 return OMX_ErrorBadParameter;
5769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770
Arun Menon906de572013-06-18 17:01:40 -07005771 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005772 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005773 return OMX_ErrorBadPortIndex;
5774 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005775
Arun Menon906de572013-06-18 17:01:40 -07005776 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5777 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5778 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779}
5780/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005781 FUNCTION
5782 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005783
Arun Menon906de572013-06-18 17:01:40 -07005784 DESCRIPTION
5785 IL client uses this method to release the frame buffer
5786 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787
Arun Menon906de572013-06-18 17:01:40 -07005788 PARAMETERS
5789 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 RETURN VALUE
5792 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005796 OMX_IN OMX_HANDLETYPE hComp,
5797 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798{
Arun Menon906de572013-06-18 17:01:40 -07005799 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5800 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5801 unsigned nPortIndex = 0;
5802 struct vdec_fillbuffer_cmd fillbuffer;
5803 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5804 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005805
Arun Menon906de572013-06-18 17:01:40 -07005806 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807
Arun Menon906de572013-06-18 17:01:40 -07005808 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5809 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005810
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005811 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005812 bufferAdd, bufferAdd->pBuffer);
5813 /*Return back the output buffer to client*/
5814 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005815 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005816 buffer->nFilledLen = 0;
5817 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5818 return OMX_ErrorNone;
5819 }
5820 pending_output_buffers++;
5821 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5822 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5823 if (ptr_respbuffer) {
5824 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5825 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005826
Arun Menon906de572013-06-18 17:01:40 -07005827 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5828 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5829 buffer->nFilledLen = 0;
5830 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5831 pending_output_buffers--;
5832 return OMX_ErrorBadParameter;
5833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834
Arun Menon906de572013-06-18 17:01:40 -07005835 int rc = 0;
5836 struct v4l2_buffer buf;
5837 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5838 memset( (void *)&buf, 0, sizeof(buf));
5839 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5840 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005841
Arun Menon906de572013-06-18 17:01:40 -07005842 buf.index = nPortIndex;
5843 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5844 buf.memory = V4L2_MEMORY_USERPTR;
5845 plane[0].bytesused = buffer->nFilledLen;
5846 plane[0].length = drv_ctx.op_buf.buffer_size;
5847 plane[0].m.userptr =
5848 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5849 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5850 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5851 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5852 plane[0].data_offset = 0;
5853 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5854 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5855 plane[extra_idx].bytesused = 0;
5856 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5857 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 -07005858#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005859 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005860#endif
Arun Menon906de572013-06-18 17:01:40 -07005861 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5862 plane[extra_idx].data_offset = 0;
5863 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005864 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005865 return OMX_ErrorBadParameter;
5866 }
5867 buf.m.planes = plane;
5868 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005869 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005870 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5871
Arun Menon906de572013-06-18 17:01:40 -07005872 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5873 if (rc) {
5874 /*TODO: How to handle this case */
5875 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5876 }
Arun Menon906de572013-06-18 17:01:40 -07005877return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005878}
5879
5880/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005881 FUNCTION
5882 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005883
Arun Menon906de572013-06-18 17:01:40 -07005884 DESCRIPTION
5885 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886
Arun Menon906de572013-06-18 17:01:40 -07005887 PARAMETERS
5888 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005889
Arun Menon906de572013-06-18 17:01:40 -07005890 RETURN VALUE
5891 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005892
Arun Menon906de572013-06-18 17:01:40 -07005893 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005894OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005895 OMX_IN OMX_CALLBACKTYPE* callbacks,
5896 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005897{
5898
Arun Menon906de572013-06-18 17:01:40 -07005899 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005900 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005901 m_cb.EventHandler,m_cb.FillBufferDone);
5902 m_app_data = appData;
5903 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005904}
5905
5906/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005907 FUNCTION
5908 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005909
Arun Menon906de572013-06-18 17:01:40 -07005910 DESCRIPTION
5911 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912
Arun Menon906de572013-06-18 17:01:40 -07005913 PARAMETERS
5914 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005915
Arun Menon906de572013-06-18 17:01:40 -07005916 RETURN VALUE
5917 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005918
Arun Menon906de572013-06-18 17:01:40 -07005919 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005920OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5921{
5922#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005923 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924 delete iDivXDrmDecrypt;
5925 iDivXDrmDecrypt=NULL;
5926 }
5927#endif //_ANDROID_
5928
Shalaj Jain286b0062013-02-21 20:35:48 -08005929 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005930 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005931 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07005932 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005933 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005934 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005935 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005936 }
5937
5938 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005939 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005940 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07005941 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5942 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005943 }
5944#ifdef _ANDROID_ICS_
5945 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5946#endif
5947 }
5948
5949 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005950 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005951 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07005952 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5953 if (m_inp_mem_ptr)
5954 free_input_buffer (i,&m_inp_mem_ptr[i]);
5955 else
5956 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005957 }
5958 }
5959 free_input_buffer_header();
5960 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005961 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005962 free(h264_scratch.pBuffer);
5963 h264_scratch.pBuffer = NULL;
5964 }
5965
Arun Menon906de572013-06-18 17:01:40 -07005966 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005967 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005968 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005969 }
5970
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005971 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005972 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005973 delete (m_frame_parser.mutils);
5974 m_frame_parser.mutils = NULL;
5975 }
5976
Arun Menon906de572013-06-18 17:01:40 -07005977 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005978 free(m_platform_list);
5979 m_platform_list = NULL;
5980 }
Arun Menon906de572013-06-18 17:01:40 -07005981 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005982 free(m_vendor_config.pData);
5983 m_vendor_config.pData = NULL;
5984 }
5985
5986 // Reset counters in mesg queues
5987 m_ftb_q.m_size=0;
5988 m_cmd_q.m_size=0;
5989 m_etb_q.m_size=0;
5990 m_ftb_q.m_read = m_ftb_q.m_write =0;
5991 m_cmd_q.m_read = m_cmd_q.m_write =0;
5992 m_etb_q.m_read = m_etb_q.m_write =0;
5993#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005994 if (m_debug_timestamp) {
5995 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005996 }
5997#endif
5998
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005999 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006000 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006001 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006002 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006003
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006004 if (m_debug.infile) {
6005 fclose(m_debug.infile);
6006 m_debug.infile = NULL;
6007 }
6008 if (m_debug.outfile) {
6009 fclose(m_debug.outfile);
6010 m_debug.outfile = NULL;
6011 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006012#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006013 if (outputExtradataFile)
6014 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006016 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006017 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006018}
6019
6020/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006021 FUNCTION
6022 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006023
Arun Menon906de572013-06-18 17:01:40 -07006024 DESCRIPTION
6025 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006026
Arun Menon906de572013-06-18 17:01:40 -07006027 PARAMETERS
6028 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006029
Arun Menon906de572013-06-18 17:01:40 -07006030 RETURN VALUE
6031 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006032
Arun Menon906de572013-06-18 17:01:40 -07006033 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006034OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006035 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6036 OMX_IN OMX_U32 port,
6037 OMX_IN OMX_PTR appData,
6038 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006039{
Arun Menon906de572013-06-18 17:01:40 -07006040 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6041 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6042 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043
6044#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006045 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6046 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006047#else
Arun Menon906de572013-06-18 17:01:40 -07006048 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006050 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006051 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006052 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006053 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006055 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006056 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006058 }
6059 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6060 eglGetProcAddress("eglQueryImageKHR");
6061 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6062 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6063 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006064#else //with OMX test app
6065 struct temp_egl {
6066 int pmem_fd;
6067 int offset;
6068 };
6069 struct temp_egl *temp_egl_id = NULL;
6070 void * pmemPtr = (void *) eglImage;
6071 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006072 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006073 fd = temp_egl_id->pmem_fd;
6074 offset = temp_egl_id->offset;
6075 }
6076#endif
6077 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006078 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006080 }
6081 pmem_info.pmem_fd = (OMX_U32) fd;
6082 pmem_info.offset = (OMX_U32) offset;
6083 pmem_entry.entry = (void *) &pmem_info;
6084 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6085 pmem_list.entryList = &pmem_entry;
6086 pmem_list.nEntries = 1;
6087 ouput_egl_buffers = true;
6088 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6089 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6090 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006091 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006092 return OMX_ErrorInsufficientResources;
6093 }
6094 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006095}
6096
6097/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006098 FUNCTION
6099 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006100
Arun Menon906de572013-06-18 17:01:40 -07006101 DESCRIPTION
6102 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 PARAMETERS
6105 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106
Arun Menon906de572013-06-18 17:01:40 -07006107 RETURN VALUE
6108 OMX Error None if everything is successful.
6109 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006110OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006111 OMX_OUT OMX_U8* role,
6112 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113{
Arun Menon906de572013-06-18 17:01:40 -07006114 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006115
Arun Menon906de572013-06-18 17:01:40 -07006116 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6117 if ((0 == index) && role) {
6118 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006119 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006120 } else {
6121 eRet = OMX_ErrorNoMore;
6122 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006123 }
Arun Menon906de572013-06-18 17:01:40 -07006124 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6125 if ((0 == index) && role) {
6126 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006127 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006128 } else {
6129 eRet = OMX_ErrorNoMore;
6130 }
6131 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6132 if ((0 == index) && role) {
6133 strlcpy((char *)role, "video_decoder.h263",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 {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006136 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006137 eRet = OMX_ErrorNoMore;
6138 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006139 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006140
Arun Menon906de572013-06-18 17:01:40 -07006141 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6142 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6143 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Shalaj Jain273b3e02012-06-22 19:08:03 -07006145 {
Arun Menon906de572013-06-18 17:01:40 -07006146 if ((0 == index) && role) {
6147 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006148 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006149 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006150 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006151 eRet = OMX_ErrorNoMore;
6152 }
6153 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6154 if ((0 == index) && role) {
6155 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006156 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006157 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006158 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006159 eRet = OMX_ErrorNoMore;
6160 }
6161 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6162 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6163 ) {
6164 if ((0 == index) && role) {
6165 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006166 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006167 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006168 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006169 eRet = OMX_ErrorNoMore;
6170 }
6171 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6172 if ((0 == index) && role) {
6173 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006174 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006175 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006176 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006177 eRet = OMX_ErrorNoMore;
6178 }
6179 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006180 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006181 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006182 }
Arun Menon906de572013-06-18 17:01:40 -07006183 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006184}
6185
6186
6187
6188
6189/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006190 FUNCTION
6191 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006192
Arun Menon906de572013-06-18 17:01:40 -07006193 DESCRIPTION
6194 Checks if entire buffer pool is allocated by IL Client or not.
6195 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006196
Arun Menon906de572013-06-18 17:01:40 -07006197 PARAMETERS
6198 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006199
Arun Menon906de572013-06-18 17:01:40 -07006200 RETURN VALUE
6201 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006202
Arun Menon906de572013-06-18 17:01:40 -07006203 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006204bool omx_vdec::allocate_done(void)
6205{
Arun Menon906de572013-06-18 17:01:40 -07006206 bool bRet = false;
6207 bool bRet_In = false;
6208 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006209
Arun Menon906de572013-06-18 17:01:40 -07006210 bRet_In = allocate_input_done();
6211 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006212
Arun Menon906de572013-06-18 17:01:40 -07006213 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214 bRet = true;
6215 }
Arun Menon906de572013-06-18 17:01:40 -07006216
6217 return bRet;
6218}
6219/* ======================================================================
6220 FUNCTION
6221 omx_vdec::AllocateInputDone
6222
6223 DESCRIPTION
6224 Checks if I/P buffer pool is allocated by IL Client or not.
6225
6226 PARAMETERS
6227 None.
6228
6229 RETURN VALUE
6230 true/false.
6231
6232 ========================================================================== */
6233bool omx_vdec::allocate_input_done(void)
6234{
6235 bool bRet = false;
6236 unsigned i=0;
6237
6238 if (m_inp_mem_ptr == NULL) {
6239 return bRet;
6240 }
6241 if (m_inp_mem_ptr ) {
6242 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6243 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6244 break;
6245 }
6246 }
6247 }
6248 if (i == drv_ctx.ip_buf.actualcount) {
6249 bRet = true;
6250 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6251 }
6252 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6253 m_inp_bPopulated = OMX_TRUE;
6254 }
6255 return bRet;
6256}
6257/* ======================================================================
6258 FUNCTION
6259 omx_vdec::AllocateOutputDone
6260
6261 DESCRIPTION
6262 Checks if entire O/P buffer pool is allocated by IL Client or not.
6263
6264 PARAMETERS
6265 None.
6266
6267 RETURN VALUE
6268 true/false.
6269
6270 ========================================================================== */
6271bool omx_vdec::allocate_output_done(void)
6272{
6273 bool bRet = false;
6274 unsigned j=0;
6275
6276 if (m_out_mem_ptr == NULL) {
6277 return bRet;
6278 }
6279
6280 if (m_out_mem_ptr) {
6281 for (; j < drv_ctx.op_buf.actualcount; j++) {
6282 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6283 break;
6284 }
6285 }
6286 }
6287
6288 if (j == drv_ctx.op_buf.actualcount) {
6289 bRet = true;
6290 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6291 if (m_out_bEnabled)
6292 m_out_bPopulated = OMX_TRUE;
6293 }
6294
6295 return bRet;
6296}
6297
6298/* ======================================================================
6299 FUNCTION
6300 omx_vdec::ReleaseDone
6301
6302 DESCRIPTION
6303 Checks if IL client has released all the buffers.
6304
6305 PARAMETERS
6306 None.
6307
6308 RETURN VALUE
6309 true/false
6310
6311 ========================================================================== */
6312bool omx_vdec::release_done(void)
6313{
6314 bool bRet = false;
6315
6316 if (release_input_done()) {
6317 if (release_output_done()) {
6318 bRet = true;
6319 }
6320 }
6321 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006322}
6323
6324
6325/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006326 FUNCTION
6327 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006328
Arun Menon906de572013-06-18 17:01:40 -07006329 DESCRIPTION
6330 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006331
Arun Menon906de572013-06-18 17:01:40 -07006332 PARAMETERS
6333 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006334
Arun Menon906de572013-06-18 17:01:40 -07006335 RETURN VALUE
6336 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006337
Arun Menon906de572013-06-18 17:01:40 -07006338 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006339bool omx_vdec::release_output_done(void)
6340{
Arun Menon906de572013-06-18 17:01:40 -07006341 bool bRet = false;
6342 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006343
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006344 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006345 if (m_out_mem_ptr) {
6346 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6347 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6348 break;
6349 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006350 }
Arun Menon906de572013-06-18 17:01:40 -07006351 if (j == drv_ctx.op_buf.actualcount) {
6352 m_out_bm_count = 0;
6353 bRet = true;
6354 }
6355 } else {
6356 m_out_bm_count = 0;
6357 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006358 }
Arun Menon906de572013-06-18 17:01:40 -07006359 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006360}
6361/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006362 FUNCTION
6363 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364
Arun Menon906de572013-06-18 17:01:40 -07006365 DESCRIPTION
6366 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006367
Arun Menon906de572013-06-18 17:01:40 -07006368 PARAMETERS
6369 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006370
Arun Menon906de572013-06-18 17:01:40 -07006371 RETURN VALUE
6372 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006373
Arun Menon906de572013-06-18 17:01:40 -07006374 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006375bool omx_vdec::release_input_done(void)
6376{
Arun Menon906de572013-06-18 17:01:40 -07006377 bool bRet = false;
6378 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006379
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006380 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006381 if (m_inp_mem_ptr) {
6382 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6383 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6384 break;
6385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006386 }
Arun Menon906de572013-06-18 17:01:40 -07006387 if (j==drv_ctx.ip_buf.actualcount) {
6388 bRet = true;
6389 }
6390 } else {
6391 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006392 }
Arun Menon906de572013-06-18 17:01:40 -07006393 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006394}
6395
6396OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006397 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006398{
Arun Menon906de572013-06-18 17:01:40 -07006399 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306400 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006401 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006402 return OMX_ErrorBadParameter;
6403 } else if (output_flush_progress) {
6404 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6405 buffer->nFilledLen = 0;
6406 buffer->nTimeStamp = 0;
6407 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6408 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6409 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006410 }
6411
Arun Menon906de572013-06-18 17:01:40 -07006412 if (m_debug_extradata) {
6413 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006414 DEBUG_PRINT_HIGH("");
6415 DEBUG_PRINT_HIGH("***************************************************");
6416 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6417 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006418 }
6419
6420 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006421 DEBUG_PRINT_HIGH("");
6422 DEBUG_PRINT_HIGH("***************************************************");
6423 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6424 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006425 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006426 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006427
6428
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006429 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006430 buffer, buffer->pBuffer);
6431 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006432
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006433 if (dynamic_buf_mode) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006434 unsigned int nPortIndex = 0;
6435 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006436
6437 if (!secure_mode) {
6438 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6439 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6440 }
6441
6442 //Clear graphic buffer handles in dynamic mode
6443 native_buffer[nPortIndex].privatehandle = NULL;
6444 native_buffer[nPortIndex].nativehandle = NULL;
Arun Menonbdb80b02013-08-12 17:45:54 -07006445 }
Arun Menon906de572013-06-18 17:01:40 -07006446 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006447 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006448 if (!output_flush_progress)
6449 post_event((unsigned)NULL, (unsigned)NULL,
6450 OMX_COMPONENT_GENERATE_EOS_DONE);
6451
6452 if (psource_frame) {
6453 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6454 psource_frame = NULL;
6455 }
6456 if (pdest_frame) {
6457 pdest_frame->nFilledLen = 0;
6458 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6459 (unsigned)NULL);
6460 pdest_frame = NULL;
6461 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006463
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006464 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006465 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006466
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006467 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6468 DEBUG_PRINT_LOW("Processing extradata");
6469 handle_extradata(buffer);
6470 }
6471
Arun Menon906de572013-06-18 17:01:40 -07006472 /* For use buffer we need to copy the data */
6473 if (!output_flush_progress) {
6474 /* This is the error check for non-recoverable errros */
6475 bool is_duplicate_ts_valid = true;
6476 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006477
Arun Menon906de572013-06-18 17:01:40 -07006478 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6479 output_capability == V4L2_PIX_FMT_MPEG2 ||
6480 output_capability == V4L2_PIX_FMT_DIVX ||
6481 output_capability == V4L2_PIX_FMT_DIVX_311)
6482 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006483
Arun Menon906de572013-06-18 17:01:40 -07006484 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6485 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6486 if (mbaff) {
6487 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306488 }
Arun Menon906de572013-06-18 17:01:40 -07006489 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306490
Arun Menon906de572013-06-18 17:01:40 -07006491 if (buffer->nFilledLen > 0) {
6492 time_stamp_dts.get_next_timestamp(buffer,
6493 is_interlaced && is_duplicate_ts_valid);
6494 if (m_debug_timestamp) {
6495 {
6496 OMX_TICKS expected_ts = 0;
6497 m_timestamp_list.pop_min_ts(expected_ts);
6498 if (is_interlaced && is_duplicate_ts_valid) {
6499 m_timestamp_list.pop_min_ts(expected_ts);
6500 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006501 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006502 buffer->nTimeStamp, expected_ts);
6503
6504 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006505 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006506 }
6507 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306508 }
Arun Menon906de572013-06-18 17:01:40 -07006509 } else {
6510 m_inp_err_count++;
6511 time_stamp_dts.remove_time_stamp(
6512 buffer->nTimeStamp,
6513 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306514 }
Arun Menon906de572013-06-18 17:01:40 -07006515
6516
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006517 }
Arun Menon906de572013-06-18 17:01:40 -07006518 if (m_cb.FillBufferDone) {
6519 if (buffer->nFilledLen > 0) {
Arun Menon906de572013-06-18 17:01:40 -07006520 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6521 set_frame_rate(buffer->nTimeStamp);
6522 else if (arbitrary_bytes)
6523 adjust_timestamp(buffer->nTimeStamp);
6524 if (perf_flag) {
6525 if (!proc_frms) {
6526 dec_time.stop();
6527 latency = dec_time.processing_time_us() - latency;
6528 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6529 dec_time.start();
6530 fps_metrics.start();
6531 }
6532 proc_frms++;
6533 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6534 OMX_U64 proc_time = 0;
6535 fps_metrics.stop();
6536 proc_time = fps_metrics.processing_time_us();
6537 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006538 proc_frms, (float)proc_time / 1e6,
6539 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006540 proc_frms = 0;
6541 }
6542 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006543
6544#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006545 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006546
Arun Menon906de572013-06-18 17:01:40 -07006547 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6548 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6549 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6550 buffer->nFilledLen + 3)&(~3));
6551 while (p_extra &&
6552 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006553 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006554 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6555 if (p_extra->eType == OMX_ExtraDataNone) {
6556 break;
6557 }
6558 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6559 }
6560 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006561#endif
Arun Menon906de572013-06-18 17:01:40 -07006562 }
6563 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6564 prev_ts = LLONG_MAX;
6565 rst_prev_ts = true;
6566 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006567
Arun Menon906de572013-06-18 17:01:40 -07006568 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6569 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6570 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006571 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006572 OMX_BUFFERHEADERTYPE *il_buffer;
6573 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6574 if (il_buffer)
6575 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6576 else {
6577 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6578 return OMX_ErrorBadParameter;
6579 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006580 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006581 } else {
6582 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006583 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006584
Praveen Chavancf924182013-12-06 23:16:23 -08006585#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6586 if (m_smoothstreaming_mode) {
6587 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6588 BufferDim_t dim;
6589 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6590 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6591 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6592 if (private_handle) {
6593 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6594 dim.sliceWidth, dim.sliceHeight);
6595 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6596 }
6597 }
6598#endif
6599
Arun Menon906de572013-06-18 17:01:40 -07006600 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006601}
6602
6603OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006604 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006605{
6606
Surajit Podderd2644d52013-08-28 17:59:06 +05306607 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006608 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006609 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006610 }
6611
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006612 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006613 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006614 pending_input_buffers--;
6615
Arun Menon906de572013-06-18 17:01:40 -07006616 if (arbitrary_bytes) {
6617 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006618 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006619 pdest_frame = buffer;
6620 buffer->nFilledLen = 0;
6621 buffer->nTimeStamp = LLONG_MAX;
6622 push_input_buffer (hComp);
6623 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006624 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006625 buffer->nFilledLen = 0;
6626 if (!m_input_free_q.insert_entry((unsigned)buffer,
6627 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006628 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006630 }
Arun Menon906de572013-06-18 17:01:40 -07006631 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006633 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006634 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6635 }
6636 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6637 }
6638 return OMX_ErrorNone;
6639}
6640
Shalaj Jain273b3e02012-06-22 19:08:03 -07006641int omx_vdec::async_message_process (void *context, void* message)
6642{
Arun Menon906de572013-06-18 17:01:40 -07006643 omx_vdec* omx = NULL;
6644 struct vdec_msginfo *vdec_msg = NULL;
6645 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6646 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6647 struct vdec_output_frameinfo *output_respbuf = NULL;
6648 int rc=1;
6649 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006650 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006651 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006652 }
Arun Menon906de572013-06-18 17:01:40 -07006653 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006654
Arun Menon906de572013-06-18 17:01:40 -07006655 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006656
Arun Menon906de572013-06-18 17:01:40 -07006657 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006658
Arun Menon906de572013-06-18 17:01:40 -07006659 case VDEC_MSG_EVT_HW_ERROR:
6660 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6661 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6662 break;
6663
6664 case VDEC_MSG_RESP_START_DONE:
6665 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6666 OMX_COMPONENT_GENERATE_START_DONE);
6667 break;
6668
6669 case VDEC_MSG_RESP_STOP_DONE:
6670 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6671 OMX_COMPONENT_GENERATE_STOP_DONE);
6672 break;
6673
6674 case VDEC_MSG_RESP_RESUME_DONE:
6675 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6676 OMX_COMPONENT_GENERATE_RESUME_DONE);
6677 break;
6678
6679 case VDEC_MSG_RESP_PAUSE_DONE:
6680 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6681 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6682 break;
6683
6684 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6685 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6686 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6687 break;
6688 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6689 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6690 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6691 break;
6692 case VDEC_MSG_RESP_INPUT_FLUSHED:
6693 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6694
6695 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6696 vdec_msg->msgdata.input_frame_clientdata; */
6697
6698 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6699 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6700 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306701 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006702 omxhdr = NULL;
6703 vdec_msg->status_code = VDEC_S_EFATAL;
6704 }
6705 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6706 DEBUG_PRINT_HIGH("Unsupported input");
6707 omx->omx_report_error ();
6708 }
6709 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6710 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6711 }
6712 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6713 OMX_COMPONENT_GENERATE_EBD);
6714 break;
6715 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6716 int64_t *timestamp;
6717 timestamp = (int64_t *) malloc(sizeof(int64_t));
6718 if (timestamp) {
6719 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6720 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6721 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006722 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006723 vdec_msg->msgdata.output_frame.time_stamp);
6724 }
6725 break;
6726 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6727 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6728
6729 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6730 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6731 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6732 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6733 vdec_msg->msgdata.output_frame.pic_type);
6734
6735 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306736 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006737 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306738 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006739 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6740 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6741 }
Arun Menon906de572013-06-18 17:01:40 -07006742 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6743 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6744 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6745 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6746 omxhdr->nFlags = 0;
6747
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006748 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006749 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6750 //rc = -1;
6751 }
6752 if (omxhdr->nFilledLen) {
6753 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6754 }
6755 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6756 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6757 } else {
6758 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6759 }
6760 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6761 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6762 }
6763 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6764 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6765 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006766 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006767 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006768 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6769 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6770 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006771 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6772 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6773 omxhdr->nOffset);
6774 }
Arun Menon906de572013-06-18 17:01:40 -07006775 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6776 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006777 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006778 omx->time_stamp_dts.remove_time_stamp(
6779 omxhdr->nTimeStamp,
6780 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6781 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006782 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6783 OMX_COMPONENT_GENERATE_FTB);
6784 break;
6785 }
6786 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6787 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6788 }
6789 vdec_msg->msgdata.output_frame.bufferaddr =
6790 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6791 int format_notably_changed = 0;
6792 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306793 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006794 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6795 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006796 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006797 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6798 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6799 format_notably_changed = 1;
6800 }
6801 }
6802 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6803 vdec_msg->msgdata.output_frame.framesize.left)
6804 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6805 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6806 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6807 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6808 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6809 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6810 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006811 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006812 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6813 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6814 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006815 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006816 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6817 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006818 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6819 omx->drv_ctx.video_resolution.frame_width) {
6820 vdec_msg->msgdata.output_frame.framesize.left = 0;
6821 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6822 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6823 }
6824 }
6825 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6826 omx->drv_ctx.video_resolution.frame_height) {
6827 vdec_msg->msgdata.output_frame.framesize.top = 0;
6828 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6829 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6830 }
6831 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006832 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 -07006833 vdec_msg->msgdata.output_frame.framesize.left,
6834 vdec_msg->msgdata.output_frame.framesize.top,
6835 vdec_msg->msgdata.output_frame.framesize.right,
6836 vdec_msg->msgdata.output_frame.framesize.bottom,
6837 omx->drv_ctx.video_resolution.frame_width,
6838 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006839 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6840 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6841 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6842 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6843 format_notably_changed = 1;
6844 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006845 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006846 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6847 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006848 if (format_notably_changed) {
6849 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306850 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006851 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6852 } else {
6853 if (!omx->client_buffers.update_buffer_req()) {
6854 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6855 }
6856 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6857 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6858 }
6859 }
6860 if (omxhdr->nFilledLen)
6861 omx->prev_n_filled_len = omxhdr->nFilledLen;
6862
6863 output_respbuf = (struct vdec_output_frameinfo *)\
6864 omxhdr->pOutputPortPrivate;
6865 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6866 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6867 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6868 output_respbuf->pic_type = PICTURE_TYPE_I;
6869 }
6870 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6871 output_respbuf->pic_type = PICTURE_TYPE_P;
6872 }
6873 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6874 output_respbuf->pic_type = PICTURE_TYPE_B;
6875 }
6876
6877 if (omx->output_use_buffer)
6878 memcpy ( omxhdr->pBuffer, (void *)
6879 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6880 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6881 vdec_msg->msgdata.output_frame.len);
6882 } else
6883 omxhdr->nFilledLen = 0;
6884 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6885 OMX_COMPONENT_GENERATE_FBD);
6886 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6887 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6888 OMX_COMPONENT_GENERATE_EOS_DONE);
6889 else
6890 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6891 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6892 break;
6893 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006894 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07006895 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6896 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6897 break;
6898 default:
6899 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900 }
Arun Menon906de572013-06-18 17:01:40 -07006901 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006902}
6903
6904OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006905 OMX_HANDLETYPE hComp,
6906 OMX_BUFFERHEADERTYPE *buffer
6907 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006908{
Arun Menon906de572013-06-18 17:01:40 -07006909 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006910 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006911
Arun Menon906de572013-06-18 17:01:40 -07006912 if (buffer == NULL) {
6913 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006914 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006915 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6916 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07006917 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6918
6919 /* return zero length and not an EOS buffer */
6920 /* return buffer if input flush in progress */
6921 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6922 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006923 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07006924 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6925 return OMX_ErrorNone;
6926 }
6927
6928 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006929 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07006930 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006931 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07006932 push_input_buffer (hComp);
6933 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006934 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006935 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6936 (unsigned)NULL)) {
6937 return OMX_ErrorBadParameter;
6938 }
6939 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006940
6941
Arun Menon906de572013-06-18 17:01:40 -07006942 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006943}
6944
6945OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6946{
Arun Menon906de572013-06-18 17:01:40 -07006947 unsigned address,p2,id;
6948 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006949
Arun Menon906de572013-06-18 17:01:40 -07006950 if (pdest_frame == NULL || psource_frame == NULL) {
6951 /*Check if we have a destination buffer*/
6952 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006953 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006954 if (m_input_free_q.m_size) {
6955 m_input_free_q.pop_entry(&address,&p2,&id);
6956 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6957 pdest_frame->nFilledLen = 0;
6958 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006959 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07006960 }
6961 }
6962
6963 /*Check if we have a destination buffer*/
6964 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006965 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006966 if (m_input_pending_q.m_size) {
6967 m_input_pending_q.pop_entry(&address,&p2,&id);
6968 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006969 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07006970 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006971 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07006972 psource_frame->nFlags,psource_frame->nFilledLen);
6973
6974 }
6975 }
6976
Shalaj Jain273b3e02012-06-22 19:08:03 -07006977 }
6978
Arun Menon906de572013-06-18 17:01:40 -07006979 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6980 switch (codec_type_parse) {
6981 case CODEC_TYPE_MPEG4:
6982 case CODEC_TYPE_H263:
6983 case CODEC_TYPE_MPEG2:
6984 ret = push_input_sc_codec(hComp);
6985 break;
6986 case CODEC_TYPE_H264:
6987 ret = push_input_h264(hComp);
6988 break;
6989 case CODEC_TYPE_VC1:
6990 ret = push_input_vc1(hComp);
6991 break;
6992 default:
6993 break;
6994 }
6995 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006996 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07006997 omx_report_error ();
6998 break;
6999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007000 }
7001
Arun Menon906de572013-06-18 17:01:40 -07007002 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007003}
7004
7005OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7006{
Arun Menon906de572013-06-18 17:01:40 -07007007 OMX_U32 partial_frame = 1;
7008 OMX_BOOL generate_ebd = OMX_TRUE;
7009 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007010
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007011 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007012 psource_frame,psource_frame->nTimeStamp);
7013 if (m_frame_parser.parse_sc_frame(psource_frame,
7014 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007015 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007016 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007017 }
Arun Menon906de572013-06-18 17:01:40 -07007018
7019 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007020 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007021 pdest_frame->nFilledLen,psource_frame,frame_count);
7022
7023
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007024 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007025 /*First Parsed buffer will have only header Hence skip*/
7026 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007027 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007028
7029 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7030 codec_type_parse == CODEC_TYPE_DIVX) {
7031 mp4StreamType psBits;
7032 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7033 psBits.numBytes = pdest_frame->nFilledLen;
7034 mp4_headerparser.parseHeader(&psBits);
7035 }
7036
7037 frame_count++;
7038 } else {
7039 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7040 if (pdest_frame->nFilledLen) {
7041 /*Push the frame to the Decoder*/
7042 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7043 return OMX_ErrorBadParameter;
7044 }
7045 frame_count++;
7046 pdest_frame = NULL;
7047
7048 if (m_input_free_q.m_size) {
7049 m_input_free_q.pop_entry(&address,&p2,&id);
7050 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7051 pdest_frame->nFilledLen = 0;
7052 }
7053 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007054 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007055 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7056 (unsigned)NULL);
7057 pdest_frame = NULL;
7058 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007059 }
Arun Menon906de572013-06-18 17:01:40 -07007060 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007061 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007062 /*Check if Destination Buffer is full*/
7063 if (pdest_frame->nAllocLen ==
7064 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007065 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007066 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007068 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007069
Arun Menon906de572013-06-18 17:01:40 -07007070 if (psource_frame->nFilledLen == 0) {
7071 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7072 if (pdest_frame) {
7073 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007074 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007075 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007076 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007077 pdest_frame->nFilledLen,frame_count++);
7078 /*Push the frame to the Decoder*/
7079 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7080 return OMX_ErrorBadParameter;
7081 }
7082 frame_count++;
7083 pdest_frame = NULL;
7084 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007085 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007086 generate_ebd = OMX_FALSE;
7087 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007088 }
Arun Menon906de572013-06-18 17:01:40 -07007089 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007090 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007091 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7092 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007093
Arun Menon906de572013-06-18 17:01:40 -07007094 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007095 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007096 m_input_pending_q.pop_entry(&address,&p2,&id);
7097 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007098 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007099 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007100 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007101 psource_frame->nFlags,psource_frame->nFilledLen);
7102 }
7103 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007104 }
Arun Menon906de572013-06-18 17:01:40 -07007105 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007106}
7107
7108OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7109{
Arun Menon906de572013-06-18 17:01:40 -07007110 OMX_U32 partial_frame = 1;
7111 unsigned address = 0, p2 = 0, id = 0;
7112 OMX_BOOL isNewFrame = OMX_FALSE;
7113 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007114
Arun Menon906de572013-06-18 17:01:40 -07007115 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007116 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007117 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007118 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007119 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007120 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007121 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007122 if (h264_scratch.nFilledLen && look_ahead_nal) {
7123 look_ahead_nal = false;
7124 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7125 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007126 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7127 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7128 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007129 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007130 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007131 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007132 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007133 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007134 }
Arun Menon906de572013-06-18 17:01:40 -07007135 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007136
7137 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7138 in EOS flag getting associated with the destination
7139 */
7140 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7141 pdest_frame->nFilledLen) {
7142 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7143 generate_ebd = OMX_FALSE;
7144 }
7145
Arun Menon906de572013-06-18 17:01:40 -07007146 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007147 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007148 if (m_frame_parser.parse_sc_frame(psource_frame,
7149 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007150 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007151 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007152 }
Arun Menon906de572013-06-18 17:01:40 -07007153 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007154 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007155 if (m_frame_parser.parse_h264_nallength(psource_frame,
7156 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007157 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007158 return OMX_ErrorBadParameter;
7159 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007161
Arun Menon906de572013-06-18 17:01:40 -07007162 if (partial_frame == 0) {
7163 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007164 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007165 nal_count++;
7166 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7167 h264_scratch.nFlags = psource_frame->nFlags;
7168 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007169 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007170 if (h264_scratch.nFilledLen) {
7171 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7172 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007173#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007174 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7175 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7176 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7177 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7178 // If timeinfo is present frame info from SEI is already processed
7179 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7180 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007181#endif
Arun Menon906de572013-06-18 17:01:40 -07007182 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7183 nal_count++;
7184 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7185 pdest_frame->nTimeStamp = h264_last_au_ts;
7186 pdest_frame->nFlags = h264_last_au_flags;
7187#ifdef PANSCAN_HDLR
7188 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7189 h264_parser->update_panscan_data(h264_last_au_ts);
7190#endif
7191 }
7192 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7193 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7194 h264_last_au_ts = h264_scratch.nTimeStamp;
7195 h264_last_au_flags = h264_scratch.nFlags;
7196#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7197 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7198 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7199 if (!VALID_TS(h264_last_au_ts))
7200 h264_last_au_ts = ts_in_sei;
7201 }
7202#endif
7203 } else
7204 h264_last_au_ts = LLONG_MAX;
7205 }
7206
7207 if (!isNewFrame) {
7208 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7209 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007210 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007211 h264_scratch.nFilledLen);
7212 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7213 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7214 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7215 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7216 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7217 h264_scratch.nFilledLen = 0;
7218 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007219 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007220 return OMX_ErrorBadParameter;
7221 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007222 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007223 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007224 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007225 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007226 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007227 pdest_frame->nFilledLen,frame_count++);
7228
7229 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007230 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007231 look_ahead_nal = false;
7232 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7233 h264_scratch.nFilledLen) {
7234 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7235 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7236 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7237 h264_scratch.nFilledLen = 0;
7238 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007240 return OMX_ErrorBadParameter;
7241 }
7242 } else {
7243 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007244 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007245 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7246 }
7247 /*Push the frame to the Decoder*/
7248 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7249 return OMX_ErrorBadParameter;
7250 }
7251 //frame_count++;
7252 pdest_frame = NULL;
7253 if (m_input_free_q.m_size) {
7254 m_input_free_q.pop_entry(&address,&p2,&id);
7255 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007256 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007257 pdest_frame->nFilledLen = 0;
7258 pdest_frame->nFlags = 0;
7259 pdest_frame->nTimeStamp = LLONG_MAX;
7260 }
7261 }
7262 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263 }
Arun Menon906de572013-06-18 17:01:40 -07007264 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007265 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007266 /*Check if Destination Buffer is full*/
7267 if (h264_scratch.nAllocLen ==
7268 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007269 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007270 return OMX_ErrorStreamCorrupt;
7271 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007272 }
Arun Menon906de572013-06-18 17:01:40 -07007273
7274 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007275 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007276
7277 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7278 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007279 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007280 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7281 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007282 if(pdest_frame->nFilledLen == 0) {
7283 /* No residual frame from before, send whatever
7284 * we have left */
7285 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7286 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7287 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7288 h264_scratch.nFilledLen = 0;
7289 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7290 } else {
7291 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7292 if(!isNewFrame) {
7293 /* Have a residual frame, but we know that the
7294 * AU in this frame is belonging to whatever
7295 * frame we had left over. So append it */
7296 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7297 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7298 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7299 h264_scratch.nFilledLen = 0;
7300 pdest_frame->nTimeStamp = h264_last_au_ts;
7301 } else {
7302 /* Completely new frame, let's just push what
7303 * we have now. The resulting EBD would trigger
7304 * another push */
7305 generate_ebd = OMX_FALSE;
7306 pdest_frame->nTimeStamp = h264_last_au_ts;
7307 h264_last_au_ts = h264_scratch.nTimeStamp;
7308 }
7309 }
Arun Menon906de572013-06-18 17:01:40 -07007310 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007311 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007312 return OMX_ErrorBadParameter;
7313 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007314
7315 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7316 if(generate_ebd == OMX_TRUE) {
7317 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7318 }
Arun Menon906de572013-06-18 17:01:40 -07007319
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007320 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007321 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007322 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007323#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7324 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7325 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7326 if (!VALID_TS(pdest_frame->nTimeStamp))
7327 pdest_frame->nTimeStamp = ts_in_sei;
7328 }
7329#endif
7330 /*Push the frame to the Decoder*/
7331 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7332 return OMX_ErrorBadParameter;
7333 }
7334 frame_count++;
7335 pdest_frame = NULL;
7336 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007337 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007338 pdest_frame,h264_scratch.nFilledLen);
7339 generate_ebd = OMX_FALSE;
7340 }
7341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007342 }
Arun Menon906de572013-06-18 17:01:40 -07007343 if (generate_ebd && !psource_frame->nFilledLen) {
7344 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7345 psource_frame = NULL;
7346 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007347 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007348 m_input_pending_q.pop_entry(&address,&p2,&id);
7349 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007350 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007351 psource_frame->nFlags,psource_frame->nFilledLen);
7352 }
7353 }
7354 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007355}
7356
7357OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7358{
7359 OMX_U8 *buf, *pdest;
7360 OMX_U32 partial_frame = 1;
7361 OMX_U32 buf_len, dest_len;
7362
Arun Menon906de572013-06-18 17:01:40 -07007363 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007364 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007365 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007366 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007367 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007368 buf = psource_frame->pBuffer;
7369 buf_len = psource_frame->nFilledLen;
7370
7371 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007372 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007373 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007374 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007375 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007376 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007377 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007378 return OMX_ErrorStreamCorrupt;
7379 }
Arun Menon906de572013-06-18 17:01:40 -07007380 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007381 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7382 pdest_frame->nOffset;
7383 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007384 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007385
Arun Menon906de572013-06-18 17:01:40 -07007386 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007387 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007388 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007389 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7391 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7392 }
7393 }
7394 }
7395
Arun Menon906de572013-06-18 17:01:40 -07007396 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007397 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007398 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007399 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007400 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007401 return OMX_ErrorBadParameter;
7402 }
Arun Menon906de572013-06-18 17:01:40 -07007403 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007404
7405 case VC1_SP_MP_RCV:
7406 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007407 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007408 return OMX_ErrorBadParameter;
7409 }
7410 return OMX_ErrorNone;
7411}
7412
David Ng38e2d232013-03-15 20:05:58 -07007413#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007414bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007415 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007416{
Arun Menon906de572013-06-18 17:01:40 -07007417 struct pmem_allocation allocation;
7418 allocation.size = buffer_size;
7419 allocation.align = clip2(alignment);
7420 if (allocation.align < 4096) {
7421 allocation.align = 4096;
7422 }
7423 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007424 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007425 allocation.align, allocation.size);
7426 return false;
7427 }
7428 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007429}
David Ng38e2d232013-03-15 20:05:58 -07007430#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007431#ifdef USE_ION
7432int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007433 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7434 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007435{
Arun Menon906de572013-06-18 17:01:40 -07007436 int fd = -EINVAL;
7437 int rc = -EINVAL;
7438 int ion_dev_flag;
7439 struct vdec_ion ion_buf_info;
7440 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007441 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007442 return -EINVAL;
7443 }
7444 ion_dev_flag = O_RDONLY;
7445 fd = open (MEM_DEVICE, ion_dev_flag);
7446 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007447 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007448 return fd;
7449 }
7450 alloc_data->flags = 0;
7451 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7452 alloc_data->flags |= ION_FLAG_CACHED;
7453 }
7454 alloc_data->len = buffer_size;
7455 alloc_data->align = clip2(alignment);
7456 if (alloc_data->align < 4096) {
7457 alloc_data->align = 4096;
7458 }
7459 if ((secure_mode) && (flag & ION_SECURE))
7460 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007461
Arun Menon906de572013-06-18 17:01:40 -07007462 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307463 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007464 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7465 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7466 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007467 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007468 alloc_data->handle = NULL;
7469 close(fd);
7470 fd = -ENOMEM;
7471 return fd;
7472 }
7473 fd_data->handle = alloc_data->handle;
7474 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7475 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007476 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007477 ion_buf_info.ion_alloc_data = *alloc_data;
7478 ion_buf_info.ion_device_fd = fd;
7479 ion_buf_info.fd_ion_data = *fd_data;
7480 free_ion_memory(&ion_buf_info);
7481 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007482 fd = -ENOMEM;
7483 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007484
Arun Menon906de572013-06-18 17:01:40 -07007485 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007486}
7487
Arun Menon906de572013-06-18 17:01:40 -07007488void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7489{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007490
Arun Menon906de572013-06-18 17:01:40 -07007491 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007492 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007493 return;
7494 }
7495 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7496 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007497 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007498 }
7499 close(buf_ion_info->ion_device_fd);
7500 buf_ion_info->ion_device_fd = -1;
7501 buf_ion_info->ion_alloc_data.handle = NULL;
7502 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007503}
7504#endif
7505void omx_vdec::free_output_buffer_header()
7506{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007507 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007508 output_use_buffer = false;
7509 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007510
Arun Menon906de572013-06-18 17:01:40 -07007511 if (m_out_mem_ptr) {
7512 free (m_out_mem_ptr);
7513 m_out_mem_ptr = NULL;
7514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515
Arun Menon906de572013-06-18 17:01:40 -07007516 if (m_platform_list) {
7517 free(m_platform_list);
7518 m_platform_list = NULL;
7519 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007520
Arun Menon906de572013-06-18 17:01:40 -07007521 if (drv_ctx.ptr_respbuffer) {
7522 free (drv_ctx.ptr_respbuffer);
7523 drv_ctx.ptr_respbuffer = NULL;
7524 }
7525 if (drv_ctx.ptr_outputbuffer) {
7526 free (drv_ctx.ptr_outputbuffer);
7527 drv_ctx.ptr_outputbuffer = NULL;
7528 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007529#ifdef USE_ION
7530 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007531 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007532 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007533 drv_ctx.op_buf_ion_info = NULL;
7534 }
7535#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007536 if (out_dynamic_list) {
7537 free(out_dynamic_list);
7538 out_dynamic_list = NULL;
7539 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007540}
7541
7542void omx_vdec::free_input_buffer_header()
7543{
7544 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007545 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007546 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007547 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007548 free (m_inp_heap_ptr);
7549 m_inp_heap_ptr = NULL;
7550 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007551
Arun Menon906de572013-06-18 17:01:40 -07007552 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007553 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007554 free (m_phdr_pmem_ptr);
7555 m_phdr_pmem_ptr = NULL;
7556 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007557 }
Arun Menon906de572013-06-18 17:01:40 -07007558 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007559 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007560 free (m_inp_mem_ptr);
7561 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007562 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007563 /* We just freed all the buffer headers, every thing in m_input_free_q
7564 * is now invalid */
7565 while (m_input_free_q.m_size) {
7566 unsigned address, p2, id;
7567 m_input_free_q.pop_entry(&address, &p2, &id);
7568 }
Arun Menon906de572013-06-18 17:01:40 -07007569 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007570 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007571 free (drv_ctx.ptr_inputbuffer);
7572 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007573 }
7574#ifdef USE_ION
7575 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007576 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007577 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007578 drv_ctx.ip_buf_ion_info = NULL;
7579 }
7580#endif
7581}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007582
7583int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007584{
Arun Menon906de572013-06-18 17:01:40 -07007585 enum v4l2_buf_type btype;
7586 int rc = 0;
7587 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007588
Arun Menon906de572013-06-18 17:01:40 -07007589 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7590 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7591 v4l2_port = OUTPUT_PORT;
7592 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7593 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7594 v4l2_port = CAPTURE_PORT;
7595 } else if (port == OMX_ALL) {
7596 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7597 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007598
Arun Menon906de572013-06-18 17:01:40 -07007599 if (!rc_input)
7600 return rc_input;
7601 else
7602 return rc_output;
7603 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007604
Arun Menon906de572013-06-18 17:01:40 -07007605 if (!streaming[v4l2_port]) {
7606 // already streamed off, warn and move on
7607 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7608 " which is already streamed off", v4l2_port);
7609 return 0;
7610 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007611
Arun Menon906de572013-06-18 17:01:40 -07007612 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007613
Arun Menon906de572013-06-18 17:01:40 -07007614 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7615 if (rc) {
7616 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007617 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007618 } else {
7619 streaming[v4l2_port] = false;
7620 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007621
Arun Menon906de572013-06-18 17:01:40 -07007622 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007623}
7624
7625OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7626{
Arun Menon906de572013-06-18 17:01:40 -07007627 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7628 struct v4l2_requestbuffers bufreq;
7629 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7630 struct v4l2_format fmt;
7631 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007632 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007633 buffer_prop->actualcount, buffer_prop->buffer_size);
7634 bufreq.memory = V4L2_MEMORY_USERPTR;
7635 bufreq.count = 1;
7636 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7637 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7638 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7639 fmt.fmt.pix_mp.pixelformat = output_capability;
7640 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7641 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7642 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7643 fmt.fmt.pix_mp.pixelformat = capture_capability;
7644 } else {
7645 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007646 }
Arun Menon906de572013-06-18 17:01:40 -07007647 if (eRet==OMX_ErrorNone) {
7648 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649 }
Arun Menon906de572013-06-18 17:01:40 -07007650 if (ret) {
7651 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7652 /*TODO: How to handle this case */
7653 eRet = OMX_ErrorInsufficientResources;
7654 return eRet;
7655 } else {
7656 buffer_prop->actualcount = bufreq.count;
7657 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007658 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007659 }
Arun Menon906de572013-06-18 17:01:40 -07007660 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7661 buffer_prop->actualcount, buffer_prop->buffer_size);
7662
7663 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7664 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7665
7666 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7667
7668 update_resolution(fmt.fmt.pix_mp.width,
7669 fmt.fmt.pix_mp.height,
7670 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7671 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7672 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7673 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007674 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007675
7676 if (ret) {
7677 /*TODO: How to handle this case */
7678 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7679 eRet = OMX_ErrorInsufficientResources;
7680 } else {
7681 int extra_idx = 0;
7682
7683 eRet = is_video_session_supported();
7684 if (eRet)
7685 return eRet;
7686
7687 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7688 buf_size = buffer_prop->buffer_size;
7689 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7690 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7691 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7692 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007694 return OMX_ErrorBadParameter;
7695 }
7696 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7697 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7698 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7699 }
7700 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7701 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7702 }
7703 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7704 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007706 client_extra_data_size);
7707 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307708 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7709 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7710 DEBUG_PRINT_HIGH("framepack extradata enabled");
7711 }
Arun Menon906de572013-06-18 17:01:40 -07007712 if (client_extra_data_size) {
7713 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7714 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7715 }
7716 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7717 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7718 drv_ctx.extradata_info.buffer_size = extra_data_size;
7719 buf_size += client_extra_data_size;
7720 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7721 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7722 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7723 if (in_reconfig) // BufReq will be set to driver when port is disabled
7724 buffer_prop->buffer_size = buf_size;
7725 else if (buf_size != buffer_prop->buffer_size) {
7726 buffer_prop->buffer_size = buf_size;
7727 eRet = set_buffer_req(buffer_prop);
7728 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007729 }
Arun Menon906de572013-06-18 17:01:40 -07007730 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7731 buffer_prop->actualcount, buffer_prop->buffer_size);
7732 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007733}
7734
7735OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7736{
Arun Menon906de572013-06-18 17:01:40 -07007737 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7738 unsigned buf_size = 0;
7739 struct v4l2_format fmt;
7740 struct v4l2_requestbuffers bufreq;
7741 int ret;
7742 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7743 buffer_prop->actualcount, buffer_prop->buffer_size);
7744 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7745 if (buf_size != buffer_prop->buffer_size) {
7746 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7747 buffer_prop->buffer_size, buf_size);
7748 eRet = OMX_ErrorBadParameter;
7749 } else {
7750 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7751 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007752
Arun Menon906de572013-06-18 17:01:40 -07007753 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7754 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7755 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007756 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007757 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7758 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7759 fmt.fmt.pix_mp.pixelformat = capture_capability;
7760 } else {
7761 eRet = OMX_ErrorBadParameter;
7762 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007763
Arun Menon906de572013-06-18 17:01:40 -07007764 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7765 if (ret) {
7766 /*TODO: How to handle this case */
7767 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7768 eRet = OMX_ErrorInsufficientResources;
7769 }
7770
7771 bufreq.memory = V4L2_MEMORY_USERPTR;
7772 bufreq.count = buffer_prop->actualcount;
7773 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7774 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7775 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7776 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7777 } else {
7778 eRet = OMX_ErrorBadParameter;
7779 }
7780
7781 if (eRet==OMX_ErrorNone) {
7782 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7783 }
7784
7785 if (ret) {
7786 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7787 /*TODO: How to handle this case */
7788 eRet = OMX_ErrorInsufficientResources;
7789 } else if (bufreq.count < buffer_prop->actualcount) {
7790 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7791 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7792 buffer_prop->actualcount, bufreq.count);
7793 eRet = OMX_ErrorInsufficientResources;
7794 } else {
7795 if (!client_buffers.update_buffer_req()) {
7796 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7797 eRet = OMX_ErrorInsufficientResources;
7798 }
7799 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007800 }
Arun Menon906de572013-06-18 17:01:40 -07007801 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007802}
7803
Shalaj Jain273b3e02012-06-22 19:08:03 -07007804OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7805{
Arun Menon906de572013-06-18 17:01:40 -07007806 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7807 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007808}
7809
7810OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7811{
Arun Menon906de572013-06-18 17:01:40 -07007812 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7813 if (!portDefn) {
7814 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007815 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007816 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007817 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7818 portDefn->nSize = sizeof(portDefn);
7819 portDefn->eDomain = OMX_PortDomainVideo;
7820 if (drv_ctx.frame_rate.fps_denominator > 0)
7821 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7822 drv_ctx.frame_rate.fps_denominator;
7823 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007824 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007825 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007826 }
Arun Menon906de572013-06-18 17:01:40 -07007827 if (0 == portDefn->nPortIndex) {
7828 portDefn->eDir = OMX_DirInput;
7829 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7830 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7831 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7832 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7833 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7834 portDefn->bEnabled = m_inp_bEnabled;
7835 portDefn->bPopulated = m_inp_bPopulated;
7836 } else if (1 == portDefn->nPortIndex) {
7837 unsigned int buf_size = 0;
7838 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007839 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007840 return OMX_ErrorHardware;
7841 }
7842 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007843 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007844 return OMX_ErrorHardware;
7845 }
7846 portDefn->nBufferSize = buf_size;
7847 portDefn->eDir = OMX_DirOutput;
7848 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7849 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7850 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7851 portDefn->bEnabled = m_out_bEnabled;
7852 portDefn->bPopulated = m_out_bPopulated;
7853 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007854 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007855 return OMX_ErrorHardware;
7856 }
7857 } else {
7858 portDefn->eDir = OMX_DirMax;
7859 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7860 (int)portDefn->nPortIndex);
7861 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007862 }
Arun Menon906de572013-06-18 17:01:40 -07007863 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7864 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7865 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7866 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7867 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007868 " SliceHeight = %lu", portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07007869 portDefn->format.video.nFrameHeight,
7870 portDefn->format.video.nStride,
7871 portDefn->format.video.nSliceHeight);
7872 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007873
7874}
7875
7876OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7877{
Arun Menon906de572013-06-18 17:01:40 -07007878 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7879 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7880 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007881
Arun Menon906de572013-06-18 17:01:40 -07007882 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007883 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07007884 int nBufHdrSize = 0;
7885 int nPlatformEntrySize = 0;
7886 int nPlatformListSize = 0;
7887 int nPMEMInfoSize = 0;
7888 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7889 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7890 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007891
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007892 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007893 drv_ctx.op_buf.actualcount);
7894 nBufHdrSize = drv_ctx.op_buf.actualcount *
7895 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896
Arun Menon906de572013-06-18 17:01:40 -07007897 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7898 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7899 nPlatformListSize = drv_ctx.op_buf.actualcount *
7900 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7901 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7902 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007903
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007904 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07007905 sizeof(OMX_BUFFERHEADERTYPE),
7906 nPMEMInfoSize,
7907 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007908 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07007909 m_out_bm_count);
7910 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7911 // Alloc mem for platform specific info
7912 char *pPtr=NULL;
7913 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7914 nPMEMInfoSize,1);
7915 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7916 calloc (sizeof(struct vdec_bufferpayload),
7917 drv_ctx.op_buf.actualcount);
7918 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7919 calloc (sizeof (struct vdec_output_frameinfo),
7920 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007921#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007922 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7923 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007924#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007925 if (dynamic_buf_mode) {
7926 out_dynamic_list = (struct dynamic_buf_list *) \
7927 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7928 }
Arun Menon906de572013-06-18 17:01:40 -07007929 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7930 && drv_ctx.ptr_respbuffer) {
7931 bufHdr = m_out_mem_ptr;
7932 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7933 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7934 (((char *) m_platform_list) + nPlatformListSize);
7935 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7936 (((char *) m_platform_entry) + nPlatformEntrySize);
7937 pPlatformList = m_platform_list;
7938 pPlatformEntry = m_platform_entry;
7939 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007941 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007942
Arun Menon906de572013-06-18 17:01:40 -07007943 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007944 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07007945 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007946 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07007947 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7948 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7949 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7950 // Set the values when we determine the right HxW param
7951 bufHdr->nAllocLen = 0;
7952 bufHdr->nFilledLen = 0;
7953 bufHdr->pAppPrivate = NULL;
7954 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7955 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7956 pPlatformEntry->entry = pPMEMInfo;
7957 // Initialize the Platform List
7958 pPlatformList->nEntries = 1;
7959 pPlatformList->entryList = pPlatformEntry;
7960 // Keep pBuffer NULL till vdec is opened
7961 bufHdr->pBuffer = NULL;
7962 pPMEMInfo->offset = 0;
7963 pPMEMInfo->pmem_fd = 0;
7964 bufHdr->pPlatformPrivate = pPlatformList;
7965 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007966#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007967 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007968#endif
Arun Menon906de572013-06-18 17:01:40 -07007969 /*Create a mapping between buffers*/
7970 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7971 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7972 &drv_ctx.ptr_outputbuffer[i];
7973 // Move the buffer and buffer header pointers
7974 bufHdr++;
7975 pPMEMInfo++;
7976 pPlatformEntry++;
7977 pPlatformList++;
7978 }
7979 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007980 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07007981 m_out_mem_ptr, pPtr);
7982 if (m_out_mem_ptr) {
7983 free(m_out_mem_ptr);
7984 m_out_mem_ptr = NULL;
7985 }
7986 if (pPtr) {
7987 free(pPtr);
7988 pPtr = NULL;
7989 }
7990 if (drv_ctx.ptr_outputbuffer) {
7991 free(drv_ctx.ptr_outputbuffer);
7992 drv_ctx.ptr_outputbuffer = NULL;
7993 }
7994 if (drv_ctx.ptr_respbuffer) {
7995 free(drv_ctx.ptr_respbuffer);
7996 drv_ctx.ptr_respbuffer = NULL;
7997 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007999 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008000 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008001 free(drv_ctx.op_buf_ion_info);
8002 drv_ctx.op_buf_ion_info = NULL;
8003 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008004#endif
Arun Menon906de572013-06-18 17:01:40 -07008005 eRet = OMX_ErrorInsufficientResources;
8006 }
8007 } else {
8008 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009 }
Arun Menon906de572013-06-18 17:01:40 -07008010 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008011}
8012
8013void omx_vdec::complete_pending_buffer_done_cbs()
8014{
Arun Menon906de572013-06-18 17:01:40 -07008015 unsigned p1;
8016 unsigned p2;
8017 unsigned ident;
8018 omx_cmd_queue tmp_q, pending_bd_q;
8019 pthread_mutex_lock(&m_lock);
8020 // pop all pending GENERATE FDB from ftb queue
8021 while (m_ftb_q.m_size) {
8022 m_ftb_q.pop_entry(&p1,&p2,&ident);
8023 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8024 pending_bd_q.insert_entry(p1,p2,ident);
8025 } else {
8026 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008027 }
Arun Menon906de572013-06-18 17:01:40 -07008028 }
8029 //return all non GENERATE FDB to ftb queue
8030 while (tmp_q.m_size) {
8031 tmp_q.pop_entry(&p1,&p2,&ident);
8032 m_ftb_q.insert_entry(p1,p2,ident);
8033 }
8034 // pop all pending GENERATE EDB from etb queue
8035 while (m_etb_q.m_size) {
8036 m_etb_q.pop_entry(&p1,&p2,&ident);
8037 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8038 pending_bd_q.insert_entry(p1,p2,ident);
8039 } else {
8040 tmp_q.insert_entry(p1,p2,ident);
8041 }
8042 }
8043 //return all non GENERATE FDB to etb queue
8044 while (tmp_q.m_size) {
8045 tmp_q.pop_entry(&p1,&p2,&ident);
8046 m_etb_q.insert_entry(p1,p2,ident);
8047 }
8048 pthread_mutex_unlock(&m_lock);
8049 // process all pending buffer dones
8050 while (pending_bd_q.m_size) {
8051 pending_bd_q.pop_entry(&p1,&p2,&ident);
8052 switch (ident) {
8053 case OMX_COMPONENT_GENERATE_EBD:
8054 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008055 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008056 omx_report_error ();
8057 }
8058 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008059
Arun Menon906de572013-06-18 17:01:40 -07008060 case OMX_COMPONENT_GENERATE_FBD:
8061 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008062 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008063 omx_report_error ();
8064 }
8065 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008066 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008068}
8069
8070void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8071{
Arun Menon906de572013-06-18 17:01:40 -07008072 OMX_U32 new_frame_interval = 0;
8073 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8074 && llabs(act_timestamp - prev_ts) > 2000) {
8075 new_frame_interval = client_set_fps ? frm_int :
8076 llabs(act_timestamp - prev_ts);
8077 if (new_frame_interval < frm_int || frm_int == 0) {
8078 frm_int = new_frame_interval;
8079 if (frm_int) {
8080 drv_ctx.frame_rate.fps_numerator = 1e6;
8081 drv_ctx.frame_rate.fps_denominator = frm_int;
8082 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8083 frm_int, drv_ctx.frame_rate.fps_numerator /
8084 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008085
Arun Menon906de572013-06-18 17:01:40 -07008086 /* We need to report the difference between this FBD and the previous FBD
8087 * back to the driver for clock scaling purposes. */
8088 struct v4l2_outputparm oparm;
8089 /*XXX: we're providing timing info as seconds per frame rather than frames
8090 * per second.*/
8091 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8092 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008093
Arun Menon906de572013-06-18 17:01:40 -07008094 struct v4l2_streamparm sparm;
8095 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8096 sparm.parm.output = oparm;
8097 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8098 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8099 performance might be affected");
8100 }
8101
8102 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008103 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008104 }
Arun Menon906de572013-06-18 17:01:40 -07008105 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008106}
8107
8108void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8109{
Arun Menon906de572013-06-18 17:01:40 -07008110 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8111 prev_ts = act_timestamp;
8112 rst_prev_ts = false;
8113 } else if (VALID_TS(prev_ts)) {
8114 bool codec_cond = (drv_ctx.timestamp_adjust)?
8115 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8116 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8117 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8118 if (frm_int > 0 && codec_cond) {
8119 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8120 act_timestamp = prev_ts + frm_int;
8121 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8122 prev_ts = act_timestamp;
8123 } else
8124 set_frame_rate(act_timestamp);
8125 } else if (frm_int > 0) // In this case the frame rate was set along
8126 { // with the port definition, start ts with 0
8127 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8128 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008129 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008130}
8131
8132void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8133{
Arun Menon906de572013-06-18 17:01:40 -07008134 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8135 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308136 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008137 OMX_U32 frame_rate = 0;
8138 int consumed_len = 0;
8139 OMX_U32 num_MB_in_frame;
8140 OMX_U32 recovery_sei_flags = 1;
8141 int enable = 0;
8142 OMX_U32 mbaff = 0;
8143 int buf_index = p_buf_hdr - m_out_mem_ptr;
8144 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8145 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8146 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308147
Arun Menon906de572013-06-18 17:01:40 -07008148 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308149 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008150 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008151 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308152 if (!secure_mode)
8153 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008154 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308155 else
8156 p_extra = m_other_extradata;
8157
Arun Menon906de572013-06-18 17:01:40 -07008158 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308159
8160 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008161 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308162 return;
8163 }
Arun Menon906de572013-06-18 17:01:40 -07008164 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8165 if (data) {
8166 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8167 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308168 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008169 DEBUG_PRINT_LOW("Invalid extra data size");
8170 break;
8171 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308172 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008173 switch ((unsigned long)data->eType) {
8174 case EXTRADATA_INTERLACE_VIDEO:
8175 struct msm_vidc_interlace_payload *payload;
8176 payload = (struct msm_vidc_interlace_payload *)data->data;
8177 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8178 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8179 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008180 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8181 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8182 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8183 enable = 1;
8184 } else {
Arun Menon906de572013-06-18 17:01:40 -07008185 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8186 enable = 1;
8187 }
8188 if (m_enable_android_native_buffers)
8189 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8190 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308191 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008192 append_interlace_extradata(p_extra, payload->format);
8193 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8194 }
8195 break;
8196 case EXTRADATA_FRAME_RATE:
8197 struct msm_vidc_framerate_payload *frame_rate_payload;
8198 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8199 frame_rate = frame_rate_payload->frame_rate;
8200 break;
8201 case EXTRADATA_TIMESTAMP:
8202 struct msm_vidc_ts_payload *time_stamp_payload;
8203 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308204 time_stamp = time_stamp_payload->timestamp_lo;
8205 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8206 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008207 break;
8208 case EXTRADATA_NUM_CONCEALED_MB:
8209 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8210 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8211 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8212 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8213 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8214 break;
8215 case EXTRADATA_INDEX:
8216 int *etype;
8217 etype = (int *)(data->data);
8218 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8219 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8220 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8221 if (aspect_ratio_payload) {
8222 ((struct vdec_output_frameinfo *)
8223 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8224 ((struct vdec_output_frameinfo *)
8225 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8226 }
8227 }
8228 break;
8229 case EXTRADATA_RECOVERY_POINT_SEI:
8230 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8231 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8232 recovery_sei_flags = recovery_sei_payload->flags;
8233 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8234 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008235 DEBUG_PRINT_HIGH("");
8236 DEBUG_PRINT_HIGH("***************************************************");
8237 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8238 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008239 }
8240 break;
8241 case EXTRADATA_PANSCAN_WINDOW:
8242 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8243 break;
8244 case EXTRADATA_MPEG2_SEQDISP:
8245 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8246 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8247 if (seqdisp_payload) {
8248 m_disp_hor_size = seqdisp_payload->disp_width;
8249 m_disp_vert_size = seqdisp_payload->disp_height;
8250 }
8251 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308252 case EXTRADATA_S3D_FRAME_PACKING:
8253 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8254 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
8255 if (!secure_mode && (client_extradata & OMX_FRAMEPACK_EXTRADATA)) {
8256 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8257 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8258 }
8259 break;
Arun Menon906de572013-06-18 17:01:40 -07008260 default:
8261 goto unrecognized_extradata;
8262 }
8263 consumed_len += data->nSize;
8264 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8265 }
8266 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8267 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8268 append_frame_info_extradata(p_extra,
8269 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308270 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008271 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008272 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008273 }
8274 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008275unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008276 if (!secure_mode && client_extradata)
8277 append_terminator_extradata(p_extra);
8278 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008279}
8280
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008281OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008282 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008283{
Arun Menon906de572013-06-18 17:01:40 -07008284 OMX_ERRORTYPE ret = OMX_ErrorNone;
8285 struct v4l2_control control;
8286 if (m_state != OMX_StateLoaded) {
8287 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8288 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008289 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008290 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008291 client_extradata, requested_extradata, enable, is_internal);
8292
8293 if (!is_internal) {
8294 if (enable)
8295 client_extradata |= requested_extradata;
8296 else
8297 client_extradata = client_extradata & ~requested_extradata;
8298 }
8299
8300 if (enable) {
8301 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8302 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8303 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8304 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8305 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008306 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008307 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308308 }
8309 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008310 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8311 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8312 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008313 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008314 }
8315 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8316 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8317 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008318 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008319 }
8320 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8321 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8322 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008323 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008324 }
8325 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8326 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8327 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008328 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008329 }
8330 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8331 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8332 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008333 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008334 }
8335 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8336 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8337 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8338 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008339 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008340 }
8341 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308342 }
8343 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008344 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8345 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8346 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008347 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008348 }
8349 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308350 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8351 if (output_capability == V4L2_PIX_FMT_H264) {
8352 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8353 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8354 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8355 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8356 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8357 }
8358 } else {
8359 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8360 }
8361 }
Arun Menon906de572013-06-18 17:01:40 -07008362 }
8363 ret = get_buffer_req(&drv_ctx.op_buf);
8364 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008365}
8366
8367OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8368{
Arun Menon906de572013-06-18 17:01:40 -07008369 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8370 OMX_U8 *data_ptr = extra->data, data = 0;
8371 while (byte_count < extra->nDataSize) {
8372 data = *data_ptr;
8373 while (data) {
8374 num_MB += (data&0x01);
8375 data >>= 1;
8376 }
8377 data_ptr++;
8378 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008379 }
Arun Menon906de572013-06-18 17:01:40 -07008380 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8381 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8382 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008383}
8384
8385void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8386{
Arun Menon906de572013-06-18 17:01:40 -07008387 if (!m_debug_extradata)
8388 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008389
8390 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008391 "============== Extra Data =============="
8392 " Size: %lu"
8393 " Version: %lu"
8394 " PortIndex: %lu"
8395 " Type: %x"
8396 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008397 extra->nSize, extra->nVersion.nVersion,
8398 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008399
Arun Menon906de572013-06-18 17:01:40 -07008400 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8401 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8402 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008403 "------ Interlace Format ------"
8404 " Size: %lu"
8405 " Version: %lu"
8406 " PortIndex: %lu"
8407 " Is Interlace Format: %d"
8408 " Interlace Formats: %lu"
8409 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008410 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8411 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8412 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8413 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8414
8415 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008416 "-------- Frame Format --------"
8417 " Picture Type: %d"
8418 " Interlace Type: %d"
8419 " Pan Scan Total Frame Num: %lu"
8420 " Concealed Macro Blocks: %lu"
8421 " frame rate: %lu"
8422 " Time Stamp: %llu"
8423 " Aspect Ratio X: %lu"
8424 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008425 fminfo->ePicType,
8426 fminfo->interlaceType,
8427 fminfo->panScan.numWindows,
8428 fminfo->nConcealedMacroblocks,
8429 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308430 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008431 fminfo->aspectRatio.aspectRatioX,
8432 fminfo->aspectRatio.aspectRatioY);
8433
8434 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8435 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008436 "------------------------------"
8437 " Pan Scan Frame Num: %lu"
8438 " Rectangle x: %ld"
8439 " Rectangle y: %ld"
8440 " Rectangle dx: %ld"
8441 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008442 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8443 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8444 }
8445
8446 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308447 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8448 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8449 DEBUG_PRINT_HIGH(
8450 "------------------ Framepack Format ----------\n"
8451 " id: %lu \n"
8452 " cancel_flag: %lu \n"
8453 " type: %lu \n"
8454 " quincunx_sampling_flagFormat: %lu \n"
8455 " content_interpretation_type: %lu \n"
8456 " content_interpretation_type: %lu \n"
8457 " spatial_flipping_flag: %lu \n"
8458 " frame0_flipped_flag: %lu \n"
8459 " field_views_flag: %lu \n"
8460 " current_frame_is_frame0_flag: %lu \n"
8461 " frame0_self_contained_flag: %lu \n"
8462 " frame1_self_contained_flag: %lu \n"
8463 " frame0_grid_position_x: %lu \n"
8464 " frame0_grid_position_y: %lu \n"
8465 " frame1_grid_position_x: %lu \n"
8466 " frame1_grid_position_y: %lu \n"
8467 " reserved_byte: %lu \n"
8468 " repetition_period: %lu \n"
8469 " extension_flag: %lu \n"
8470 "================== End of Framepack ===========",
8471 framepack->id,
8472 framepack->cancel_flag,
8473 framepack->type,
8474 framepack->quincunx_sampling_flag,
8475 framepack->content_interpretation_type,
8476 framepack->spatial_flipping_flag,
8477 framepack->frame0_flipped_flag,
8478 framepack->field_views_flag,
8479 framepack->current_frame_is_frame0_flag,
8480 framepack->frame0_self_contained_flag,
8481 framepack->frame1_self_contained_flag,
8482 framepack->frame0_grid_position_x,
8483 framepack->frame0_grid_position_y,
8484 framepack->frame1_grid_position_x,
8485 framepack->frame1_grid_position_y,
8486 framepack->reserved_byte,
8487 framepack->repetition_period,
8488 framepack->extension_flag);
Arun Menon906de572013-06-18 17:01:40 -07008489 } else if (extra->eType == OMX_ExtraDataNone) {
8490 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8491 } else {
8492 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008493 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008494}
8495
8496void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008497 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008498{
Arun Menon906de572013-06-18 17:01:40 -07008499 OMX_STREAMINTERLACEFORMAT *interlace_format;
8500 OMX_U32 mbaff = 0;
8501 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8502 return;
8503 }
8504 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8505 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8506 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8507 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8508 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8509 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8510 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8511 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8512 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8513 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8514 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8515 interlace_format->bInterlaceFormat = OMX_FALSE;
8516 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8517 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008518 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8519 interlace_format->bInterlaceFormat = OMX_TRUE;
8520 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8521 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8522 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8523 interlace_format->bInterlaceFormat = OMX_TRUE;
8524 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8525 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008526 } else {
8527 interlace_format->bInterlaceFormat = OMX_TRUE;
8528 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8529 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8530 }
8531 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008532}
8533
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008534void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008535 struct vdec_aspectratioinfo *aspect_ratio_info,
8536 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008537{
Arun Menon906de572013-06-18 17:01:40 -07008538 m_extradata = frame_info;
8539 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8540 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308541 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008542 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008543}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008544
8545void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008546 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308547 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008548 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008549{
Arun Menon906de572013-06-18 17:01:40 -07008550 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8551 struct msm_vidc_panscan_window *panscan_window;
8552 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008553 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008554 }
Arun Menon906de572013-06-18 17:01:40 -07008555 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8556 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8557 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8558 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8559 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8560 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8561 switch (picture_type) {
8562 case PICTURE_TYPE_I:
8563 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8564 break;
8565 case PICTURE_TYPE_P:
8566 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8567 break;
8568 case PICTURE_TYPE_B:
8569 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8570 break;
8571 default:
8572 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8573 }
8574 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8575 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8576 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8577 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8578 else
8579 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8580 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8581 frame_info->nConcealedMacroblocks = num_conceal_mb;
8582 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308583 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008584 frame_info->panScan.numWindows = 0;
8585 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8586 if (m_disp_hor_size && m_disp_vert_size) {
8587 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8588 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8589 }
8590 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008591
Arun Menon906de572013-06-18 17:01:40 -07008592 if (panscan_payload) {
8593 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8594 panscan_window = &panscan_payload->wnd[0];
8595 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8596 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8597 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8598 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8599 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8600 panscan_window++;
8601 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008602 }
Arun Menon906de572013-06-18 17:01:40 -07008603 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8604 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008605}
8606
8607void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8608{
Arun Menon906de572013-06-18 17:01:40 -07008609 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8610 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8611 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8612 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8613 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8614 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8615 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8616 *portDefn = m_port_def;
8617 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008618 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008619 portDefn->format.video.nFrameWidth,
8620 portDefn->format.video.nStride,
8621 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008622}
8623
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308624void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8625 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8626{
8627 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8628 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8629 DEBUG_PRINT_ERROR("frame packing size mismatch");
8630 return;
8631 }
8632 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8633 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8634 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8635 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8636 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8637 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8638 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8639 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8640 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8641 memcpy(&framepack->id, s3d_frame_packing_payload,
8642 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8643 memcpy(&m_frame_pack_arrangement, framepack,
8644 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8645 print_debug_extradata(extra);
8646}
8647
Shalaj Jain273b3e02012-06-22 19:08:03 -07008648void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8649{
Arun Menon906de572013-06-18 17:01:40 -07008650 if (!client_extradata) {
8651 return;
8652 }
8653 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8654 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8655 extra->eType = OMX_ExtraDataNone;
8656 extra->nDataSize = 0;
8657 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008658
Arun Menon906de572013-06-18 17:01:40 -07008659 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008660}
8661
8662OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8663{
Arun Menon906de572013-06-18 17:01:40 -07008664 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8665 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008666 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008667 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008668 }
Arun Menon906de572013-06-18 17:01:40 -07008669 if (m_desc_buffer_ptr == NULL) {
8670 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8671 calloc( (sizeof(desc_buffer_hdr)),
8672 drv_ctx.ip_buf.actualcount);
8673 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008674 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008675 return OMX_ErrorInsufficientResources;
8676 }
8677 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008678
Arun Menon906de572013-06-18 17:01:40 -07008679 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8680 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008681 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008682 return OMX_ErrorInsufficientResources;
8683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008684
Arun Menon906de572013-06-18 17:01:40 -07008685 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008686}
8687
8688void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8689{
Arun Menon906de572013-06-18 17:01:40 -07008690 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8691 if (m_demux_entries < 8192) {
8692 m_demux_offsets[m_demux_entries++] = address_offset;
8693 }
8694 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008695}
8696
8697void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8698{
Arun Menon906de572013-06-18 17:01:40 -07008699 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8700 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8701 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008702
Arun Menon906de572013-06-18 17:01:40 -07008703 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008704
Arun Menon906de572013-06-18 17:01:40 -07008705 while (index < bytes_to_parse) {
8706 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8707 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8708 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8709 (buf[index+2] == 0x01)) ) {
8710 //Found start code, insert address offset
8711 insert_demux_addr_offset(index);
8712 if (buf[index+2] == 0x01) // 3 byte start code
8713 index += 3;
8714 else //4 byte start code
8715 index += 4;
8716 } else
8717 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008718 }
Arun Menon906de572013-06-18 17:01:40 -07008719 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8720 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008721}
8722
8723OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8724{
Arun Menon906de572013-06-18 17:01:40 -07008725 //fix this, handle 3 byte start code, vc1 terminator entry
8726 OMX_U8 *p_demux_data = NULL;
8727 OMX_U32 desc_data = 0;
8728 OMX_U32 start_addr = 0;
8729 OMX_U32 nal_size = 0;
8730 OMX_U32 suffix_byte = 0;
8731 OMX_U32 demux_index = 0;
8732 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008733
Arun Menon906de572013-06-18 17:01:40 -07008734 if (m_desc_buffer_ptr == NULL) {
8735 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8736 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008738
Arun Menon906de572013-06-18 17:01:40 -07008739 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8740 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8741 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8742 return OMX_ErrorBadParameter;
8743 }
8744
8745 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8746
8747 if ( ((OMX_U8*)p_demux_data == NULL) ||
8748 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8749 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8750 return OMX_ErrorBadParameter;
8751 } else {
8752 for (; demux_index < m_demux_entries; demux_index++) {
8753 desc_data = 0;
8754 start_addr = m_demux_offsets[demux_index];
8755 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8756 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8757 } else {
8758 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8759 }
8760 if (demux_index < (m_demux_entries - 1)) {
8761 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8762 } else {
8763 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8764 }
8765 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8766 (void *)start_addr,
8767 suffix_byte,
8768 nal_size,
8769 demux_index);
8770 desc_data = (start_addr >> 3) << 1;
8771 desc_data |= (start_addr & 7) << 21;
8772 desc_data |= suffix_byte << 24;
8773
8774 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8775 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8776 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8777 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8778
8779 p_demux_data += 16;
8780 }
8781 if (codec_type_parse == CODEC_TYPE_VC1) {
8782 DEBUG_PRINT_LOW("VC1 terminator entry");
8783 desc_data = 0;
8784 desc_data = 0x82 << 24;
8785 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8786 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8787 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8788 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8789 p_demux_data += 16;
8790 m_demux_entries++;
8791 }
8792 //Add zero word to indicate end of descriptors
8793 memset(p_demux_data, 0, sizeof(OMX_U32));
8794
8795 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8796 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8797 }
8798 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8799 m_demux_entries = 0;
8800 DEBUG_PRINT_LOW("Demux table complete!");
8801 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008802}
8803
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008804OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008805{
Arun Menon906de572013-06-18 17:01:40 -07008806 OMX_ERRORTYPE err = OMX_ErrorNone;
8807 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8808 if (iDivXDrmDecrypt) {
8809 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8810 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008811 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008812 delete iDivXDrmDecrypt;
8813 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008814 }
8815 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008816 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07008817 err = OMX_ErrorUndefined;
8818 }
8819 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008820}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008821
Vinay Kaliada4f4422013-01-09 10:45:03 -08008822omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8823{
Arun Menon906de572013-06-18 17:01:40 -07008824 enabled = false;
8825 omx = NULL;
8826 init_members();
8827 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008828}
8829
8830void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8831{
Arun Menon906de572013-06-18 17:01:40 -07008832 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008833}
8834
Arun Menon906de572013-06-18 17:01:40 -07008835void omx_vdec::allocate_color_convert_buf::init_members()
8836{
8837 allocated_count = 0;
8838 buffer_size_req = 0;
8839 buffer_alignment_req = 0;
8840 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8841 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8842 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8843 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008844#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008845 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008846#endif
Arun Menon906de572013-06-18 17:01:40 -07008847 for (int i = 0; i < MAX_COUNT; i++)
8848 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008849}
8850
Arun Menon906de572013-06-18 17:01:40 -07008851omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8852{
8853 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008854}
8855
8856bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8857{
Arun Menon906de572013-06-18 17:01:40 -07008858 bool status = true;
8859 unsigned int src_size = 0, destination_size = 0;
8860 OMX_COLOR_FORMATTYPE drv_color_format;
8861 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008862 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008863 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008864 }
Arun Menon906de572013-06-18 17:01:40 -07008865 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008866 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07008867 return status;
8868 }
8869 pthread_mutex_lock(&omx->c_lock);
8870 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8871 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008872 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07008873 status = false;
8874 goto fail_update_buf_req;
8875 }
8876 c2d.close();
8877 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8878 omx->drv_ctx.video_resolution.frame_width,
8879 NV12_128m,YCbCr420P);
8880 if (status) {
8881 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8882 if (status)
8883 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8884 }
8885 if (status) {
8886 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8887 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008888 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07008889 "driver size %d destination size %d",
8890 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8891 status = false;
8892 c2d.close();
8893 buffer_size_req = 0;
8894 } else {
8895 buffer_size_req = destination_size;
8896 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8897 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8898 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8899 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8900 }
8901 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008902fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008903 pthread_mutex_unlock(&omx->c_lock);
8904 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008905}
8906
8907bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008908 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008909{
Arun Menon906de572013-06-18 17:01:40 -07008910 bool status = true;
8911 OMX_COLOR_FORMATTYPE drv_color_format;
8912 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008913 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008914 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008915 }
Arun Menon906de572013-06-18 17:01:40 -07008916 pthread_mutex_lock(&omx->c_lock);
8917 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8918 drv_color_format = (OMX_COLOR_FORMATTYPE)
8919 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8920 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008921 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07008922 status = false;
8923 }
8924 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008925 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07008926 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008927 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008928 status = false;
8929 } else {
8930 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8931 if (enabled)
8932 c2d.destroy();
8933 enabled = false;
8934 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008935 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008936 status = false;
8937 } else
8938 enabled = true;
8939 }
8940 } else {
8941 if (enabled)
8942 c2d.destroy();
8943 enabled = false;
8944 }
8945 pthread_mutex_unlock(&omx->c_lock);
8946 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008947}
8948
8949OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8950{
Arun Menon906de572013-06-18 17:01:40 -07008951 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008952 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008953 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008954 }
Arun Menon906de572013-06-18 17:01:40 -07008955 if (!enabled)
8956 return omx->m_out_mem_ptr;
8957 return m_out_mem_ptr_client;
8958}
8959
8960 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8961(OMX_BUFFERHEADERTYPE *bufadd)
8962{
8963 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008964 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008965 return NULL;
8966 }
8967 if (!enabled)
8968 return bufadd;
8969
8970 unsigned index = 0;
8971 index = bufadd - omx->m_out_mem_ptr;
8972 if (index < omx->drv_ctx.op_buf.actualcount) {
8973 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8974 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8975 bool status;
8976 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8977 pthread_mutex_lock(&omx->c_lock);
8978 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8979 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8980 pmem_baseaddress[index], pmem_baseaddress[index]);
8981 pthread_mutex_unlock(&omx->c_lock);
8982 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8983 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008984 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07008985 m_out_mem_ptr_client[index].nFilledLen = 0;
8986 return &m_out_mem_ptr_client[index];
8987 }
8988 } else
8989 m_out_mem_ptr_client[index].nFilledLen = 0;
8990 return &m_out_mem_ptr_client[index];
8991 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008992 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008993 return NULL;
8994}
8995
8996 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8997(OMX_BUFFERHEADERTYPE *bufadd)
8998{
8999 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009000 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009001 return NULL;
9002 }
9003 if (!enabled)
9004 return bufadd;
9005 unsigned index = 0;
9006 index = bufadd - m_out_mem_ptr_client;
9007 if (index < omx->drv_ctx.op_buf.actualcount) {
9008 return &omx->m_out_mem_ptr[index];
9009 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009010 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009011 return NULL;
9012}
9013 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9014(unsigned int &buffer_size)
9015{
9016 bool status = true;
9017 pthread_mutex_lock(&omx->c_lock);
9018 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009019 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009020 else {
9021 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009022 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009023 status = false;
9024 goto fail_get_buffer_size;
9025 }
9026 }
9027 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9028 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9029 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9030 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009031fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009032 pthread_mutex_unlock(&omx->c_lock);
9033 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009034}
9035OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009036 OMX_BUFFERHEADERTYPE *bufhdr)
9037{
9038 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009039
Arun Menon906de572013-06-18 17:01:40 -07009040 if (!enabled)
9041 return omx->free_output_buffer(bufhdr);
9042 if (enabled && omx->is_component_secure())
9043 return OMX_ErrorNone;
9044 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009045 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009046 return OMX_ErrorBadParameter;
9047 }
9048 index = bufhdr - m_out_mem_ptr_client;
9049 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009050 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009051 return OMX_ErrorBadParameter;
9052 }
9053 if (pmem_fd[index] > 0) {
9054 munmap(pmem_baseaddress[index], buffer_size_req);
9055 close(pmem_fd[index]);
9056 }
9057 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009058#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009059 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009060#endif
Arun Menon906de572013-06-18 17:01:40 -07009061 m_heap_ptr[index].video_heap_ptr = NULL;
9062 if (allocated_count > 0)
9063 allocated_count--;
9064 else
9065 allocated_count = 0;
9066 if (!allocated_count) {
9067 pthread_mutex_lock(&omx->c_lock);
9068 c2d.close();
9069 init_members();
9070 pthread_mutex_unlock(&omx->c_lock);
9071 }
9072 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009073}
9074
9075OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009076 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009077{
Arun Menon906de572013-06-18 17:01:40 -07009078 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9079 if (!enabled) {
9080 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9081 return eRet;
9082 }
9083 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009084 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009085 omx->is_component_secure());
9086 return OMX_ErrorUnsupportedSetting;
9087 }
9088 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009089 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9090 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009091 buffer_size_req,bytes);
9092 return OMX_ErrorBadParameter;
9093 }
9094 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009095 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009096 return OMX_ErrorInsufficientResources;
9097 }
9098 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9099 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9100 port,appData,omx->drv_ctx.op_buf.buffer_size);
9101 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009102 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009103 return eRet;
9104 }
9105 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309106 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009107 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009108 (temp_bufferHdr - omx->m_out_mem_ptr));
9109 return OMX_ErrorUndefined;
9110 }
9111 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009112#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009113 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9114 buffer_size_req,buffer_alignment_req,
9115 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9116 0);
9117 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9118 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009119 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009120 return OMX_ErrorInsufficientResources;
9121 }
9122 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9123 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009124
Arun Menon906de572013-06-18 17:01:40 -07009125 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009126 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009127 close(pmem_fd[i]);
9128 omx->free_ion_memory(&op_buf_ion_info[i]);
9129 return OMX_ErrorInsufficientResources;
9130 }
9131 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9132 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9133 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009134#endif
Arun Menon906de572013-06-18 17:01:40 -07009135 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9136 m_pmem_info_client[i].offset = 0;
9137 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9138 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9139 m_platform_list_client[i].nEntries = 1;
9140 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9141 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9142 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9143 m_out_mem_ptr_client[i].nFilledLen = 0;
9144 m_out_mem_ptr_client[i].nFlags = 0;
9145 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9146 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9147 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9148 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9149 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9150 m_out_mem_ptr_client[i].pAppPrivate = appData;
9151 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009152 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009153 allocated_count++;
9154 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009155}
9156
9157bool omx_vdec::is_component_secure()
9158{
Arun Menon906de572013-06-18 17:01:40 -07009159 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009160}
9161
9162bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9163{
Arun Menon906de572013-06-18 17:01:40 -07009164 bool status = true;
9165 if (!enabled) {
9166 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9167 dest_color_format = (OMX_COLOR_FORMATTYPE)
9168 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9169 else
9170 status = false;
9171 } else {
9172 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9173 status = false;
9174 } else
9175 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9176 }
9177 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009178}
Arun Menonbdb80b02013-08-12 17:45:54 -07009179
Arun Menonbdb80b02013-08-12 17:45:54 -07009180void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9181{
9182 int i = 0;
9183 bool buf_present = false;
9184 pthread_mutex_lock(&m_lock);
9185 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9186 //check the buffer fd, offset, uv addr with list contents
9187 //If present increment reference.
9188 if ((out_dynamic_list[i].fd == fd) &&
9189 (out_dynamic_list[i].offset == offset)) {
9190 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009191 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009192 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9193 buf_present = true;
9194 break;
9195 }
9196 }
9197 if (!buf_present) {
9198 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9199 //search for a entry to insert details of the new buffer
9200 if (out_dynamic_list[i].dup_fd == 0) {
9201 out_dynamic_list[i].fd = fd;
9202 out_dynamic_list[i].offset = offset;
9203 out_dynamic_list[i].dup_fd = dup(fd);
9204 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009205 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009206 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9207 break;
9208 }
9209 }
9210 }
9211 pthread_mutex_unlock(&m_lock);
9212}
9213
9214void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9215{
9216 int i = 0;
9217 pthread_mutex_lock(&m_lock);
9218 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9219 //check the buffer fd, offset, uv addr with list contents
9220 //If present decrement reference.
9221 if ((out_dynamic_list[i].fd == fd) &&
9222 (out_dynamic_list[i].offset == offset)) {
9223 out_dynamic_list[i].ref_count--;
9224 if (out_dynamic_list[i].ref_count == 0) {
9225 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009226 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] 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 out_dynamic_list[i].dup_fd = 0;
9229 out_dynamic_list[i].fd = 0;
9230 out_dynamic_list[i].offset = 0;
9231 }
9232 break;
9233 }
9234 }
9235 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009236 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009237 }
9238 pthread_mutex_unlock(&m_lock);
9239}