blob: 50b1cf828ab3c141ccc343e2eaa09b6448374fa2 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Maheshwar Ajja507d6552014-01-03 14:54:29 +05302Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080053#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070054
55#ifndef _ANDROID_
56#include <sys/ioctl.h>
57#include <sys/mman.h>
58#endif //_ANDROID_
59
60#ifdef _ANDROID_
61#include <cutils/properties.h>
62#undef USE_EGL_IMAGE_GPU
63#endif
64
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070065#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070066
67#ifdef _ANDROID_
68#include "DivXDrmDecrypt.h"
69#endif //_ANDROID_
70
Arun Menon45346052013-11-13 12:40:08 -080071#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070072#include "QComOMXMetadata.h"
73#endif
74
Shalaj Jain273b3e02012-06-22 19:08:03 -070075#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070081
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070082#define BUFFER_LOG_LOC "/data/misc/media"
83
Shalaj Jain273b3e02012-06-22 19:08:03 -070084#ifdef OUTPUT_EXTRADATA_LOG
85FILE *outputExtradataFile;
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -080086char output_extradata_filename [] = "/data/misc/extradata";
Shalaj Jain273b3e02012-06-22 19:08:03 -070087#endif
88
89#define DEFAULT_FPS 30
Shalaj Jain273b3e02012-06-22 19:08:03 -070090#define MAX_SUPPORTED_FPS 120
Deepak Vermaa2efdb12013-12-26 12:30:05 +053091#define DEFAULT_WIDTH_ALIGNMENT 128
92#define DEFAULT_HEIGHT_ALIGNMENT 32
Shalaj Jain273b3e02012-06-22 19:08:03 -070093
94#define VC1_SP_MP_START_CODE 0xC5000000
95#define VC1_SP_MP_START_CODE_MASK 0xFF000000
96#define VC1_AP_SEQ_START_CODE 0x0F010000
97#define VC1_STRUCT_C_PROFILE_MASK 0xF0
98#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
99#define VC1_SIMPLE_PROFILE 0
100#define VC1_MAIN_PROFILE 1
101#define VC1_ADVANCE_PROFILE 3
102#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
103#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
104#define VC1_STRUCT_C_LEN 4
105#define VC1_STRUCT_C_POS 8
106#define VC1_STRUCT_A_POS 12
107#define VC1_STRUCT_B_POS 24
108#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700109#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700110
111#define MEM_DEVICE "/dev/ion"
112#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
113
114#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700115extern "C" {
116#include<utils/Log.h>
117}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700118#endif//_ANDROID_
119
Vinay Kalia53fa6832012-10-11 17:55:30 -0700120#define SZ_4K 0x1000
121#define SZ_1M 0x100000
122
Shalaj Jain273b3e02012-06-22 19:08:03 -0700123#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
124#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 -0700125#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
126
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800127#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800128#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700129
130int debug_level = PRIO_ERROR;
131
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530132static OMX_U32 maxSmoothStreamingWidth = 1920;
133static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800134
Shalaj Jain273b3e02012-06-22 19:08:03 -0700135void* async_message_thread (void *input)
136{
Arun Menon906de572013-06-18 17:01:40 -0700137 OMX_BUFFERHEADERTYPE *buffer;
138 struct v4l2_plane plane[VIDEO_MAX_PLANES];
139 struct pollfd pfd;
140 struct v4l2_buffer v4l2_buf;
141 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
142 struct v4l2_event dqevent;
143 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
144 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
145 pfd.fd = omx->drv_ctx.video_driver_fd;
146 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700147 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700148 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
149 while (1) {
150 rc = poll(&pfd, 1, POLL_TIMEOUT);
151 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700152 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700153 break;
154 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700155 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700156 break;
157 }
158 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
159 struct vdec_msginfo vdec_msg;
160 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
161 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
162 v4l2_buf.length = omx->drv_ctx.num_planes;
163 v4l2_buf.m.planes = plane;
164 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
165 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
166 vdec_msg.status_code=VDEC_S_SUCCESS;
167 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
168 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
169 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
170 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
171 (uint64_t)v4l2_buf.timestamp.tv_usec;
172 if (vdec_msg.msgdata.output_frame.len) {
173 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
174 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
175 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
176 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
177 }
178 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700179 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700180 break;
181 }
182 }
183 }
184 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
185 struct vdec_msginfo vdec_msg;
186 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
187 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
188 v4l2_buf.length = 1;
189 v4l2_buf.m.planes = plane;
190 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
191 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
192 vdec_msg.status_code=VDEC_S_SUCCESS;
193 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
194 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700195 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700196 break;
197 }
198 }
199 }
200 if (pfd.revents & POLLPRI) {
201 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
202 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
203 struct vdec_msginfo vdec_msg;
204 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
205 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700206 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700207 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700208 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700209 break;
210 }
211 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
212 struct vdec_msginfo vdec_msg;
213 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
214 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700215 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700216 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700217 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700218 break;
219 }
220 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
221 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700222 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700223 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700224 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700225 break;
226 }
227 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700228 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700229 break;
Deepak Verma24720fb2014-01-29 16:57:40 +0530230 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
231 struct vdec_msginfo vdec_msg;
232 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
233 vdec_msg.status_code=VDEC_S_SUCCESS;
234 DEBUG_PRINT_ERROR("HW Overload received");
235 if (omx->async_message_process(input,&vdec_msg) < 0) {
236 DEBUG_PRINT_HIGH("async_message_thread Exited");
237 break;
238 }
Arun Menon906de572013-06-18 17:01:40 -0700239 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
240 struct vdec_msginfo vdec_msg;
Jia Meng1e236c82014-04-03 10:54:39 +0800241 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
242 vdec_msg.status_code = VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700243 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700244 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700245 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700246 break;
247 }
Arun Menon45346052013-11-13 12:40:08 -0800248 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700249 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700250 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700251 omx->buf_ref_remove(ptr[0], ptr[1]);
252 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
253 unsigned int *ptr = (unsigned int *)dqevent.u.data;
254 struct vdec_msginfo vdec_msg;
255
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700256 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700257
258 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
259 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
260 v4l2_buf.length = omx->drv_ctx.num_planes;
261 v4l2_buf.m.planes = plane;
262 v4l2_buf.index = ptr[5];
263 v4l2_buf.flags = 0;
264
265 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
266 vdec_msg.status_code = VDEC_S_SUCCESS;
267 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
268 vdec_msg.msgdata.output_frame.len = 0;
269 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
270 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
271 (uint64_t)ptr[4];
272 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700273 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700274 break;
275 }
276 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700277 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700278 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700279 continue;
280 }
281 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700282 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700283 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700284 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700285}
286
287void* message_thread(void *input)
288{
Arun Menon906de572013-06-18 17:01:40 -0700289 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
290 unsigned char id;
291 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700292
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700293 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700294 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
295 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700296
Arun Menon906de572013-06-18 17:01:40 -0700297 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700298
Arun Menon906de572013-06-18 17:01:40 -0700299 if (0 == n) {
300 break;
301 }
302
303 if (1 == n) {
304 omx->process_event_cb(omx, id);
305 }
306 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700307 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700308 break;
309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700310 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700311 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700312 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700313}
314
315void post_message(omx_vdec *omx, unsigned char id)
316{
Arun Menon906de572013-06-18 17:01:40 -0700317 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700318 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700319 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700320 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700321}
322
323// omx_cmd_queue destructor
324omx_vdec::omx_cmd_queue::~omx_cmd_queue()
325{
Arun Menon906de572013-06-18 17:01:40 -0700326 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700327}
328
329// omx cmd queue constructor
330omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
331{
332 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
333}
334
335// omx cmd queue insert
336bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
337{
Arun Menon906de572013-06-18 17:01:40 -0700338 bool ret = true;
339 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
340 m_q[m_write].id = id;
341 m_q[m_write].param1 = p1;
342 m_q[m_write].param2 = p2;
343 m_write++;
344 m_size ++;
345 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
346 m_write = 0;
347 }
348 } else {
349 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700350 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700351 }
Arun Menon906de572013-06-18 17:01:40 -0700352 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700353}
354
355// omx cmd queue pop
356bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
357{
Arun Menon906de572013-06-18 17:01:40 -0700358 bool ret = true;
359 if (m_size > 0) {
360 *id = m_q[m_read].id;
361 *p1 = m_q[m_read].param1;
362 *p2 = m_q[m_read].param2;
363 // Move the read pointer ahead
364 ++m_read;
365 --m_size;
366 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
367 m_read = 0;
368 }
369 } else {
370 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700371 }
Arun Menon906de572013-06-18 17:01:40 -0700372 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700373}
374
375// Retrieve the first mesg type in the queue
376unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
377{
378 return m_q[m_read].id;
379}
380
381#ifdef _ANDROID_
382omx_vdec::ts_arr_list::ts_arr_list()
383{
Arun Menon906de572013-06-18 17:01:40 -0700384 //initialize timestamps array
385 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700386}
387omx_vdec::ts_arr_list::~ts_arr_list()
388{
Arun Menon906de572013-06-18 17:01:40 -0700389 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700390}
391
392bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
393{
Arun Menon906de572013-06-18 17:01:40 -0700394 bool ret = true;
395 bool duplicate_ts = false;
396 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700397
Arun Menon906de572013-06-18 17:01:40 -0700398 //insert at the first available empty location
399 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
400 if (!m_ts_arr_list[idx].valid) {
401 //found invalid or empty entry, save timestamp
402 m_ts_arr_list[idx].valid = true;
403 m_ts_arr_list[idx].timestamp = ts;
404 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
405 ts, idx);
406 break;
407 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700408 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700409
Arun Menon906de572013-06-18 17:01:40 -0700410 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
411 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
412 ret = false;
413 }
414 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415}
416
417bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
418{
Arun Menon906de572013-06-18 17:01:40 -0700419 bool ret = true;
420 int min_idx = -1;
421 OMX_TICKS min_ts = 0;
422 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700423
Arun Menon906de572013-06-18 17:01:40 -0700424 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700425
Arun Menon906de572013-06-18 17:01:40 -0700426 if (m_ts_arr_list[idx].valid) {
427 //found valid entry, save index
428 if (min_idx < 0) {
429 //first valid entry
430 min_ts = m_ts_arr_list[idx].timestamp;
431 min_idx = idx;
432 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
433 min_ts = m_ts_arr_list[idx].timestamp;
434 min_idx = idx;
435 }
436 }
437
Shalaj Jain273b3e02012-06-22 19:08:03 -0700438 }
439
Arun Menon906de572013-06-18 17:01:40 -0700440 if (min_idx < 0) {
441 //no valid entries found
442 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
443 ts = 0;
444 ret = false;
445 } else {
446 ts = m_ts_arr_list[min_idx].timestamp;
447 m_ts_arr_list[min_idx].valid = false;
448 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
449 ts, min_idx);
450 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700451
Arun Menon906de572013-06-18 17:01:40 -0700452 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700453
454}
455
456
457bool omx_vdec::ts_arr_list::reset_ts_list()
458{
Arun Menon906de572013-06-18 17:01:40 -0700459 bool ret = true;
460 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700461
Arun Menon906de572013-06-18 17:01:40 -0700462 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
463 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
464 m_ts_arr_list[idx].valid = false;
465 }
466 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700467}
468#endif
469
470// factory function executed by the core to create instances
471void *get_omx_component_factory_fn(void)
472{
Arun Menon906de572013-06-18 17:01:40 -0700473 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700474}
475
476#ifdef _ANDROID_
477#ifdef USE_ION
478VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700479 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700480{
Arun Menon906de572013-06-18 17:01:40 -0700481 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700482}
483#else
484VideoHeap::VideoHeap(int fd, size_t size, void* base)
485{
486 // dup file descriptor, map once, use pmem
487 init(dup(fd), base, size, 0 , MEM_DEVICE);
488}
489#endif
490#endif // _ANDROID_
491/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700492 FUNCTION
493 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700494
Arun Menon906de572013-06-18 17:01:40 -0700495 DESCRIPTION
496 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700497
Arun Menon906de572013-06-18 17:01:40 -0700498 PARAMETERS
499 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700500
Arun Menon906de572013-06-18 17:01:40 -0700501 RETURN VALUE
502 None.
503 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800504omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700505 m_state(OMX_StateInvalid),
506 m_app_data(NULL),
507 m_inp_mem_ptr(NULL),
508 m_out_mem_ptr(NULL),
Arun Menon906de572013-06-18 17:01:40 -0700509 input_flush_progress (false),
510 output_flush_progress (false),
511 input_use_buffer (false),
512 output_use_buffer (false),
513 ouput_egl_buffers(false),
514 m_use_output_pmem(OMX_FALSE),
515 m_out_mem_region_smi(OMX_FALSE),
516 m_out_pvt_entry_pmem(OMX_FALSE),
517 pending_input_buffers(0),
518 pending_output_buffers(0),
519 m_out_bm_count(0),
520 m_inp_bm_count(0),
521 m_inp_bPopulated(OMX_FALSE),
522 m_out_bPopulated(OMX_FALSE),
523 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700524#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700525 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700526#endif
Arun Menon906de572013-06-18 17:01:40 -0700527 m_inp_bEnabled(OMX_TRUE),
528 m_out_bEnabled(OMX_TRUE),
529 m_in_alloc_cnt(0),
530 m_platform_list(NULL),
531 m_platform_entry(NULL),
532 m_pmem_info(NULL),
533 arbitrary_bytes (true),
534 psource_frame (NULL),
535 pdest_frame (NULL),
536 m_inp_heap_ptr (NULL),
537 m_phdr_pmem_ptr(NULL),
538 m_heap_inp_bm_count (0),
539 codec_type_parse ((codec_type)0),
540 first_frame_meta (true),
541 frame_count (0),
542 nal_count (0),
543 nal_length(0),
544 look_ahead_nal (false),
545 first_frame(0),
546 first_buffer(NULL),
547 first_frame_size (0),
548 m_device_file_ptr(NULL),
549 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700550 h264_last_au_ts(LLONG_MAX),
551 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530552 m_disp_hor_size(0),
553 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700554 prev_ts(LLONG_MAX),
555 rst_prev_ts(true),
556 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700557 in_reconfig(false),
558 m_display_id(NULL),
559 h264_parser(NULL),
560 client_extradata(0),
561 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530562 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700563#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700564 m_enable_android_native_buffers(OMX_FALSE),
565 m_use_android_native_buffers(OMX_FALSE),
566 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700567#endif
Arun Menon906de572013-06-18 17:01:40 -0700568 m_desc_buffer_ptr(NULL),
569 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530570 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800571 client_set_fps(false),
572 m_last_rendered_TS(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700573{
Arun Menon906de572013-06-18 17:01:40 -0700574 /* Assumption is that , to begin with , we have all the frames with decoder */
575 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700576 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700577#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700578 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700579 property_get("vidc.debug.level", property_value, "0");
580 debug_level = atoi(property_value);
581 property_value[0] = '\0';
582
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700583 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
584
Arun Menon906de572013-06-18 17:01:40 -0700585 property_get("vidc.dec.debug.perf", property_value, "0");
586 perf_flag = atoi(property_value);
587 if (perf_flag) {
588 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
589 dec_time.start();
590 proc_frms = latency = 0;
591 }
592 prev_n_filled_len = 0;
593 property_value[0] = '\0';
594 property_get("vidc.dec.debug.ts", property_value, "0");
595 m_debug_timestamp = atoi(property_value);
596 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
597 if (m_debug_timestamp) {
598 time_stamp_dts.set_timestamp_reorder_mode(true);
599 time_stamp_dts.enable_debug_print(true);
600 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700601
Arun Menon906de572013-06-18 17:01:40 -0700602 property_value[0] = '\0';
603 property_get("vidc.dec.debug.concealedmb", property_value, "0");
604 m_debug_concealedmb = atoi(property_value);
605 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700606
Arun Menon906de572013-06-18 17:01:40 -0700607 property_value[0] = '\0';
608 property_get("vidc.dec.profile.check", property_value, "0");
609 m_reject_avc_1080p_mp = atoi(property_value);
610 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530611
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700612 property_value[0] = '\0';
613 property_get("vidc.dec.log.in", property_value, "0");
614 m_debug.in_buffer_log = atoi(property_value);
615
616 property_value[0] = '\0';
617 property_get("vidc.dec.log.out", property_value, "0");
618 m_debug.out_buffer_log = atoi(property_value);
619 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
620
621 property_value[0] = '\0';
622 property_get("vidc.log.loc", property_value, "");
623 if (*property_value)
624 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800625
626 property_value[0] = '\0';
627 property_get("vidc.dec.120fps.enabled", property_value, "0");
628
629 //if this feature is not enabled then reset this value -ve
630 if(atoi(property_value)) {
631 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
632 m_last_rendered_TS = 0;
633 }
634
Shalaj Jain273b3e02012-06-22 19:08:03 -0700635#endif
Arun Menon906de572013-06-18 17:01:40 -0700636 memset(&m_cmp,0,sizeof(m_cmp));
637 memset(&m_cb,0,sizeof(m_cb));
638 memset (&drv_ctx,0,sizeof(drv_ctx));
639 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
640 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
641 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +0530642 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
Arun Menon906de572013-06-18 17:01:40 -0700643 m_demux_entries = 0;
644 msg_thread_id = 0;
645 async_thread_id = 0;
646 msg_thread_created = false;
647 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700648#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700649 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700650#endif
Arun Menon906de572013-06-18 17:01:40 -0700651 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530652 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700653 drv_ctx.timestamp_adjust = false;
654 drv_ctx.video_driver_fd = -1;
655 m_vendor_config.pData = NULL;
656 pthread_mutex_init(&m_lock, NULL);
657 pthread_mutex_init(&c_lock, NULL);
658 sem_init(&m_cmd_lock,0,0);
659 streaming[CAPTURE_PORT] =
660 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700661#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700662 char extradata_value[PROPERTY_VALUE_MAX] = {0};
663 property_get("vidc.dec.debug.extradata", extradata_value, "0");
664 m_debug_extradata = atoi(extradata_value);
665 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700666#endif
Arun Menon906de572013-06-18 17:01:40 -0700667 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
668 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700669 dynamic_buf_mode = false;
670 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800671 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800672 m_smoothstreaming_mode = false;
673 m_smoothstreaming_width = 0;
674 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530675 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700676}
677
Vinay Kalia85793762012-06-14 19:12:34 -0700678static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700679 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
680 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
681 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700682 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
683 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700684 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
Jia Meng1e236c82014-04-03 10:54:39 +0800685 V4L2_EVENT_MSM_VIDC_SYS_ERROR,
686 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD
Vinay Kalia85793762012-06-14 19:12:34 -0700687};
688
689static OMX_ERRORTYPE subscribe_to_events(int fd)
690{
Arun Menon906de572013-06-18 17:01:40 -0700691 OMX_ERRORTYPE eRet = OMX_ErrorNone;
692 struct v4l2_event_subscription sub;
693 int array_sz = sizeof(event_type)/sizeof(int);
694 int i,rc;
695 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700696 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700697 return OMX_ErrorBadParameter;
698 }
Vinay Kalia85793762012-06-14 19:12:34 -0700699
Arun Menon906de572013-06-18 17:01:40 -0700700 for (i = 0; i < array_sz; ++i) {
701 memset(&sub, 0, sizeof(sub));
702 sub.type = event_type[i];
703 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
704 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700705 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700706 break;
707 }
708 }
709 if (i < array_sz) {
710 for (--i; i >=0 ; 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 }
717 eRet = OMX_ErrorNotImplemented;
718 }
719 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700720}
721
722
723static OMX_ERRORTYPE unsubscribe_to_events(int fd)
724{
Arun Menon906de572013-06-18 17:01:40 -0700725 OMX_ERRORTYPE eRet = OMX_ErrorNone;
726 struct v4l2_event_subscription sub;
727 int array_sz = sizeof(event_type)/sizeof(int);
728 int i,rc;
729 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700730 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700731 return OMX_ErrorBadParameter;
732 }
Vinay Kalia85793762012-06-14 19:12:34 -0700733
Arun Menon906de572013-06-18 17:01:40 -0700734 for (i = 0; i < array_sz; ++i) {
735 memset(&sub, 0, sizeof(sub));
736 sub.type = event_type[i];
737 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
738 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700739 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700740 break;
741 }
742 }
743 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700744}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700745
746/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700747 FUNCTION
748 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700749
Arun Menon906de572013-06-18 17:01:40 -0700750 DESCRIPTION
751 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700752
Arun Menon906de572013-06-18 17:01:40 -0700753 PARAMETERS
754 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700755
Arun Menon906de572013-06-18 17:01:40 -0700756 RETURN VALUE
757 None.
758 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700759omx_vdec::~omx_vdec()
760{
Arun Menon906de572013-06-18 17:01:40 -0700761 m_pmem_info = NULL;
762 struct v4l2_decoder_cmd dec;
763 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
764 if (m_pipe_in) close(m_pipe_in);
765 if (m_pipe_out) close(m_pipe_out);
766 m_pipe_in = -1;
767 m_pipe_out = -1;
768 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
769 if (msg_thread_created)
770 pthread_join(msg_thread_id,NULL);
771 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
772 dec.cmd = V4L2_DEC_CMD_STOP;
773 if (drv_ctx.video_driver_fd >=0 ) {
774 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700775 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700776 }
777 if (async_thread_created)
778 pthread_join(async_thread_id,NULL);
779 unsubscribe_to_events(drv_ctx.video_driver_fd);
780 close(drv_ctx.video_driver_fd);
781 pthread_mutex_destroy(&m_lock);
782 pthread_mutex_destroy(&c_lock);
783 sem_destroy(&m_cmd_lock);
784 if (perf_flag) {
785 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
786 dec_time.end();
787 }
788 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700789}
790
Arun Menon906de572013-06-18 17:01:40 -0700791int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
792{
793 struct v4l2_requestbuffers bufreq;
794 int rc = 0;
795 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
796 bufreq.memory = V4L2_MEMORY_USERPTR;
797 bufreq.count = 0;
798 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
799 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530800 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
801 bufreq.memory = V4L2_MEMORY_USERPTR;
802 bufreq.count = 0;
803 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
804 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700805 }
806 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700807}
808
Shalaj Jain273b3e02012-06-22 19:08:03 -0700809/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700810 FUNCTION
811 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700812
Arun Menon906de572013-06-18 17:01:40 -0700813 DESCRIPTION
814 IL Client callbacks are generated through this routine. The decoder
815 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816
Arun Menon906de572013-06-18 17:01:40 -0700817 PARAMETERS
818 ctxt -- Context information related to the self.
819 id -- Event identifier. This could be any of the following:
820 1. Command completion event
821 2. Buffer done callback event
822 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700823
Arun Menon906de572013-06-18 17:01:40 -0700824 RETURN VALUE
825 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700826
Arun Menon906de572013-06-18 17:01:40 -0700827 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700828void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
829{
Arun Menon906de572013-06-18 17:01:40 -0700830 signed p1; // Parameter - 1
831 signed p2; // Parameter - 2
832 unsigned ident;
833 unsigned qsize=0; // qsize
834 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700835
Arun Menon906de572013-06-18 17:01:40 -0700836 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700837 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700838 __func__);
839 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700840 }
841
Arun Menon906de572013-06-18 17:01:40 -0700842 // Protect the shared queue data structure
843 do {
844 /*Read the message id's from the queue*/
845 pthread_mutex_lock(&pThis->m_lock);
846 qsize = pThis->m_cmd_q.m_size;
847 if (qsize) {
848 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700849 }
Arun Menon906de572013-06-18 17:01:40 -0700850
851 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
852 qsize = pThis->m_ftb_q.m_size;
853 if (qsize) {
854 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
855 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700856 }
Arun Menon906de572013-06-18 17:01:40 -0700857
858 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
859 qsize = pThis->m_etb_q.m_size;
860 if (qsize) {
861 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
862 }
863 }
864 pthread_mutex_unlock(&pThis->m_lock);
865
866 /*process message if we have one*/
867 if (qsize > 0) {
868 id = ident;
869 switch (id) {
870 case OMX_COMPONENT_GENERATE_EVENT:
871 if (pThis->m_cb.EventHandler) {
872 switch (p1) {
873 case OMX_CommandStateSet:
874 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700875 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700876 pThis->m_state);
877 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
878 OMX_EventCmdComplete, p1, p2, NULL);
879 break;
880
881 case OMX_EventError:
882 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700883 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700884 pThis->m_state = (OMX_STATETYPE) p2;
885 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
886 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
887 } else if (p2 == OMX_ErrorHardware) {
888 pThis->omx_report_error();
889 } else {
890 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
891 OMX_EventError, p2, (OMX_U32)NULL, NULL );
892 }
893 break;
894
895 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700896 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700897 if (BITMASK_PRESENT(&pThis->m_flags,
898 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
899 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
900 break;
901 }
902 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
903 OMX_ERRORTYPE eRet = OMX_ErrorNone;
904 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
905 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700906 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700907 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
908 pThis->in_reconfig = false;
909 if (eRet != OMX_ErrorNone) {
910 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
911 pThis->omx_report_error();
912 break;
913 }
914 }
915 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
916 OMX_EventCmdComplete, p1, p2, NULL );
917 break;
918 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700919 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700920 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
921 OMX_EventCmdComplete, p1, p2, NULL );
922 break;
923
924 default:
925 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
926 OMX_EventCmdComplete, p1, p2, NULL );
927 break;
928
929 }
930 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700931 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700932 }
933 break;
934 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
935 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
936 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700937 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700938 pThis->omx_report_error ();
939 }
940 break;
Jia Meng1e236c82014-04-03 10:54:39 +0800941 case OMX_COMPONENT_GENERATE_ETB: {
942 OMX_ERRORTYPE iret;
943 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
944 if (iret == OMX_ErrorInsufficientResources) {
945 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
946 pThis->omx_report_hw_overload ();
947 } else if (iret != OMX_ErrorNone) {
948 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
949 pThis->omx_report_error ();
950 }
Arun Menon906de572013-06-18 17:01:40 -0700951 }
952 break;
953
954 case OMX_COMPONENT_GENERATE_FTB:
955 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
956 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700957 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700958 pThis->omx_report_error ();
959 }
960 break;
961
962 case OMX_COMPONENT_GENERATE_COMMAND:
963 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
964 (OMX_U32)p2,(OMX_PTR)NULL);
965 break;
966
967 case OMX_COMPONENT_GENERATE_EBD:
968
969 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700970 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700971 pThis->omx_report_error ();
972 } else {
973 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
Arun Menon906de572013-06-18 17:01:40 -0700974 pThis->time_stamp_dts.remove_time_stamp(
975 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
976 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
977 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -0700978 }
Deva Ramasubramanian02b0d882014-04-03 14:58:50 -0700979
Arun Menon906de572013-06-18 17:01:40 -0700980 if ( pThis->empty_buffer_done(&pThis->m_cmp,
981 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700982 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700983 pThis->omx_report_error ();
984 }
Arun Menon906de572013-06-18 17:01:40 -0700985 }
986 break;
987 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
988 int64_t *timestamp = (int64_t *)p1;
989 if (p1) {
990 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
991 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
992 ?true:false);
993 free(timestamp);
994 }
995 }
996 break;
997 case OMX_COMPONENT_GENERATE_FBD:
998 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700999 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -07001000 pThis->omx_report_error ();
1001 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1002 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001003 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -07001004 pThis->omx_report_error ();
1005 }
1006 break;
1007
1008 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001009 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001010 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001011 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001012 } else {
1013 pThis->execute_input_flush();
1014 if (pThis->m_cb.EventHandler) {
1015 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001016 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001017 pThis->omx_report_error ();
1018 } else {
1019 /*Check if we need generate event for Flush done*/
1020 if (BITMASK_PRESENT(&pThis->m_flags,
1021 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1022 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001023 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001024 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1025 OMX_EventCmdComplete,OMX_CommandFlush,
1026 OMX_CORE_INPUT_PORT_INDEX,NULL );
1027 }
1028 if (BITMASK_PRESENT(&pThis->m_flags,
1029 OMX_COMPONENT_IDLE_PENDING)) {
1030 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001031 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001032 pThis->omx_report_error ();
1033 } else {
1034 pThis->streaming[OUTPUT_PORT] = false;
1035 }
1036 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001037 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001038 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1039 OMX_COMPONENT_GENERATE_STOP_DONE);
1040 }
1041 }
1042 }
1043 } else {
1044 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1045 }
1046 }
1047 break;
1048
1049 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001050 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001051 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001052 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001053 } else {
1054 pThis->execute_output_flush();
1055 if (pThis->m_cb.EventHandler) {
1056 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001057 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001058 pThis->omx_report_error ();
1059 } else {
1060 /*Check if we need generate event for Flush done*/
1061 if (BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001063 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001064 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1065 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1066 OMX_EventCmdComplete,OMX_CommandFlush,
1067 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1068 }
1069 if (BITMASK_PRESENT(&pThis->m_flags,
1070 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001071 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001072 BITMASK_CLEAR (&pThis->m_flags,
1073 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1074 if (BITMASK_PRESENT(&pThis->m_flags,
1075 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1076 pThis->post_event(OMX_CommandPortDisable,
1077 OMX_CORE_OUTPUT_PORT_INDEX,
1078 OMX_COMPONENT_GENERATE_EVENT);
1079 BITMASK_CLEAR (&pThis->m_flags,
1080 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001081 BITMASK_CLEAR (&pThis->m_flags,
1082 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001083
1084 }
1085 }
1086
1087 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1088 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001089 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001090 pThis->omx_report_error ();
1091 break;
1092 }
1093 pThis->streaming[CAPTURE_PORT] = false;
1094 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001095 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001096 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1097 OMX_COMPONENT_GENERATE_STOP_DONE);
1098 }
1099 }
1100 }
1101 } else {
1102 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1103 }
1104 }
1105 break;
1106
1107 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001108 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001109
1110 if (pThis->m_cb.EventHandler) {
1111 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001112 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001113 pThis->omx_report_error ();
1114 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001115 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001116 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001117 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001118 // Send the callback now
1119 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1120 pThis->m_state = OMX_StateExecuting;
1121 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1122 OMX_EventCmdComplete,OMX_CommandStateSet,
1123 OMX_StateExecuting, NULL);
1124 } else if (BITMASK_PRESENT(&pThis->m_flags,
1125 OMX_COMPONENT_PAUSE_PENDING)) {
1126 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1127 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001128 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001129 pThis->omx_report_error ();
1130 }
1131 }
1132 }
1133 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001134 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001135 }
1136 break;
1137
1138 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001139 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001140 if (pThis->m_cb.EventHandler) {
1141 if (p2 != VDEC_S_SUCCESS) {
1142 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1143 pThis->omx_report_error ();
1144 } else {
1145 pThis->complete_pending_buffer_done_cbs();
1146 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001147 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001148 //Send the callback now
1149 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1150 pThis->m_state = OMX_StatePause;
1151 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1152 OMX_EventCmdComplete,OMX_CommandStateSet,
1153 OMX_StatePause, NULL);
1154 }
1155 }
1156 } else {
1157 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1158 }
1159
1160 break;
1161
1162 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001163 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001164 if (pThis->m_cb.EventHandler) {
1165 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001166 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001167 pThis->omx_report_error ();
1168 } else {
1169 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001170 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001171 // Send the callback now
1172 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1173 pThis->m_state = OMX_StateExecuting;
1174 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1175 OMX_EventCmdComplete,OMX_CommandStateSet,
1176 OMX_StateExecuting,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_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001186 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001187 if (pThis->m_cb.EventHandler) {
1188 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001189 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001190 pThis->omx_report_error ();
1191 } else {
1192 pThis->complete_pending_buffer_done_cbs();
1193 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001194 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001195 // Send the callback now
1196 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1197 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001198 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001199 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1200 OMX_EventCmdComplete,OMX_CommandStateSet,
1201 OMX_StateIdle,NULL);
1202 }
1203 }
1204 } else {
1205 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1206 }
1207
1208 break;
1209
1210 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001211 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001212
1213 if (p2 == OMX_IndexParamPortDefinition) {
1214 pThis->in_reconfig = true;
1215 }
1216 if (pThis->m_cb.EventHandler) {
1217 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1218 OMX_EventPortSettingsChanged, p1, p2, NULL );
1219 } else {
1220 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1221 }
1222
Arun Menon906de572013-06-18 17:01:40 -07001223 break;
1224
1225 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001226 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001227 if (pThis->m_cb.EventHandler) {
1228 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1229 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1230 } else {
1231 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1232 }
1233 pThis->prev_ts = LLONG_MAX;
1234 pThis->rst_prev_ts = true;
1235 break;
1236
1237 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001238 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001239 pThis->omx_report_error ();
1240 break;
1241
1242 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001243 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001244 pThis->omx_report_unsupported_setting();
1245 break;
1246
Deepak Verma24720fb2014-01-29 16:57:40 +05301247 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1248 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1249 pThis->omx_report_hw_overload();
1250 break;
1251
Arun Menon906de572013-06-18 17:01:40 -07001252 default:
1253 break;
1254 }
1255 }
1256 pthread_mutex_lock(&pThis->m_lock);
1257 qsize = pThis->m_cmd_q.m_size;
1258 if (pThis->m_state != OMX_StatePause)
1259 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1260 pthread_mutex_unlock(&pThis->m_lock);
1261 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001262
1263}
1264
Vinay Kaliab9e98102013-04-02 19:31:43 -07001265int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001266{
Arun Menon906de572013-06-18 17:01:40 -07001267 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301268 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1269 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001270 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001271 width, drv_ctx.video_resolution.frame_width,
1272 height,drv_ctx.video_resolution.frame_height);
1273 format_changed = 1;
1274 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001275 drv_ctx.video_resolution.frame_height = height;
1276 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001277 drv_ctx.video_resolution.scan_lines = scan_lines;
1278 drv_ctx.video_resolution.stride = stride;
Pushkaraj Patil41588352014-02-25 20:51:34 +05301279 if(!is_down_scalar_enabled) {
1280 rectangle.nLeft = 0;
1281 rectangle.nTop = 0;
1282 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1283 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1284 }
Arun Menon906de572013-06-18 17:01:40 -07001285 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001286}
1287
Arun Menon6836ba02013-02-19 20:37:40 -08001288OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1289{
Arun Menon906de572013-06-18 17:01:40 -07001290 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1291 OMX_MAX_STRINGNAME_SIZE) &&
1292 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1293 m_decoder_capability.max_width = 1280;
1294 m_decoder_capability.max_height = 720;
1295 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1296 }
Arun Menon888aa852013-05-30 11:24:42 -07001297
Arun Menon906de572013-06-18 17:01:40 -07001298 if ((drv_ctx.video_resolution.frame_width *
1299 drv_ctx.video_resolution.frame_height >
1300 m_decoder_capability.max_width *
1301 m_decoder_capability.max_height) ||
1302 (drv_ctx.video_resolution.frame_width*
1303 drv_ctx.video_resolution.frame_height <
1304 m_decoder_capability.min_width *
1305 m_decoder_capability.min_height)) {
1306 DEBUG_PRINT_ERROR(
1307 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1308 drv_ctx.video_resolution.frame_width,
1309 drv_ctx.video_resolution.frame_height,
1310 m_decoder_capability.min_width,
1311 m_decoder_capability.min_height,
1312 m_decoder_capability.max_width,
1313 m_decoder_capability.max_height);
1314 return OMX_ErrorUnsupportedSetting;
1315 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001316 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001317 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001318}
1319
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001320int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1321{
1322 if (m_debug.in_buffer_log && !m_debug.infile) {
1323 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1324 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1325 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1326 }
1327 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1328 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); }
1329 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1330 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1331 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1332 }
1333 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1334 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1335 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1336 }
1337 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1338 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1339 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1340 }
1341 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1342 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1343 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1344 }
1345 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1346 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1347 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1348 }
1349 m_debug.infile = fopen (m_debug.infile_name, "ab");
1350 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001351 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001352 m_debug.infile_name[0] = '\0';
1353 return -1;
1354 }
1355 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1356 struct ivf_file_header {
1357 OMX_U8 signature[4]; //='DKIF';
1358 OMX_U8 version ; //= 0;
1359 OMX_U8 headersize ; //= 32;
1360 OMX_U32 FourCC;
1361 OMX_U8 width;
1362 OMX_U8 height;
1363 OMX_U32 rate;
1364 OMX_U32 scale;
1365 OMX_U32 length;
1366 OMX_U8 unused[4];
1367 } file_header;
1368
1369 memset((void *)&file_header,0,sizeof(file_header));
1370 file_header.signature[0] = 'D';
1371 file_header.signature[1] = 'K';
1372 file_header.signature[2] = 'I';
1373 file_header.signature[3] = 'F';
1374 file_header.version = 0;
1375 file_header.headersize = 32;
1376 file_header.FourCC = 0x30385056;
1377 fwrite((const char *)&file_header,
1378 sizeof(file_header),1,m_debug.infile);
1379 }
1380 }
1381 if (m_debug.infile && buffer_addr && buffer_len) {
1382 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1383 struct vp8_ivf_frame_header {
1384 OMX_U32 framesize;
1385 OMX_U32 timestamp_lo;
1386 OMX_U32 timestamp_hi;
1387 } vp8_frame_header;
1388 vp8_frame_header.framesize = buffer_len;
1389 /* Currently FW doesn't use timestamp values */
1390 vp8_frame_header.timestamp_lo = 0;
1391 vp8_frame_header.timestamp_hi = 0;
1392 fwrite((const char *)&vp8_frame_header,
1393 sizeof(vp8_frame_header),1,m_debug.infile);
1394 }
1395 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1396 }
1397 return 0;
1398}
1399
1400int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1401 if (m_debug.out_buffer_log && !m_debug.outfile) {
1402 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1403 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1404 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1405 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001406 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001407 m_debug.outfile_name[0] = '\0';
1408 return -1;
1409 }
1410 }
1411 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1412 int buf_index = buffer - m_out_mem_ptr;
1413 int stride = drv_ctx.video_resolution.stride;
1414 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301415 if (m_smoothstreaming_mode) {
1416 stride = drv_ctx.video_resolution.frame_width;
1417 scanlines = drv_ctx.video_resolution.frame_height;
1418 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1419 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1420 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001421 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1422 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301423 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1424 drv_ctx.video_resolution.frame_width,
1425 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001426 int bytes_written = 0;
1427 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1428 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1429 temp += stride;
1430 }
1431 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1432 int stride_c = stride;
1433 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1434 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1435 temp += stride_c;
1436 }
1437 }
1438 return 0;
1439}
1440
Shalaj Jain273b3e02012-06-22 19:08:03 -07001441/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001442 FUNCTION
1443 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001444
Arun Menon906de572013-06-18 17:01:40 -07001445 DESCRIPTION
1446 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001447
Arun Menon906de572013-06-18 17:01:40 -07001448 PARAMETERS
1449 ctxt -- Context information related to the self.
1450 id -- Event identifier. This could be any of the following:
1451 1. Command completion event
1452 2. Buffer done callback event
1453 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454
Arun Menon906de572013-06-18 17:01:40 -07001455 RETURN VALUE
1456 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457
Arun Menon906de572013-06-18 17:01:40 -07001458 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001459OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1460{
1461
Arun Menon906de572013-06-18 17:01:40 -07001462 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1463 struct v4l2_fmtdesc fdesc;
1464 struct v4l2_format fmt;
1465 struct v4l2_requestbuffers bufreq;
1466 struct v4l2_control control;
1467 struct v4l2_frmsizeenum frmsize;
1468 unsigned int alignment = 0,buffer_size = 0;
1469 int fds[2];
1470 int r,ret=0;
1471 bool codec_ambiguous = false;
1472 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001473 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001474
1475#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001476 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001477 property_get("ro.board.platform", platform_name, "0");
1478 if (!strncmp(platform_name, "msm8610", 7)) {
1479 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301480 is_q6_platform = true;
1481 maxSmoothStreamingWidth = 1280;
1482 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001483 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001484#endif
1485
Arun Menon906de572013-06-18 17:01:40 -07001486 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1487 struct v4l2_control control;
1488 secure_mode = true;
1489 arbitrary_bytes = false;
1490 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301491 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1492 OMX_MAX_STRINGNAME_SIZE)){
1493 secure_mode = true;
1494 arbitrary_bytes = false;
1495 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001496 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001497
Arun Menon906de572013-06-18 17:01:40 -07001498 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001499
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001500 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001501 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001502
Arun Menon906de572013-06-18 17:01:40 -07001503 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001504 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001505 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1506 close(0);
1507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001508
Arun Menon906de572013-06-18 17:01:40 -07001509 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001510 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001511 return OMX_ErrorInsufficientResources;
1512 }
1513 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1514 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001515
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001516 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001517 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001518 async_thread_created = true;
1519 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1520 }
1521 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001522 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001523 async_thread_created = false;
1524 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001525 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001526
Shalaj Jain273b3e02012-06-22 19:08:03 -07001527#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001528 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001529#endif
1530
Arun Menon906de572013-06-18 17:01:40 -07001531 // Copy the role information which provides the decoder kind
1532 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001533
Arun Menon906de572013-06-18 17:01:40 -07001534 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1535 OMX_MAX_STRINGNAME_SIZE)) {
1536 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1537 OMX_MAX_STRINGNAME_SIZE);
1538 drv_ctx.timestamp_adjust = true;
1539 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1540 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1541 output_capability=V4L2_PIX_FMT_MPEG4;
1542 /*Initialize Start Code for MPEG4*/
1543 codec_type_parse = CODEC_TYPE_MPEG4;
1544 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001545 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1546 OMX_MAX_STRINGNAME_SIZE)) {
1547 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1548 OMX_MAX_STRINGNAME_SIZE);
1549 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1550 output_capability = V4L2_PIX_FMT_MPEG2;
1551 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1552 /*Initialize Start Code for MPEG2*/
1553 codec_type_parse = CODEC_TYPE_MPEG2;
1554 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001555 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1556 OMX_MAX_STRINGNAME_SIZE)) {
1557 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001558 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001559 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1560 eCompressionFormat = OMX_VIDEO_CodingH263;
1561 output_capability = V4L2_PIX_FMT_H263;
1562 codec_type_parse = CODEC_TYPE_H263;
1563 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001564 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1565 OMX_MAX_STRINGNAME_SIZE)) {
1566 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001567 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001568 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1569 output_capability = V4L2_PIX_FMT_DIVX_311;
1570 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1571 codec_type_parse = CODEC_TYPE_DIVX;
1572 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001573
Arun Menon906de572013-06-18 17:01:40 -07001574 eRet = createDivxDrmContext();
1575 if (eRet != OMX_ErrorNone) {
1576 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1577 return eRet;
1578 }
1579 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1580 OMX_MAX_STRINGNAME_SIZE)) {
1581 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001582 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001583 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1584 output_capability = V4L2_PIX_FMT_DIVX;
1585 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1586 codec_type_parse = CODEC_TYPE_DIVX;
1587 codec_ambiguous = true;
1588 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001589
Arun Menon906de572013-06-18 17:01:40 -07001590 eRet = createDivxDrmContext();
1591 if (eRet != OMX_ErrorNone) {
1592 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1593 return eRet;
1594 }
1595 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1596 OMX_MAX_STRINGNAME_SIZE)) {
1597 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001598 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001599 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1600 output_capability = V4L2_PIX_FMT_DIVX;
1601 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1602 codec_type_parse = CODEC_TYPE_DIVX;
1603 codec_ambiguous = true;
1604 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605
Arun Menon906de572013-06-18 17:01:40 -07001606 eRet = createDivxDrmContext();
1607 if (eRet != OMX_ErrorNone) {
1608 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1609 return eRet;
1610 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001611
Arun Menon906de572013-06-18 17:01:40 -07001612 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1613 OMX_MAX_STRINGNAME_SIZE)) {
1614 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1615 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1616 output_capability=V4L2_PIX_FMT_H264;
1617 eCompressionFormat = OMX_VIDEO_CodingAVC;
1618 codec_type_parse = CODEC_TYPE_H264;
1619 m_frame_parser.init_start_codes (codec_type_parse);
1620 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001621 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1622 OMX_MAX_STRINGNAME_SIZE)) {
1623 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1624 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1625 eCompressionFormat = OMX_VIDEO_CodingWMV;
1626 codec_type_parse = CODEC_TYPE_VC1;
1627 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1628 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001629 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1630 OMX_MAX_STRINGNAME_SIZE)) {
1631 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1632 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1633 eCompressionFormat = OMX_VIDEO_CodingWMV;
1634 codec_type_parse = CODEC_TYPE_VC1;
1635 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1636 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001637 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1638 OMX_MAX_STRINGNAME_SIZE)) {
1639 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1640 output_capability=V4L2_PIX_FMT_VP8;
1641 eCompressionFormat = OMX_VIDEO_CodingVPX;
1642 codec_type_parse = CODEC_TYPE_VP8;
1643 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001644
Arun Menon906de572013-06-18 17:01:40 -07001645 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001646 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001647 eRet = OMX_ErrorInvalidComponentName;
1648 }
Arun Menon906de572013-06-18 17:01:40 -07001649 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001650
Arun Menon906de572013-06-18 17:01:40 -07001651 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001652 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1653 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1654 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001655 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001656 eRet = OMX_ErrorInsufficientResources;
1657 }
1658
Arun Menon906de572013-06-18 17:01:40 -07001659 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001660
Arun Menon906de572013-06-18 17:01:40 -07001661 struct v4l2_capability cap;
1662 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1663 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001664 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001665 /*TODO: How to handle this case */
1666 } else {
1667 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001668 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001669 cap.bus_info, cap.version, cap.capabilities);
1670 }
1671 ret=0;
1672 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1673 fdesc.index=0;
1674 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001675 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001676 fdesc.pixelformat, fdesc.flags);
1677 fdesc.index++;
1678 }
1679 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1680 fdesc.index=0;
1681 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001682
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001683 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001684 fdesc.pixelformat, fdesc.flags);
1685 fdesc.index++;
1686 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001687 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001688 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1689 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1690 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1691 fmt.fmt.pix_mp.pixelformat = output_capability;
1692 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1693 if (ret) {
1694 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001695 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001696 return OMX_ErrorInsufficientResources;
1697 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001698 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001699 if (codec_ambiguous) {
1700 if (output_capability == V4L2_PIX_FMT_DIVX) {
1701 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001702
Arun Menon906de572013-06-18 17:01:40 -07001703 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1704 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1705 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1706 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1707 } else {
1708 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001710
Arun Menon906de572013-06-18 17:01:40 -07001711 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1712 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1713 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001714 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001715 }
1716 } else {
1717 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1718 }
1719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001720
Jia Meng3a3c6492013-12-19 17:16:52 +08001721 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1722 m_conceal_color= atoi(property_value);
1723 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1724 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1725 control.value = m_conceal_color;
1726 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1727 if (ret) {
1728 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1729 }
1730
Arun Menon906de572013-06-18 17:01:40 -07001731 //Get the hardware capabilities
1732 memset((void *)&frmsize,0,sizeof(frmsize));
1733 frmsize.index = 0;
1734 frmsize.pixel_format = output_capability;
1735 ret = ioctl(drv_ctx.video_driver_fd,
1736 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1737 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001738 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001739 return OMX_ErrorHardware;
1740 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001741
Arun Menon906de572013-06-18 17:01:40 -07001742 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1743 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1744 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1745 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1746 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1747 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001748
Arun Menon906de572013-06-18 17:01:40 -07001749 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1750 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1751 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1752 fmt.fmt.pix_mp.pixelformat = capture_capability;
1753 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1754 if (ret) {
1755 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001756 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001757 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001758 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001759 if (secure_mode) {
1760 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1761 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001762 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001763 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1764 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001765 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001766 return OMX_ErrorInsufficientResources;
1767 }
1768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001769
Arun Menon906de572013-06-18 17:01:40 -07001770 /*Get the Buffer requirements for input and output ports*/
1771 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1772 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1773 if (secure_mode) {
1774 drv_ctx.op_buf.alignment=SZ_1M;
1775 drv_ctx.ip_buf.alignment=SZ_1M;
1776 } else {
1777 drv_ctx.op_buf.alignment=SZ_4K;
1778 drv_ctx.ip_buf.alignment=SZ_4K;
1779 }
1780 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1781 drv_ctx.extradata = 0;
1782 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1783 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1784 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1785 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1786 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001787
Vinay Kalia5713bb32013-01-16 18:39:59 -08001788 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001789#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001790 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1791 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1792 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001793#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001794 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001795 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001796 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001797 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1798 if (m_frame_parser.mutils == NULL) {
1799 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800
Arun Menon906de572013-06-18 17:01:40 -07001801 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001802 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001803 eRet = OMX_ErrorInsufficientResources;
1804 } else {
1805 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1806 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1807 h264_scratch.nFilledLen = 0;
1808 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001809
Arun Menon906de572013-06-18 17:01:40 -07001810 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001811 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001812 return OMX_ErrorInsufficientResources;
1813 }
1814 m_frame_parser.mutils->initialize_frame_checking_environment();
1815 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1816 }
1817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001818
Arun Menon906de572013-06-18 17:01:40 -07001819 h264_parser = new h264_stream_parser();
1820 if (!h264_parser) {
1821 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1822 eRet = OMX_ErrorInsufficientResources;
1823 }
1824 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001825
Arun Menon906de572013-06-18 17:01:40 -07001826 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001827 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001828 eRet = OMX_ErrorInsufficientResources;
1829 } else {
1830 int temp1[2];
1831 if (fds[0] == 0 || fds[1] == 0) {
1832 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001833 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001834 return OMX_ErrorInsufficientResources;
1835 }
1836 //close (fds[0]);
1837 //close (fds[1]);
1838 fds[0] = temp1 [0];
1839 fds[1] = temp1 [1];
1840 }
1841 m_pipe_in = fds[0];
1842 m_pipe_out = fds[1];
1843 msg_thread_created = true;
1844 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001845
Arun Menon906de572013-06-18 17:01:40 -07001846 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001847 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001848 msg_thread_created = false;
1849 eRet = OMX_ErrorInsufficientResources;
1850 }
1851 }
1852 }
1853
1854 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001855 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001856 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001857 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001858 }
1859 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1860 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001861}
1862
1863/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001864 FUNCTION
1865 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001866
Arun Menon906de572013-06-18 17:01:40 -07001867 DESCRIPTION
1868 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001869
Arun Menon906de572013-06-18 17:01:40 -07001870 PARAMETERS
1871 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001872
Arun Menon906de572013-06-18 17:01:40 -07001873 RETURN VALUE
1874 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001875
Arun Menon906de572013-06-18 17:01:40 -07001876 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001877OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001878(
1879 OMX_IN OMX_HANDLETYPE hComp,
1880 OMX_OUT OMX_STRING componentName,
1881 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1882 OMX_OUT OMX_VERSIONTYPE* specVersion,
1883 OMX_OUT OMX_UUIDTYPE* componentUUID
1884 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001885{
Arun Menon906de572013-06-18 17:01:40 -07001886 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001887 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001888 return OMX_ErrorInvalidState;
1889 }
Arun Menon906de572013-06-18 17:01:40 -07001890 /* TBD -- Return the proper version */
1891 if (specVersion) {
1892 specVersion->nVersion = OMX_SPEC_VERSION;
1893 }
1894 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001895}
1896/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001897 FUNCTION
1898 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001899
Arun Menon906de572013-06-18 17:01:40 -07001900 DESCRIPTION
1901 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001902
Arun Menon906de572013-06-18 17:01:40 -07001903 PARAMETERS
1904 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001905
Arun Menon906de572013-06-18 17:01:40 -07001906 RETURN VALUE
1907 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001908
Arun Menon906de572013-06-18 17:01:40 -07001909 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001910OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001911 OMX_IN OMX_COMMANDTYPE cmd,
1912 OMX_IN OMX_U32 param1,
1913 OMX_IN OMX_PTR cmdData
1914 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001915{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001916 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001917 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001918 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001919 return OMX_ErrorInvalidState;
1920 }
1921 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001922 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001923 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001924 "to invalid port: %lu", param1);
1925 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001926 }
1927 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1928 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001929 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001930 return OMX_ErrorNone;
1931}
1932
1933/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001934 FUNCTION
1935 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001936
Arun Menon906de572013-06-18 17:01:40 -07001937 DESCRIPTION
1938 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001939
Arun Menon906de572013-06-18 17:01:40 -07001940 PARAMETERS
1941 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001942
Arun Menon906de572013-06-18 17:01:40 -07001943 RETURN VALUE
1944 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001945
Arun Menon906de572013-06-18 17:01:40 -07001946 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001947OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001948 OMX_IN OMX_COMMANDTYPE cmd,
1949 OMX_IN OMX_U32 param1,
1950 OMX_IN OMX_PTR cmdData
1951 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001952{
Arun Menon906de572013-06-18 17:01:40 -07001953 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1954 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1955 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001956
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001957 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1958 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001959 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001960
Arun Menon906de572013-06-18 17:01:40 -07001961 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001962 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1963 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001964 /***************************/
1965 /* Current State is Loaded */
1966 /***************************/
1967 if (m_state == OMX_StateLoaded) {
1968 if (eState == OMX_StateIdle) {
1969 //if all buffers are allocated or all ports disabled
1970 if (allocate_done() ||
1971 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001972 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001973 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001974 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001975 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1976 // Skip the event notification
1977 bFlag = 0;
1978 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001979 }
Arun Menon906de572013-06-18 17:01:40 -07001980 /* Requesting transition from Loaded to Loaded */
1981 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001982 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001983 post_event(OMX_EventError,OMX_ErrorSameState,\
1984 OMX_COMPONENT_GENERATE_EVENT);
1985 eRet = OMX_ErrorSameState;
1986 }
1987 /* Requesting transition from Loaded to WaitForResources */
1988 else if (eState == OMX_StateWaitForResources) {
1989 /* Since error is None , we will post an event
1990 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001991 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001992 }
1993 /* Requesting transition from Loaded to Executing */
1994 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001995 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001996 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1997 OMX_COMPONENT_GENERATE_EVENT);
1998 eRet = OMX_ErrorIncorrectStateTransition;
1999 }
2000 /* Requesting transition from Loaded to Pause */
2001 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002002 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002003 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2004 OMX_COMPONENT_GENERATE_EVENT);
2005 eRet = OMX_ErrorIncorrectStateTransition;
2006 }
2007 /* Requesting transition from Loaded to Invalid */
2008 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002009 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002010 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2011 eRet = OMX_ErrorInvalidState;
2012 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002013 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002014 eState);
2015 eRet = OMX_ErrorBadParameter;
2016 }
2017 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002018
Arun Menon906de572013-06-18 17:01:40 -07002019 /***************************/
2020 /* Current State is IDLE */
2021 /***************************/
2022 else if (m_state == OMX_StateIdle) {
2023 if (eState == OMX_StateLoaded) {
2024 if (release_done()) {
2025 /*
2026 Since error is None , we will post an event at the end
2027 of this function definition
2028 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002029 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002030 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002031 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002032 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2033 // Skip the event notification
2034 bFlag = 0;
2035 }
2036 }
2037 /* Requesting transition from Idle to Executing */
2038 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002039 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002040 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2041 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002042 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002043 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002044 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002045 }
2046 /* Requesting transition from Idle to Idle */
2047 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002048 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002049 post_event(OMX_EventError,OMX_ErrorSameState,\
2050 OMX_COMPONENT_GENERATE_EVENT);
2051 eRet = OMX_ErrorSameState;
2052 }
2053 /* Requesting transition from Idle to WaitForResources */
2054 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002055 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002056 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2057 OMX_COMPONENT_GENERATE_EVENT);
2058 eRet = OMX_ErrorIncorrectStateTransition;
2059 }
2060 /* Requesting transition from Idle to Pause */
2061 else if (eState == OMX_StatePause) {
2062 /*To pause the Video core we need to start the driver*/
2063 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2064 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002065 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002066 omx_report_error ();
2067 eRet = OMX_ErrorHardware;
2068 } else {
2069 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002070 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002071 bFlag = 0;
2072 }
2073 }
2074 /* Requesting transition from Idle to Invalid */
2075 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002076 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002077 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2078 eRet = OMX_ErrorInvalidState;
2079 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002080 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002081 eRet = OMX_ErrorBadParameter;
2082 }
2083 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002084
Arun Menon906de572013-06-18 17:01:40 -07002085 /******************************/
2086 /* Current State is Executing */
2087 /******************************/
2088 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002089 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002090 /* Requesting transition from Executing to Idle */
2091 if (eState == OMX_StateIdle) {
2092 /* Since error is None , we will post an event
2093 at the end of this function definition
2094 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002095 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002096 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2097 if (!sem_posted) {
2098 sem_posted = 1;
2099 sem_post (&m_cmd_lock);
2100 execute_omx_flush(OMX_ALL);
2101 }
2102 bFlag = 0;
2103 }
2104 /* Requesting transition from Executing to Paused */
2105 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002106 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002107 m_state = OMX_StatePause;
2108 bFlag = 1;
2109 }
2110 /* Requesting transition from Executing to Loaded */
2111 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002112 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002113 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2114 OMX_COMPONENT_GENERATE_EVENT);
2115 eRet = OMX_ErrorIncorrectStateTransition;
2116 }
2117 /* Requesting transition from Executing to WaitForResources */
2118 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002119 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002120 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2121 OMX_COMPONENT_GENERATE_EVENT);
2122 eRet = OMX_ErrorIncorrectStateTransition;
2123 }
2124 /* Requesting transition from Executing to Executing */
2125 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002126 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002127 post_event(OMX_EventError,OMX_ErrorSameState,\
2128 OMX_COMPONENT_GENERATE_EVENT);
2129 eRet = OMX_ErrorSameState;
2130 }
2131 /* Requesting transition from Executing to Invalid */
2132 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002133 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002134 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2135 eRet = OMX_ErrorInvalidState;
2136 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002137 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002138 eRet = OMX_ErrorBadParameter;
2139 }
2140 }
2141 /***************************/
2142 /* Current State is Pause */
2143 /***************************/
2144 else if (m_state == OMX_StatePause) {
2145 /* Requesting transition from Pause to Executing */
2146 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002147 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002148 m_state = OMX_StateExecuting;
2149 bFlag = 1;
2150 }
2151 /* Requesting transition from Pause to Idle */
2152 else if (eState == OMX_StateIdle) {
2153 /* Since error is None , we will post an event
2154 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002155 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002156 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2157 if (!sem_posted) {
2158 sem_posted = 1;
2159 sem_post (&m_cmd_lock);
2160 execute_omx_flush(OMX_ALL);
2161 }
2162 bFlag = 0;
2163 }
2164 /* Requesting transition from Pause to loaded */
2165 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002166 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002167 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2168 OMX_COMPONENT_GENERATE_EVENT);
2169 eRet = OMX_ErrorIncorrectStateTransition;
2170 }
2171 /* Requesting transition from Pause to WaitForResources */
2172 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002173 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002174 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2175 OMX_COMPONENT_GENERATE_EVENT);
2176 eRet = OMX_ErrorIncorrectStateTransition;
2177 }
2178 /* Requesting transition from Pause to Pause */
2179 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002180 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002181 post_event(OMX_EventError,OMX_ErrorSameState,\
2182 OMX_COMPONENT_GENERATE_EVENT);
2183 eRet = OMX_ErrorSameState;
2184 }
2185 /* Requesting transition from Pause to Invalid */
2186 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002187 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002188 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2189 eRet = OMX_ErrorInvalidState;
2190 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002191 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002192 eRet = OMX_ErrorBadParameter;
2193 }
2194 }
2195 /***************************/
2196 /* Current State is WaitForResources */
2197 /***************************/
2198 else if (m_state == OMX_StateWaitForResources) {
2199 /* Requesting transition from WaitForResources to Loaded */
2200 if (eState == OMX_StateLoaded) {
2201 /* Since error is None , we will post an event
2202 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002203 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002204 }
2205 /* Requesting transition from WaitForResources to WaitForResources */
2206 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002207 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002208 post_event(OMX_EventError,OMX_ErrorSameState,
2209 OMX_COMPONENT_GENERATE_EVENT);
2210 eRet = OMX_ErrorSameState;
2211 }
2212 /* Requesting transition from WaitForResources to Executing */
2213 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002214 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002215 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2216 OMX_COMPONENT_GENERATE_EVENT);
2217 eRet = OMX_ErrorIncorrectStateTransition;
2218 }
2219 /* Requesting transition from WaitForResources to Pause */
2220 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002221 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002222 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2223 OMX_COMPONENT_GENERATE_EVENT);
2224 eRet = OMX_ErrorIncorrectStateTransition;
2225 }
2226 /* Requesting transition from WaitForResources to Invalid */
2227 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002228 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002229 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2230 eRet = OMX_ErrorInvalidState;
2231 }
2232 /* Requesting transition from WaitForResources to Loaded -
2233 is NOT tested by Khronos TS */
2234
2235 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002236 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002237 eRet = OMX_ErrorBadParameter;
2238 }
2239 }
2240 /********************************/
2241 /* Current State is Invalid */
2242 /*******************************/
2243 else if (m_state == OMX_StateInvalid) {
2244 /* State Transition from Inavlid to any state */
2245 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2246 || OMX_StateIdle || OMX_StateExecuting
2247 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002248 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002249 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2250 OMX_COMPONENT_GENERATE_EVENT);
2251 eRet = OMX_ErrorInvalidState;
2252 }
2253 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002254 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002255 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002256#ifdef _MSM8974_
2257 send_codec_config();
2258#endif
Arun Menon906de572013-06-18 17:01:40 -07002259 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2260 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2261 }
2262 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2263 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2264 }
2265 if (!sem_posted) {
2266 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002267 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002268 sem_post (&m_cmd_lock);
2269 execute_omx_flush(param1);
2270 }
2271 bFlag = 0;
2272 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002273 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002274 "with param1: %lu", param1);
2275 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2276 m_inp_bEnabled = OMX_TRUE;
2277
2278 if ( (m_state == OMX_StateLoaded &&
2279 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2280 || allocate_input_done()) {
2281 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2282 OMX_COMPONENT_GENERATE_EVENT);
2283 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002284 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002285 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2286 // Skip the event notification
2287 bFlag = 0;
2288 }
2289 }
2290 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002291 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002292 m_out_bEnabled = OMX_TRUE;
2293
2294 if ( (m_state == OMX_StateLoaded &&
2295 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2296 || (allocate_output_done())) {
2297 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2298 OMX_COMPONENT_GENERATE_EVENT);
2299
2300 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002301 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002302 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2303 // Skip the event notification
2304 bFlag = 0;
2305 }
2306 }
2307 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002308 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002309 "with param1: %lu", param1);
2310 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002311 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002312 m_inp_bEnabled = OMX_FALSE;
2313 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2314 && release_input_done()) {
2315 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2316 OMX_COMPONENT_GENERATE_EVENT);
2317 } else {
2318 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2319 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2320 if (!sem_posted) {
2321 sem_posted = 1;
2322 sem_post (&m_cmd_lock);
2323 }
2324 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2325 }
2326
2327 // Skip the event notification
2328 bFlag = 0;
2329 }
2330 }
2331 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2332 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002333 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002334 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2335 && release_output_done()) {
2336 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2337 OMX_COMPONENT_GENERATE_EVENT);
2338 } else {
2339 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2340 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2341 if (!sem_posted) {
2342 sem_posted = 1;
2343 sem_post (&m_cmd_lock);
2344 }
2345 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2346 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2347 }
2348 // Skip the event notification
2349 bFlag = 0;
2350
2351 }
2352 }
2353 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002354 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002355 eRet = OMX_ErrorNotImplemented;
2356 }
2357 if (eRet == OMX_ErrorNone && bFlag) {
2358 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2359 }
2360 if (!sem_posted) {
2361 sem_post(&m_cmd_lock);
2362 }
2363
2364 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002365}
2366
2367/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002368 FUNCTION
2369 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002370
Arun Menon906de572013-06-18 17:01:40 -07002371 DESCRIPTION
2372 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002373
Arun Menon906de572013-06-18 17:01:40 -07002374 PARAMETERS
2375 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002376
Arun Menon906de572013-06-18 17:01:40 -07002377 RETURN VALUE
2378 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002379
Arun Menon906de572013-06-18 17:01:40 -07002380 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002381bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2382{
Arun Menon906de572013-06-18 17:01:40 -07002383 bool bRet = false;
2384 struct v4l2_plane plane;
2385 struct v4l2_buffer v4l2_buf;
2386 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302387 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002388 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2389 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002390
Arun Menon906de572013-06-18 17:01:40 -07002391 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002392
Arun Menon906de572013-06-18 17:01:40 -07002393 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2394 output_flush_progress = true;
2395 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2396 } else {
2397 /* XXX: The driver/hardware does not support flushing of individual ports
2398 * in all states. So we pretty much need to flush both ports internally,
2399 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2400 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2401 * we automatically omit sending the FLUSH done for the "opposite" port. */
2402 input_flush_progress = true;
2403 output_flush_progress = true;
2404 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2405 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002406
Arun Menon906de572013-06-18 17:01:40 -07002407 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002408 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002409 bRet = false;
2410 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002411
Arun Menon906de572013-06-18 17:01:40 -07002412 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002413}
2414/*=========================================================================
2415FUNCTION : execute_output_flush
2416
2417DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002418Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419
2420PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002421None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002422
2423RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002424true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002425==========================================================================*/
2426bool omx_vdec::execute_output_flush()
2427{
Arun Menon906de572013-06-18 17:01:40 -07002428 unsigned p1 = 0; // Parameter - 1
2429 unsigned p2 = 0; // Parameter - 2
2430 unsigned ident = 0;
2431 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002432
Arun Menon906de572013-06-18 17:01:40 -07002433 /*Generate FBD for all Buffers in the FTBq*/
2434 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002435 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002436
2437 //reset last render TS
2438 if(m_last_rendered_TS > 0) {
2439 m_last_rendered_TS = 0;
2440 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002441
Arun Menon906de572013-06-18 17:01:40 -07002442 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002443 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002444 m_ftb_q.m_size,pending_output_buffers);
2445 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002446 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002447 if (ident == m_fill_output_msg ) {
2448 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2449 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2450 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2451 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002452 }
Arun Menon906de572013-06-18 17:01:40 -07002453 pthread_mutex_unlock(&m_lock);
2454 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002455
Arun Menon906de572013-06-18 17:01:40 -07002456 if (arbitrary_bytes) {
2457 prev_ts = LLONG_MAX;
2458 rst_prev_ts = true;
2459 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002460 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002461 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002462}
2463/*=========================================================================
2464FUNCTION : execute_input_flush
2465
2466DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002467Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002468
2469PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002470None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002471
2472RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002473true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002474==========================================================================*/
2475bool omx_vdec::execute_input_flush()
2476{
Arun Menon906de572013-06-18 17:01:40 -07002477 unsigned i =0;
2478 unsigned p1 = 0; // Parameter - 1
2479 unsigned p2 = 0; // Parameter - 2
2480 unsigned ident = 0;
2481 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482
Arun Menon906de572013-06-18 17:01:40 -07002483 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002484 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002485
Arun Menon906de572013-06-18 17:01:40 -07002486 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002487 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002488 while (m_etb_q.m_size) {
2489 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002490
Arun Menon906de572013-06-18 17:01:40 -07002491 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002492 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002493 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2494 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2495 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002496 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002497 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2498 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2499 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002500 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002501 (OMX_BUFFERHEADERTYPE *)p1);
2502 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2503 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504 }
Arun Menon906de572013-06-18 17:01:40 -07002505 time_stamp_dts.flush_timestamp();
2506 /*Check if Heap Buffers are to be flushed*/
2507 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002508 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002509 h264_scratch.nFilledLen = 0;
2510 nal_count = 0;
2511 look_ahead_nal = false;
2512 frame_count = 0;
2513 h264_last_au_ts = LLONG_MAX;
2514 h264_last_au_flags = 0;
2515 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2516 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002517 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002518 if (m_frame_parser.mutils) {
2519 m_frame_parser.mutils->initialize_frame_checking_environment();
2520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002521
Arun Menon906de572013-06-18 17:01:40 -07002522 while (m_input_pending_q.m_size) {
2523 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2524 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2525 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002526
Arun Menon906de572013-06-18 17:01:40 -07002527 if (psource_frame) {
2528 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2529 psource_frame = NULL;
2530 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531
Arun Menon906de572013-06-18 17:01:40 -07002532 if (pdest_frame) {
2533 pdest_frame->nFilledLen = 0;
2534 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2535 (unsigned int)NULL);
2536 pdest_frame = NULL;
2537 }
2538 m_frame_parser.flush();
2539 } else if (codec_config_flag) {
2540 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2541 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002542 }
Arun Menon906de572013-06-18 17:01:40 -07002543 pthread_mutex_unlock(&m_lock);
2544 input_flush_progress = false;
2545 if (!arbitrary_bytes) {
2546 prev_ts = LLONG_MAX;
2547 rst_prev_ts = true;
2548 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002549#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002550 if (m_debug_timestamp) {
2551 m_timestamp_list.reset_ts_list();
2552 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002553#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002554 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002555 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002556}
2557
2558
2559/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002560 FUNCTION
2561 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002562
Arun Menon906de572013-06-18 17:01:40 -07002563 DESCRIPTION
2564 Send the event to decoder pipe. This is needed to generate the callbacks
2565 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002566
Arun Menon906de572013-06-18 17:01:40 -07002567 PARAMETERS
2568 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002569
Arun Menon906de572013-06-18 17:01:40 -07002570 RETURN VALUE
2571 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002572
Arun Menon906de572013-06-18 17:01:40 -07002573 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002574bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002575 unsigned int p2,
2576 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002577{
Arun Menon906de572013-06-18 17:01:40 -07002578 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002579
2580
Arun Menon906de572013-06-18 17:01:40 -07002581 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002582
Arun Menon906de572013-06-18 17:01:40 -07002583 if (id == m_fill_output_msg ||
2584 id == OMX_COMPONENT_GENERATE_FBD) {
2585 m_ftb_q.insert_entry(p1,p2,id);
2586 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2587 id == OMX_COMPONENT_GENERATE_EBD ||
2588 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2589 m_etb_q.insert_entry(p1,p2,id);
2590 } else {
2591 m_cmd_q.insert_entry(p1,p2,id);
2592 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002593
Arun Menon906de572013-06-18 17:01:40 -07002594 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002595 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002596 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002597
Arun Menon906de572013-06-18 17:01:40 -07002598 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002599
Arun Menon906de572013-06-18 17:01:40 -07002600 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002601}
2602
2603OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2604{
Arun Menon906de572013-06-18 17:01:40 -07002605 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2606 if (!profileLevelType)
2607 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002608
Arun Menon906de572013-06-18 17:01:40 -07002609 if (profileLevelType->nPortIndex == 0) {
2610 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2611 if (profileLevelType->nProfileIndex == 0) {
2612 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2613 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002614
Arun Menon906de572013-06-18 17:01:40 -07002615 } else if (profileLevelType->nProfileIndex == 1) {
2616 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2617 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2618 } else if (profileLevelType->nProfileIndex == 2) {
2619 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2620 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2621 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002622 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002623 profileLevelType->nProfileIndex);
2624 eRet = OMX_ErrorNoMore;
2625 }
2626 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2627 if (profileLevelType->nProfileIndex == 0) {
2628 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2629 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2630 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002631 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002632 eRet = OMX_ErrorNoMore;
2633 }
2634 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2635 if (profileLevelType->nProfileIndex == 0) {
2636 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2637 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2638 } else if (profileLevelType->nProfileIndex == 1) {
2639 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2640 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2641 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002642 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002643 eRet = OMX_ErrorNoMore;
2644 }
2645 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2646 eRet = OMX_ErrorNoMore;
2647 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2648 if (profileLevelType->nProfileIndex == 0) {
2649 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2650 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2651 } else if (profileLevelType->nProfileIndex == 1) {
2652 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2653 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2654 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002655 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002656 eRet = OMX_ErrorNoMore;
2657 }
2658 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002659 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002660 eRet = OMX_ErrorNoMore;
2661 }
2662 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002663 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002664 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002665 }
Arun Menon906de572013-06-18 17:01:40 -07002666 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002667}
2668
2669/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002670 FUNCTION
2671 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002672
Arun Menon906de572013-06-18 17:01:40 -07002673 DESCRIPTION
2674 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675
Arun Menon906de572013-06-18 17:01:40 -07002676 PARAMETERS
2677 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002678
Arun Menon906de572013-06-18 17:01:40 -07002679 RETURN VALUE
2680 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002681
Arun Menon906de572013-06-18 17:01:40 -07002682 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002683OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002684 OMX_IN OMX_INDEXTYPE paramIndex,
2685 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002686{
2687 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2688
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002689 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002690 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002691 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002692 return OMX_ErrorInvalidState;
2693 }
Arun Menon906de572013-06-18 17:01:40 -07002694 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002695 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002696 return OMX_ErrorBadParameter;
2697 }
Arun Menon906de572013-06-18 17:01:40 -07002698 switch ((unsigned long)paramIndex) {
2699 case OMX_IndexParamPortDefinition: {
2700 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2701 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002702 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002703 eRet = update_portdef(portDefn);
2704 if (eRet == OMX_ErrorNone)
2705 m_port_def = *portDefn;
2706 break;
2707 }
2708 case OMX_IndexParamVideoInit: {
2709 OMX_PORT_PARAM_TYPE *portParamType =
2710 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002711 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002712
Arun Menon906de572013-06-18 17:01:40 -07002713 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2714 portParamType->nSize = sizeof(portParamType);
2715 portParamType->nPorts = 2;
2716 portParamType->nStartPortNumber = 0;
2717 break;
2718 }
2719 case OMX_IndexParamVideoPortFormat: {
2720 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2721 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002722 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002723
Arun Menon906de572013-06-18 17:01:40 -07002724 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2725 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002726
Arun Menon906de572013-06-18 17:01:40 -07002727 if (0 == portFmt->nPortIndex) {
2728 if (0 == portFmt->nIndex) {
2729 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2730 portFmt->eCompressionFormat = eCompressionFormat;
2731 } else {
2732 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002733 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002734 eRet = OMX_ErrorNoMore;
2735 }
2736 } else if (1 == portFmt->nPortIndex) {
2737 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002738
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002739 // Distinguish non-surface mode from normal playback use-case based on
2740 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2741 // For non-android, use the default list
2742 bool useNonSurfaceMode = false;
2743#if _ANDROID_
2744 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
2745#endif
2746 portFmt->eColorFormat = useNonSurfaceMode ?
2747 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
2748 getPreferredColorFormatDefaultMode(portFmt->nIndex);
2749
2750 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
Praveen Chavandb7776f2014-02-06 18:17:25 -08002751 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002752 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002753 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002754 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002755 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002756 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002757 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002758 (int)portFmt->nPortIndex);
2759 eRet = OMX_ErrorBadPortIndex;
2760 }
2761 break;
2762 }
2763 /*Component should support this port definition*/
2764 case OMX_IndexParamAudioInit: {
2765 OMX_PORT_PARAM_TYPE *audioPortParamType =
2766 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002767 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002768 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2769 audioPortParamType->nSize = sizeof(audioPortParamType);
2770 audioPortParamType->nPorts = 0;
2771 audioPortParamType->nStartPortNumber = 0;
2772 break;
2773 }
2774 /*Component should support this port definition*/
2775 case OMX_IndexParamImageInit: {
2776 OMX_PORT_PARAM_TYPE *imagePortParamType =
2777 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002778 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002779 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2780 imagePortParamType->nSize = sizeof(imagePortParamType);
2781 imagePortParamType->nPorts = 0;
2782 imagePortParamType->nStartPortNumber = 0;
2783 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784
Arun Menon906de572013-06-18 17:01:40 -07002785 }
2786 /*Component should support this port definition*/
2787 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002788 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002789 paramIndex);
2790 eRet =OMX_ErrorUnsupportedIndex;
2791 break;
2792 }
2793 case OMX_IndexParamStandardComponentRole: {
2794 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2795 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2796 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2797 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002799 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002800 paramIndex);
2801 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2802 OMX_MAX_STRINGNAME_SIZE);
2803 break;
2804 }
2805 /* Added for parameter test */
2806 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002807
Arun Menon906de572013-06-18 17:01:40 -07002808 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2809 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002810 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002811 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2812 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813
Arun Menon906de572013-06-18 17:01:40 -07002814 break;
2815 }
2816 /* Added for parameter test */
2817 case OMX_IndexParamCompBufferSupplier: {
2818 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2819 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002820 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002821
Arun Menon906de572013-06-18 17:01:40 -07002822 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2823 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2824 if (0 == bufferSupplierType->nPortIndex)
2825 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2826 else if (1 == bufferSupplierType->nPortIndex)
2827 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2828 else
2829 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002830
2831
Arun Menon906de572013-06-18 17:01:40 -07002832 break;
2833 }
2834 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002835 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002836 paramIndex);
2837 break;
2838 }
2839 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002840 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002841 paramIndex);
2842 break;
2843 }
2844 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002845 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002846 paramIndex);
2847 break;
2848 }
2849 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002850 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002851 paramIndex);
2852 break;
2853 }
2854 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002855 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002856 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2857 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2858 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2859 break;
2860 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002861#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002862 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002863 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002864 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2865 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002866
Arun Menon906de572013-06-18 17:01:40 -07002867 if (secure_mode) {
2868 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2869 GRALLOC_USAGE_PRIVATE_UNCACHED);
2870 } else {
2871 nativeBuffersUsage->nUsage =
2872 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2873 GRALLOC_USAGE_PRIVATE_UNCACHED);
2874 }
2875 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002876 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002877 eRet = OMX_ErrorBadParameter;
2878 }
2879 }
2880 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002881#endif
2882
Arun Menon906de572013-06-18 17:01:40 -07002883 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002884 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002885 eRet =OMX_ErrorUnsupportedIndex;
2886 }
2887
Shalaj Jain273b3e02012-06-22 19:08:03 -07002888 }
2889
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002890 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002891 drv_ctx.video_resolution.frame_width,
2892 drv_ctx.video_resolution.frame_height,
2893 drv_ctx.video_resolution.stride,
2894 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002895
Arun Menon906de572013-06-18 17:01:40 -07002896 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002897}
2898
2899#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2900OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2901{
2902 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2903 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2904 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2905
Arun Menon906de572013-06-18 17:01:40 -07002906 if ((params == NULL) ||
2907 (params->nativeBuffer == NULL) ||
2908 (params->nativeBuffer->handle == NULL) ||
2909 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002910 return OMX_ErrorBadParameter;
2911 m_use_android_native_buffers = OMX_TRUE;
2912 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2913 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002914 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 -07002915 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002916 if (!secure_mode) {
2917 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002918 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002919 if (buffer == MAP_FAILED) {
2920 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2921 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002922 }
2923 }
2924 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2925 } else {
2926 eRet = OMX_ErrorBadParameter;
2927 }
2928 return eRet;
2929}
2930#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002931
2932OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2933 struct v4l2_control control;
2934 struct v4l2_format fmt;
2935 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2936 control.value = 1;
2937 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2938 if (rc < 0) {
2939 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2940 return OMX_ErrorHardware;
2941 }
2942 m_smoothstreaming_mode = true;
2943 return OMX_ErrorNone;
2944}
2945
Shalaj Jain273b3e02012-06-22 19:08:03 -07002946/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002947 FUNCTION
2948 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002949
Arun Menon906de572013-06-18 17:01:40 -07002950 DESCRIPTION
2951 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002952
Arun Menon906de572013-06-18 17:01:40 -07002953 PARAMETERS
2954 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002955
Arun Menon906de572013-06-18 17:01:40 -07002956 RETURN VALUE
2957 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002958
Arun Menon906de572013-06-18 17:01:40 -07002959 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002960OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002961 OMX_IN OMX_INDEXTYPE paramIndex,
2962 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002963{
2964 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002965 int ret=0;
2966 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002967 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002968 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002969 return OMX_ErrorInvalidState;
2970 }
Arun Menon906de572013-06-18 17:01:40 -07002971 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002972 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002973 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002974 }
Arun Menon906de572013-06-18 17:01:40 -07002975 if ((m_state != OMX_StateLoaded) &&
2976 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2977 (m_out_bEnabled == OMX_TRUE) &&
2978 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2979 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002980 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002981 return OMX_ErrorIncorrectStateOperation;
2982 }
Arun Menon906de572013-06-18 17:01:40 -07002983 switch ((unsigned long)paramIndex) {
2984 case OMX_IndexParamPortDefinition: {
2985 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2986 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2987 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2988 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002989 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002990 (int)portDefn->format.video.nFrameHeight,
2991 (int)portDefn->format.video.nFrameWidth);
2992 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002993 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Pushkaraj Patil41588352014-02-25 20:51:34 +05302994 bool port_format_changed = false;
Arun Menon906de572013-06-18 17:01:40 -07002995 m_display_id = portDefn->format.video.pNativeWindow;
2996 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002997 /* update output port resolution with client supplied dimensions
2998 in case scaling is enabled, else it follows input resolution set
2999 */
3000 if (is_down_scalar_enabled) {
3001 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003002 portDefn->format.video.nFrameWidth,
3003 portDefn->format.video.nFrameHeight);
3004 if (portDefn->format.video.nFrameHeight != 0x0 &&
3005 portDefn->format.video.nFrameWidth != 0x0) {
Pushkaraj Patil41588352014-02-25 20:51:34 +05303006 memset(&fmt, 0x0, sizeof(struct v4l2_format));
3007 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3008 fmt.fmt.pix_mp.pixelformat = capture_capability;
3009 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
3010 if (ret) {
3011 DEBUG_PRINT_ERROR("Get Resolution failed");
3012 eRet = OMX_ErrorHardware;
3013 break;
3014 }
3015 if ((portDefn->format.video.nFrameHeight != (int)fmt.fmt.pix_mp.height) ||
3016 (portDefn->format.video.nFrameWidth != (int)fmt.fmt.pix_mp.width)) {
3017 port_format_changed = true;
3018 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003019 update_resolution(portDefn->format.video.nFrameWidth,
3020 portDefn->format.video.nFrameHeight,
3021 portDefn->format.video.nFrameWidth,
3022 portDefn->format.video.nFrameHeight);
Pushkaraj Patil41588352014-02-25 20:51:34 +05303023
3024 /* set crop info */
3025 rectangle.nLeft = 0;
3026 rectangle.nTop = 0;
3027 rectangle.nWidth = portDefn->format.video.nFrameWidth;
3028 rectangle.nHeight = portDefn->format.video.nFrameHeight;
3029
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003030 eRet = is_video_session_supported();
3031 if (eRet)
3032 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303033 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003034 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3035 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3036 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3037 fmt.fmt.pix_mp.pixelformat = capture_capability;
3038 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);
3039 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3040 if (ret) {
3041 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3042 eRet = OMX_ErrorUnsupportedSetting;
3043 } else
3044 eRet = get_buffer_req(&drv_ctx.op_buf);
3045 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003046 }
Arun Menon906de572013-06-18 17:01:40 -07003047 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003048 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003049 eRet = OMX_ErrorBadParameter;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303050 } else if (!port_format_changed) {
Arun Menon906de572013-06-18 17:01:40 -07003051 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3052 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3053 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3054 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3055 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3056 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3057 drv_ctx.extradata_info.buffer_size;
3058 eRet = set_buffer_req(&drv_ctx.op_buf);
3059 if (eRet == OMX_ErrorNone)
3060 m_port_def = *portDefn;
3061 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003062 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003063 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3064 portDefn->nBufferCountActual, portDefn->nBufferSize);
3065 eRet = OMX_ErrorBadParameter;
3066 }
3067 }
3068 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003069 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003070 bool port_format_changed = false;
3071 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3072 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3073 // Frame rate only should be set if this is a "known value" or to
3074 // activate ts prediction logic (arbitrary mode only) sending input
3075 // timestamps with max value (LLONG_MAX).
3076 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3077 portDefn->format.video.xFramerate >> 16);
3078 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3079 drv_ctx.frame_rate.fps_denominator);
3080 if (!drv_ctx.frame_rate.fps_numerator) {
3081 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3082 drv_ctx.frame_rate.fps_numerator = 30;
3083 }
3084 if (drv_ctx.frame_rate.fps_denominator)
3085 drv_ctx.frame_rate.fps_numerator = (int)
3086 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3087 drv_ctx.frame_rate.fps_denominator = 1;
3088 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3089 drv_ctx.frame_rate.fps_numerator;
3090 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3091 frm_int, drv_ctx.frame_rate.fps_numerator /
3092 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003093
3094 struct v4l2_outputparm oparm;
3095 /*XXX: we're providing timing info as seconds per frame rather than frames
3096 * per second.*/
3097 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3098 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3099
3100 struct v4l2_streamparm sparm;
3101 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3102 sparm.parm.output = oparm;
3103 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3104 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3105 eRet = OMX_ErrorHardware;
3106 break;
3107 }
Arun Menon906de572013-06-18 17:01:40 -07003108 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003109
Arun Menon906de572013-06-18 17:01:40 -07003110 if (drv_ctx.video_resolution.frame_height !=
3111 portDefn->format.video.nFrameHeight ||
3112 drv_ctx.video_resolution.frame_width !=
3113 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003114 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003115 portDefn->format.video.nFrameWidth,
3116 portDefn->format.video.nFrameHeight);
3117 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003118 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3119 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3120 if (frameHeight != 0x0 && frameWidth != 0x0) {
3121 if (m_smoothstreaming_mode &&
3122 ((frameWidth * frameHeight) <
3123 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3124 frameWidth = m_smoothstreaming_width;
3125 frameHeight = m_smoothstreaming_height;
3126 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3127 frameWidth, frameHeight);
3128 }
3129 update_resolution(frameWidth, frameHeight,
3130 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003131 eRet = is_video_session_supported();
3132 if (eRet)
3133 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303134 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07003135 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3136 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3137 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3138 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003139 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 -07003140 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3141 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003142 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003143 eRet = OMX_ErrorUnsupportedSetting;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303144 } else {
3145 if (!is_down_scalar_enabled)
3146 eRet = get_buffer_req(&drv_ctx.op_buf);
3147 }
Arun Menon906de572013-06-18 17:01:40 -07003148 }
3149 }
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303150 if (m_custom_buffersize.input_buffersize
3151 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
3152 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
3153 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
3154 eRet = OMX_ErrorBadParameter;
3155 break;
3156 }
Arun Menon906de572013-06-18 17:01:40 -07003157 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3158 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3159 port_format_changed = true;
3160 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3161 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3162 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3163 (~(buffer_prop->alignment - 1));
3164 eRet = set_buffer_req(buffer_prop);
3165 }
3166 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003167 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003168 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3169 portDefn->nBufferCountActual, portDefn->nBufferSize);
3170 eRet = OMX_ErrorBadParameter;
3171 }
3172 } else if (portDefn->eDir == OMX_DirMax) {
3173 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3174 (int)portDefn->nPortIndex);
3175 eRet = OMX_ErrorBadPortIndex;
3176 }
3177 }
3178 break;
3179 case OMX_IndexParamVideoPortFormat: {
3180 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3181 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3182 int ret=0;
3183 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003184 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003185 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003186
Arun Menon906de572013-06-18 17:01:40 -07003187 if (1 == portFmt->nPortIndex) {
3188 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3189 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3190 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3191 fmt.fmt.pix_mp.pixelformat = capture_capability;
3192 enum vdec_output_fromat op_format;
3193 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3194 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003195 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3196 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003197 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003198 else
3199 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003200
Arun Menon906de572013-06-18 17:01:40 -07003201 if (eRet == OMX_ErrorNone) {
3202 drv_ctx.output_format = op_format;
3203 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3204 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003205 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003206 eRet = OMX_ErrorUnsupportedSetting;
3207 /*TODO: How to handle this case */
3208 } else {
3209 eRet = get_buffer_req(&drv_ctx.op_buf);
3210 }
3211 }
3212 if (eRet == OMX_ErrorNone) {
3213 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003214 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003215 eRet = OMX_ErrorBadParameter;
3216 }
3217 }
3218 }
3219 }
3220 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003221
Arun Menon906de572013-06-18 17:01:40 -07003222 case OMX_QcomIndexPortDefn: {
3223 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3224 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003225 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003226 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003227
Arun Menon906de572013-06-18 17:01:40 -07003228 /* Input port */
3229 if (portFmt->nPortIndex == 0) {
3230 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3231 if (secure_mode) {
3232 arbitrary_bytes = false;
3233 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3234 eRet = OMX_ErrorUnsupportedSetting;
3235 } else {
3236 arbitrary_bytes = true;
3237 }
3238 } else if (portFmt->nFramePackingFormat ==
3239 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3240 arbitrary_bytes = false;
3241 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003242 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003243 portFmt->nFramePackingFormat);
3244 eRet = OMX_ErrorUnsupportedSetting;
3245 }
3246 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003247 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003248 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3249 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3250 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3251 m_out_mem_region_smi = OMX_TRUE;
3252 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003253 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003254 m_use_output_pmem = OMX_TRUE;
3255 }
3256 }
3257 }
3258 }
3259 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003260
Arun Menon906de572013-06-18 17:01:40 -07003261 case OMX_IndexParamStandardComponentRole: {
3262 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3263 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003264 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003265 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003266
Arun Menon906de572013-06-18 17:01:40 -07003267 if ((m_state == OMX_StateLoaded)&&
3268 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3269 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3270 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003271 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003272 return OMX_ErrorIncorrectStateOperation;
3273 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003274
Arun Menon906de572013-06-18 17:01:40 -07003275 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3276 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3277 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3278 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003279 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003280 eRet =OMX_ErrorUnsupportedSetting;
3281 }
3282 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3283 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3284 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3285 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003286 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003287 eRet = OMX_ErrorUnsupportedSetting;
3288 }
3289 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3290 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3291 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3292 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003293 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003294 eRet =OMX_ErrorUnsupportedSetting;
3295 }
3296 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3297 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3298 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3299 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003300 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003301 eRet = OMX_ErrorUnsupportedSetting;
3302 }
3303 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3304 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3305 ) {
3306 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3307 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3308 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003309 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003310 eRet =OMX_ErrorUnsupportedSetting;
3311 }
3312 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3313 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3314 ) {
3315 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3316 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3317 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003318 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003319 eRet =OMX_ErrorUnsupportedSetting;
3320 }
3321 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3322 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3323 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3324 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3325 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003326 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003327 eRet = OMX_ErrorUnsupportedSetting;
3328 }
3329 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003330 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003331 eRet = OMX_ErrorInvalidComponentName;
3332 }
3333 break;
3334 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003335
Arun Menon906de572013-06-18 17:01:40 -07003336 case OMX_IndexParamPriorityMgmt: {
3337 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003338 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003339 return OMX_ErrorIncorrectStateOperation;
3340 }
3341 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003342 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003343 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003344
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003345 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003346 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003347
Arun Menon906de572013-06-18 17:01:40 -07003348 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3349 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003350
Arun Menon906de572013-06-18 17:01:40 -07003351 break;
3352 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003353
Arun Menon906de572013-06-18 17:01:40 -07003354 case OMX_IndexParamCompBufferSupplier: {
3355 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003356 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003357 bufferSupplierType->eBufferSupplier);
3358 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3359 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003360
Arun Menon906de572013-06-18 17:01:40 -07003361 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003362
Arun Menon906de572013-06-18 17:01:40 -07003363 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003364
Arun Menon906de572013-06-18 17:01:40 -07003365 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003366
Arun Menon906de572013-06-18 17:01:40 -07003367 }
3368 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003369 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003370 paramIndex);
3371 break;
3372 }
3373 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003374 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003375 paramIndex);
3376 break;
3377 }
3378 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003379 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003380 paramIndex);
3381 break;
3382 }
3383 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003384 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003385 paramIndex);
3386 break;
3387 }
3388 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3389 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3390 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3391 struct v4l2_control control;
3392 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003393 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003394 pictureOrder->eOutputPictureOrder);
3395 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3396 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3397 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3398 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3399 time_stamp_dts.set_timestamp_reorder_mode(false);
3400 } else
3401 eRet = OMX_ErrorBadParameter;
3402 if (eRet == OMX_ErrorNone) {
3403 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3404 control.value = pic_order;
3405 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3406 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003407 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003408 eRet = OMX_ErrorUnsupportedSetting;
3409 }
3410 }
3411 break;
3412 }
3413 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303414 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3415 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3416 break;
3417 case OMX_QcomIndexParamFrameInfoExtraData:
3418 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3419 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3420 break;
Arun Menon906de572013-06-18 17:01:40 -07003421 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303422 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3423 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3424 break;
Arun Menon906de572013-06-18 17:01:40 -07003425 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303426 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3427 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3428 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303429 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303430 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3431 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3432 break;
3433 case OMX_QcomIndexParamVideoQPExtraData:
3434 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3435 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3436 break;
3437 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3438 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3439 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3440 break;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05303441 case OMX_QcomIndexEnableExtnUserData:
3442 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
3443 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3444 break;
Arun Menon906de572013-06-18 17:01:40 -07003445 case OMX_QcomIndexParamVideoDivx: {
3446 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3447 }
3448 break;
3449 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003450 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003451 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3452 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3453 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3454 eRet = OMX_ErrorUnsupportedSetting;
3455 } else {
3456 m_out_pvt_entry_pmem = OMX_TRUE;
3457 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003458 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003459 m_use_output_pmem = OMX_TRUE;
3460 }
3461 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003462
Arun Menon906de572013-06-18 17:01:40 -07003463 }
3464 break;
3465 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3466 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3467 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3468 struct v4l2_control control;
3469 int rc;
3470 drv_ctx.idr_only_decoding = 1;
3471 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3472 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3473 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3474 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003475 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003476 eRet = OMX_ErrorUnsupportedSetting;
3477 } else {
3478 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3479 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3480 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3481 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003482 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003483 eRet = OMX_ErrorUnsupportedSetting;
3484 }
3485 /*Setting sync frame decoding on driver might change buffer
3486 * requirements so update them here*/
3487 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003488 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003489 eRet = OMX_ErrorUnsupportedSetting;
3490 }
3491 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003492 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003493 eRet = OMX_ErrorUnsupportedSetting;
3494 }
3495 }
3496 }
3497 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003498
Arun Menon906de572013-06-18 17:01:40 -07003499 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303500 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3501 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3502 (extradataIndexType->bEnabled == OMX_TRUE) &&
3503 (extradataIndexType->nPortIndex == 1)) {
3504 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3505 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3506 }
3507 }
Arun Menon906de572013-06-18 17:01:40 -07003508 break;
3509 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003510#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003511 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003512#else
Arun Menon906de572013-06-18 17:01:40 -07003513 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003514#endif
Arun Menon906de572013-06-18 17:01:40 -07003515 }
3516 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003517#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003518 /* Need to allow following two set_parameters even in Idle
3519 * state. This is ANDROID architecture which is not in sync
3520 * with openmax standard. */
3521 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3522 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3523 if (enableNativeBuffers) {
3524 m_enable_android_native_buffers = enableNativeBuffers->enable;
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003525 }
3526 if (m_enable_android_native_buffers) {
3527 // Use the most-preferred-native-color-format as surface-mode is hinted here
3528 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
3529 DEBUG_PRINT_ERROR("Failed to set native color format!");
3530 eRet = OMX_ErrorUnsupportedSetting;
3531 }
Arun Menon906de572013-06-18 17:01:40 -07003532 }
3533 }
3534 break;
3535 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3536 eRet = use_android_native_buffer(hComp, paramData);
3537 }
3538 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003539#endif
Arun Menon906de572013-06-18 17:01:40 -07003540 case OMX_QcomIndexParamEnableTimeStampReorder: {
3541 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3542 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3543 if (reorder->bEnable == OMX_TRUE) {
3544 frm_int =0;
3545 time_stamp_dts.set_timestamp_reorder_mode(true);
3546 } else
3547 time_stamp_dts.set_timestamp_reorder_mode(false);
3548 } else {
3549 time_stamp_dts.set_timestamp_reorder_mode(false);
3550 if (reorder->bEnable == OMX_TRUE) {
3551 eRet = OMX_ErrorUnsupportedSetting;
3552 }
3553 }
3554 }
3555 break;
3556 case OMX_IndexParamVideoProfileLevelCurrent: {
3557 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3558 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3559 if (pParam) {
3560 m_profile_lvl.eProfile = pParam->eProfile;
3561 m_profile_lvl.eLevel = pParam->eLevel;
3562 }
3563 break;
Arun Menon888aa852013-05-30 11:24:42 -07003564
Arun Menon906de572013-06-18 17:01:40 -07003565 }
Arun Menone5652482013-08-04 13:33:05 -07003566 case OMX_QcomIndexParamVideoMetaBufferMode:
3567 {
3568 StoreMetaDataInBuffersParams *metabuffer =
3569 (StoreMetaDataInBuffersParams *)paramData;
3570 if (!metabuffer) {
3571 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3572 eRet = OMX_ErrorBadParameter;
3573 break;
3574 }
3575 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3576 //set property dynamic buffer mode to driver.
3577 struct v4l2_control control;
3578 struct v4l2_format fmt;
3579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3580 if (metabuffer->bStoreMetaData == true) {
3581 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3582 } else {
3583 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3584 }
3585 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3586 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003587 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003588 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003589 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003590 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003591 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003592 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3593 eRet = OMX_ErrorUnsupportedSetting;
3594 }
3595 } else {
3596 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003597 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003598 metabuffer->nPortIndex);
3599 eRet = OMX_ErrorUnsupportedSetting;
3600 }
3601 break;
3602 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003603 case OMX_QcomIndexParamVideoDownScalar: {
3604 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3605 struct v4l2_control control;
3606 int rc;
3607 if (pParam) {
3608 is_down_scalar_enabled = pParam->bEnable;
3609 if (is_down_scalar_enabled) {
3610 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3611 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3612 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3613 pParam->bEnable);
3614 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3615 if (rc < 0) {
3616 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3617 eRet = OMX_ErrorUnsupportedSetting;
3618 }
3619 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3620 control.value = 1;
3621 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3622 if (rc < 0) {
3623 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3624 eRet = OMX_ErrorUnsupportedSetting;
3625 }
3626 }
3627 }
3628 break;
3629 }
Praveen Chavancf924182013-12-06 23:16:23 -08003630#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3631 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3632 {
3633 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3634 PrepareForAdaptivePlaybackParams* pParams =
3635 (PrepareForAdaptivePlaybackParams *) paramData;
3636 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3637 if (!pParams->bEnable) {
3638 return OMX_ErrorNone;
3639 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303640 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3641 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003642 DEBUG_PRINT_ERROR(
3643 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3644 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303645 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003646 eRet = OMX_ErrorBadParameter;
3647 } else {
Arun Menon1fc764f2014-04-17 15:41:27 -07003648 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3649 }
Praveen Chavancf924182013-12-06 23:16:23 -08003650 } else {
3651 DEBUG_PRINT_ERROR(
3652 "Prepare for adaptive playback supported only on output port");
3653 eRet = OMX_ErrorBadParameter;
3654 }
3655 break;
3656 }
3657
3658#endif
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303659 case OMX_QcomIndexParamVideoCustomBufferSize:
3660 {
3661 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
3662 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
3663 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3664 struct v4l2_control control;
3665 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
3666 control.value = pParam->nBufferSize;
3667 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
3668 DEBUG_PRINT_ERROR("Failed to set input buffer size");
3669 eRet = OMX_ErrorUnsupportedSetting;
3670 } else {
3671 eRet = get_buffer_req(&drv_ctx.ip_buf);
3672 if (eRet == OMX_ErrorNone) {
3673 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
3674 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
3675 m_custom_buffersize.input_buffersize);
3676 } else {
3677 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
3678 }
3679 }
3680 } else {
3681 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
3682 eRet = OMX_ErrorBadParameter;
3683 }
3684 break;
3685 }
Arun Menon906de572013-06-18 17:01:40 -07003686 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003687 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003688 eRet = OMX_ErrorUnsupportedIndex;
3689 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003690 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003691 if (eRet != OMX_ErrorNone)
3692 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003693 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003694}
3695
3696/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003697 FUNCTION
3698 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003699
Arun Menon906de572013-06-18 17:01:40 -07003700 DESCRIPTION
3701 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003702
Arun Menon906de572013-06-18 17:01:40 -07003703 PARAMETERS
3704 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003705
Arun Menon906de572013-06-18 17:01:40 -07003706 RETURN VALUE
3707 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003708
Arun Menon906de572013-06-18 17:01:40 -07003709 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003710OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003711 OMX_IN OMX_INDEXTYPE configIndex,
3712 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003713{
Arun Menon906de572013-06-18 17:01:40 -07003714 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003715
Arun Menon906de572013-06-18 17:01:40 -07003716 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003717 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003718 return OMX_ErrorInvalidState;
3719 }
Arun Menon906de572013-06-18 17:01:40 -07003720
3721 switch ((unsigned long)configIndex) {
3722 case OMX_QcomIndexConfigInterlaced: {
3723 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3724 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3725 if (configFmt->nPortIndex == 1) {
3726 if (configFmt->nIndex == 0) {
3727 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3728 } else if (configFmt->nIndex == 1) {
3729 configFmt->eInterlaceType =
3730 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3731 } else if (configFmt->nIndex == 2) {
3732 configFmt->eInterlaceType =
3733 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3734 } else {
3735 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003736 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003737 eRet = OMX_ErrorNoMore;
3738 }
3739
3740 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003741 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003742 (int)configFmt->nPortIndex);
3743 eRet = OMX_ErrorBadPortIndex;
3744 }
3745 break;
3746 }
3747 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3748 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3749 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3750 decoderinstances->nNumOfInstances = 16;
3751 /*TODO: How to handle this case */
3752 break;
3753 }
3754 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3755 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3756 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3757 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303758 memcpy(configFmt, &m_frame_pack_arrangement,
3759 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003760 } else {
3761 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3762 }
3763 break;
3764 }
3765 case OMX_IndexConfigCommonOutputCrop: {
3766 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3767 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3768 break;
3769 }
3770 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003771 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003772 eRet = OMX_ErrorBadParameter;
3773 }
3774
Shalaj Jain273b3e02012-06-22 19:08:03 -07003775 }
Arun Menon906de572013-06-18 17:01:40 -07003776
3777 return eRet;
3778}
3779
3780/* ======================================================================
3781 FUNCTION
3782 omx_vdec::SetConfig
3783
3784 DESCRIPTION
3785 OMX Set Config method implementation
3786
3787 PARAMETERS
3788 <TBD>.
3789
3790 RETURN VALUE
3791 OMX Error None if successful.
3792 ========================================================================== */
3793OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3794 OMX_IN OMX_INDEXTYPE configIndex,
3795 OMX_IN OMX_PTR configData)
3796{
3797 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003798 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003799 return OMX_ErrorInvalidState;
3800 }
3801
3802 OMX_ERRORTYPE ret = OMX_ErrorNone;
3803 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3804
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003805 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003806
3807 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3808 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003809 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003810 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003811 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003812 OMX_U32 extra_size;
3813 // Parsing done here for the AVC atom is definitely not generic
3814 // Currently this piece of code is working, but certainly
3815 // not tested with all .mp4 files.
3816 // Incase of failure, we might need to revisit this
3817 // for a generic piece of code.
3818
3819 // Retrieve size of NAL length field
3820 // byte #4 contains the size of NAL lenght field
3821 nal_length = (config->pData[4] & 0x03) + 1;
3822
3823 extra_size = 0;
3824 if (nal_length > 2) {
3825 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3826 extra_size = (nal_length - 2) * 2;
3827 }
3828
3829 // SPS starts from byte #6
3830 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3831 OMX_U8 *pDestBuf;
3832 m_vendor_config.nPortIndex = config->nPortIndex;
3833
3834 // minus 6 --> SPS starts from byte #6
3835 // minus 1 --> picture param set byte to be ignored from avcatom
3836 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3837 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3838 OMX_U32 len;
3839 OMX_U8 index = 0;
3840 // case where SPS+PPS is sent as part of set_config
3841 pDestBuf = m_vendor_config.pData;
3842
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003843 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003844 m_vendor_config.nPortIndex,
3845 m_vendor_config.nDataSize,
3846 m_vendor_config.pData);
3847 while (index < 2) {
3848 uint8 *psize;
3849 len = *pSrcBuf;
3850 len = len << 8;
3851 len |= *(pSrcBuf + 1);
3852 psize = (uint8 *) & len;
3853 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3854 for (unsigned int i = 0; i < nal_length; i++) {
3855 pDestBuf[i] = psize[nal_length - 1 - i];
3856 }
3857 //memcpy(pDestBuf,pSrcBuf,(len+2));
3858 pDestBuf += len + nal_length;
3859 pSrcBuf += len + 2;
3860 index++;
3861 pSrcBuf++; // skip picture param set
3862 len = 0;
3863 }
3864 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3865 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3866 m_vendor_config.nPortIndex = config->nPortIndex;
3867 m_vendor_config.nDataSize = config->nDataSize;
3868 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3869 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3870 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3871 if (m_vendor_config.pData) {
3872 free(m_vendor_config.pData);
3873 m_vendor_config.pData = NULL;
3874 m_vendor_config.nDataSize = 0;
3875 }
3876
3877 if (((*((OMX_U32 *) config->pData)) &
3878 VC1_SP_MP_START_CODE_MASK) ==
3879 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003880 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003881 m_vendor_config.nPortIndex = config->nPortIndex;
3882 m_vendor_config.nDataSize = config->nDataSize;
3883 m_vendor_config.pData =
3884 (OMX_U8 *) malloc(config->nDataSize);
3885 memcpy(m_vendor_config.pData, config->pData,
3886 config->nDataSize);
3887 m_vc1_profile = VC1_SP_MP_RCV;
3888 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003889 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003890 m_vendor_config.nPortIndex = config->nPortIndex;
3891 m_vendor_config.nDataSize = config->nDataSize;
3892 m_vendor_config.pData =
3893 (OMX_U8 *) malloc((config->nDataSize));
3894 memcpy(m_vendor_config.pData, config->pData,
3895 config->nDataSize);
3896 m_vc1_profile = VC1_AP;
3897 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003898 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003899 m_vendor_config.nPortIndex = config->nPortIndex;
3900 m_vendor_config.nDataSize = config->nDataSize;
3901 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3902 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3903 m_vc1_profile = VC1_SP_MP_RCV;
3904 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003905 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003906 }
3907 }
3908 return ret;
3909 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3910 struct v4l2_control temp;
3911 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3912
3913 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3914 switch (pNal->nNaluBytes) {
3915 case 0:
3916 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3917 break;
3918 case 2:
3919 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3920 break;
3921 case 4:
3922 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3923 break;
3924 default:
3925 return OMX_ErrorUnsupportedSetting;
3926 }
3927
3928 if (!arbitrary_bytes) {
3929 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3930 * with start code, so only need to notify driver in frame by frame mode */
3931 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3932 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3933 return OMX_ErrorHardware;
3934 }
3935 }
3936
3937 nal_length = pNal->nNaluBytes;
3938 m_frame_parser.init_nal_length(nal_length);
3939
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003940 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003941 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303942 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003943 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303944 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003945
3946 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3947 if (config->bEnabled) {
3948 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303949 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003950 config->nFps >> 16);
3951 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3952 drv_ctx.frame_rate.fps_denominator);
3953
3954 if (!drv_ctx.frame_rate.fps_numerator) {
3955 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3956 drv_ctx.frame_rate.fps_numerator = 30;
3957 }
3958
3959 if (drv_ctx.frame_rate.fps_denominator) {
3960 drv_ctx.frame_rate.fps_numerator = (int)
3961 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3962 }
3963
3964 drv_ctx.frame_rate.fps_denominator = 1;
3965 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3966 drv_ctx.frame_rate.fps_numerator;
3967
3968 struct v4l2_outputparm oparm;
3969 /*XXX: we're providing timing info as seconds per frame rather than frames
3970 * per second.*/
3971 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3972 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3973
3974 struct v4l2_streamparm sparm;
3975 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3976 sparm.parm.output = oparm;
3977 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3978 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3979 performance might be affected");
3980 ret = OMX_ErrorHardware;
3981 }
3982 client_set_fps = true;
3983 } else {
3984 DEBUG_PRINT_ERROR("Frame rate not supported.");
3985 ret = OMX_ErrorUnsupportedSetting;
3986 }
3987 } else {
3988 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3989 client_set_fps = false;
3990 }
3991 } else {
3992 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3993 (int)config->nPortIndex);
3994 ret = OMX_ErrorBadPortIndex;
3995 }
3996
3997 return ret;
3998 }
3999
4000 return OMX_ErrorNotImplemented;
4001}
4002
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304003#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4004
Arun Menon906de572013-06-18 17:01:40 -07004005/* ======================================================================
4006 FUNCTION
4007 omx_vdec::GetExtensionIndex
4008
4009 DESCRIPTION
4010 OMX GetExtensionIndex method implementaion. <TBD>
4011
4012 PARAMETERS
4013 <TBD>.
4014
4015 RETURN VALUE
4016 OMX Error None if everything successful.
4017
4018 ========================================================================== */
4019OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4020 OMX_IN OMX_STRING paramName,
4021 OMX_OUT OMX_INDEXTYPE* indexType)
4022{
4023 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004024 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004025 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304026 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004027 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304028 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004029 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304030 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4031 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4032 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4033 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004034 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4035 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004036 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4037 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004038 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4039 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004040 }
4041#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304042 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004043 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304044 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004045 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304046 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004047 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004048 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304049 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004050 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4051 }
4052#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304053 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004054 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4055 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304056#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004057 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4058 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4059 }
4060#endif
Arun Menon906de572013-06-18 17:01:40 -07004061 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004062 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004063 return OMX_ErrorNotImplemented;
4064 }
4065 return OMX_ErrorNone;
4066}
4067
4068/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004069 FUNCTION
4070 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004071
Arun Menon906de572013-06-18 17:01:40 -07004072 DESCRIPTION
4073 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004074
Arun Menon906de572013-06-18 17:01:40 -07004075 PARAMETERS
4076 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004077
Arun Menon906de572013-06-18 17:01:40 -07004078 RETURN VALUE
4079 Error None if everything is successful.
4080 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004081OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004082 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004083{
Arun Menon906de572013-06-18 17:01:40 -07004084 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004085 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004086 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004087}
4088
4089/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004090 FUNCTION
4091 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004092
Arun Menon906de572013-06-18 17:01:40 -07004093 DESCRIPTION
4094 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004095
Arun Menon906de572013-06-18 17:01:40 -07004096 PARAMETERS
4097 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004098
Arun Menon906de572013-06-18 17:01:40 -07004099 RETURN VALUE
4100 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004101
Arun Menon906de572013-06-18 17:01:40 -07004102 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004103OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004104 OMX_IN OMX_U32 port,
4105 OMX_IN OMX_HANDLETYPE peerComponent,
4106 OMX_IN OMX_U32 peerPort,
4107 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004108{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004109 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004110 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004111}
4112
4113/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004114 FUNCTION
4115 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004116
Arun Menon906de572013-06-18 17:01:40 -07004117 DESCRIPTION
4118 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004119
Arun Menon906de572013-06-18 17:01:40 -07004120 PARAMETERS
4121 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004122
Arun Menon906de572013-06-18 17:01:40 -07004123 RETURN VALUE
4124 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004125
Arun Menon906de572013-06-18 17:01:40 -07004126 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004127OMX_ERRORTYPE omx_vdec::allocate_extradata()
4128{
4129#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004130 if (drv_ctx.extradata_info.buffer_size) {
4131 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4132 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4133 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4134 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004135 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004136 }
4137 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4138 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4139 drv_ctx.extradata_info.size, 4096,
4140 &drv_ctx.extradata_info.ion.ion_alloc_data,
4141 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4142 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004143 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004144 return OMX_ErrorInsufficientResources;
4145 }
4146 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4147 drv_ctx.extradata_info.size,
4148 PROT_READ|PROT_WRITE, MAP_SHARED,
4149 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4150 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004151 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004152 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4153 free_ion_memory(&drv_ctx.extradata_info.ion);
4154 return OMX_ErrorInsufficientResources;
4155 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004156 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004157#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304158 if (!m_other_extradata) {
4159 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4160 if (!m_other_extradata) {
4161 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4162 return OMX_ErrorInsufficientResources;
4163 }
4164 }
Arun Menon906de572013-06-18 17:01:40 -07004165 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004166}
4167
Arun Menon906de572013-06-18 17:01:40 -07004168void omx_vdec::free_extradata()
4169{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004170#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004171 if (drv_ctx.extradata_info.uaddr) {
4172 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4173 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4174 free_ion_memory(&drv_ctx.extradata_info.ion);
4175 }
4176 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004177#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304178 if (m_other_extradata) {
4179 free(m_other_extradata);
4180 m_other_extradata = NULL;
4181 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004182}
4183
Shalaj Jain273b3e02012-06-22 19:08:03 -07004184OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004185 OMX_IN OMX_HANDLETYPE hComp,
4186 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4187 OMX_IN OMX_U32 port,
4188 OMX_IN OMX_PTR appData,
4189 OMX_IN OMX_U32 bytes,
4190 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004191{
Arun Menon906de572013-06-18 17:01:40 -07004192 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4193 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4194 unsigned i= 0; // Temporary counter
4195 struct vdec_setbuffer_cmd setbuffers;
4196 OMX_PTR privateAppData = NULL;
4197 private_handle_t *handle = NULL;
4198 OMX_U8 *buff = buffer;
4199 struct v4l2_buffer buf;
4200 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4201 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004202
Arun Menon906de572013-06-18 17:01:40 -07004203 if (!m_out_mem_ptr) {
4204 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4205 eRet = allocate_output_headers();
4206 if (eRet == OMX_ErrorNone)
4207 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004208 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004209
Arun Menon906de572013-06-18 17:01:40 -07004210 if (eRet == OMX_ErrorNone) {
4211 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4212 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4213 break;
4214 }
4215 }
4216 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004217
Arun Menon906de572013-06-18 17:01:40 -07004218 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004219 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004220 eRet = OMX_ErrorInsufficientResources;
4221 }
4222
Arun Menonbdb80b02013-08-12 17:45:54 -07004223 if (dynamic_buf_mode) {
4224 *bufferHdr = (m_out_mem_ptr + i );
4225 (*bufferHdr)->pBuffer = NULL;
4226 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4227 enum v4l2_buf_type buf_type;
4228 int rr = 0;
4229 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4230 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4231 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4232 return OMX_ErrorInsufficientResources;
4233 } else {
4234 streaming[CAPTURE_PORT] = true;
4235 DEBUG_PRINT_LOW("STREAMON Successful");
4236 }
4237 }
4238 BITMASK_SET(&m_out_bm_count,i);
4239 (*bufferHdr)->pAppPrivate = appData;
4240 (*bufferHdr)->pBuffer = buffer;
4241 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4242 return eRet;
4243 }
Arun Menon906de572013-06-18 17:01:40 -07004244 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004245#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004246 if (m_enable_android_native_buffers) {
4247 if (m_use_android_native_buffers) {
4248 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4249 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4250 handle = (private_handle_t *)nBuf->handle;
4251 privateAppData = params->pAppPrivate;
4252 } else {
4253 handle = (private_handle_t *)buff;
4254 privateAppData = appData;
4255 }
Arun Menon8544ead2014-05-08 17:42:29 -07004256 if (!handle) {
4257 DEBUG_PRINT_ERROR("handle is invalid");
4258 return OMX_ErrorBadParameter;
4259 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004260
Arun Menon906de572013-06-18 17:01:40 -07004261 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4262 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4263 " expected %u, got %lu",
4264 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4265 return OMX_ErrorBadParameter;
4266 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004267
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004268 drv_ctx.op_buf.buffer_size = handle->size;
4269
Arun Menon906de572013-06-18 17:01:40 -07004270 if (!m_use_android_native_buffers) {
4271 if (!secure_mode) {
4272 buff = (OMX_U8*)mmap(0, handle->size,
4273 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4274 if (buff == MAP_FAILED) {
4275 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4276 return OMX_ErrorInsufficientResources;
4277 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004278 }
4279 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004280#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004281 native_buffer[i].nativehandle = handle;
4282 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004283#endif
Arun Menon906de572013-06-18 17:01:40 -07004284 if (!handle) {
4285 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4286 return OMX_ErrorBadParameter;
4287 }
4288 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4289 drv_ctx.ptr_outputbuffer[i].offset = 0;
4290 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4291 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4292 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4293 } else
4294#endif
4295
4296 if (!ouput_egl_buffers && !m_use_output_pmem) {
4297#ifdef USE_ION
4298 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4299 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4300 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4301 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4302 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004303 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 -07004304 return OMX_ErrorInsufficientResources;
4305 }
4306 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4307 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4308#else
4309 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4310 open (MEM_DEVICE,O_RDWR);
4311
4312 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004313 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004314 return OMX_ErrorInsufficientResources;
4315 }
4316
4317 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4318 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4319 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4320 open (MEM_DEVICE,O_RDWR);
4321 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004322 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004323 return OMX_ErrorInsufficientResources;
4324 }
4325 }
4326
4327 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4328 drv_ctx.op_buf.buffer_size,
4329 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004330 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004331 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4332 return OMX_ErrorInsufficientResources;
4333 }
4334#endif
4335 if (!secure_mode) {
4336 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4337 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4338 PROT_READ|PROT_WRITE, MAP_SHARED,
4339 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4340 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4341 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4342#ifdef USE_ION
4343 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4344#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004345 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004346 return OMX_ErrorInsufficientResources;
4347 }
4348 }
4349 drv_ctx.ptr_outputbuffer[i].offset = 0;
4350 privateAppData = appData;
4351 } else {
4352
4353 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4354 if (!appData || !bytes ) {
4355 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004356 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004357 return OMX_ErrorBadParameter;
4358 }
4359 }
4360
4361 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4362 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4363 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004364 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004365 !pmem_list->nEntries ||
4366 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004367 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004368 return OMX_ErrorBadParameter;
4369 }
4370 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4371 pmem_list->entryList->entry;
4372 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4373 pmem_info->pmem_fd);
4374 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4375 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4376 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4377 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4378 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4379 privateAppData = appData;
4380 }
4381 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4382 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304383 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4384 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4385 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004386
4387 *bufferHdr = (m_out_mem_ptr + i );
4388 if (secure_mode)
4389 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4390 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4391 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4392 sizeof (vdec_bufferpayload));
4393
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004394 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004395 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4396 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4397
4398 buf.index = i;
4399 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4400 buf.memory = V4L2_MEMORY_USERPTR;
4401 plane[0].length = drv_ctx.op_buf.buffer_size;
4402 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4403 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4404 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4405 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4406 plane[0].data_offset = 0;
4407 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4408 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4409 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4410 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4411#ifdef USE_ION
4412 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4413#endif
4414 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4415 plane[extra_idx].data_offset = 0;
4416 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004417 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004418 return OMX_ErrorBadParameter;
4419 }
Arun Menon906de572013-06-18 17:01:40 -07004420 buf.m.planes = plane;
4421 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004422
Arun Menon906de572013-06-18 17:01:40 -07004423 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004424 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004425 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004426 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004427 }
4428
Arun Menon906de572013-06-18 17:01:40 -07004429 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4430 enum v4l2_buf_type buf_type;
4431 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4432 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4433 return OMX_ErrorInsufficientResources;
4434 } else {
4435 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004436 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004437 }
4438 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004439
Arun Menon906de572013-06-18 17:01:40 -07004440 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4441 if (m_enable_android_native_buffers) {
4442 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4443 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4444 } else {
4445 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004446 }
Arun Menon906de572013-06-18 17:01:40 -07004447 (*bufferHdr)->pAppPrivate = privateAppData;
4448 BITMASK_SET(&m_out_bm_count,i);
4449 }
4450 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004451}
4452
4453/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004454 FUNCTION
4455 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004456
Arun Menon906de572013-06-18 17:01:40 -07004457 DESCRIPTION
4458 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004459
Arun Menon906de572013-06-18 17:01:40 -07004460 PARAMETERS
4461 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004462
Arun Menon906de572013-06-18 17:01:40 -07004463 RETURN VALUE
4464 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004465
Arun Menon906de572013-06-18 17:01:40 -07004466 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004467OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004468 OMX_IN OMX_HANDLETYPE hComp,
4469 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4470 OMX_IN OMX_U32 port,
4471 OMX_IN OMX_PTR appData,
4472 OMX_IN OMX_U32 bytes,
4473 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004474{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004475 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004476 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4477 if (!m_inp_heap_ptr)
4478 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4479 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4480 drv_ctx.ip_buf.actualcount);
4481 if (!m_phdr_pmem_ptr)
4482 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4483 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4484 drv_ctx.ip_buf.actualcount);
4485 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4486 DEBUG_PRINT_ERROR("Insufficent memory");
4487 eRet = OMX_ErrorInsufficientResources;
4488 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4489 input_use_buffer = true;
4490 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4491 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4492 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4493 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4494 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4495 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4496 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4497 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004498 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 -07004499 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4500 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004501 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004502 return OMX_ErrorInsufficientResources;
4503 }
4504 m_in_alloc_cnt++;
4505 } else {
4506 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4507 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004508 }
Arun Menon906de572013-06-18 17:01:40 -07004509 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004510}
4511
4512/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004513 FUNCTION
4514 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004515
Arun Menon906de572013-06-18 17:01:40 -07004516 DESCRIPTION
4517 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004518
Arun Menon906de572013-06-18 17:01:40 -07004519 PARAMETERS
4520 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521
Arun Menon906de572013-06-18 17:01:40 -07004522 RETURN VALUE
4523 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004524
Arun Menon906de572013-06-18 17:01:40 -07004525 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004526OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004527 OMX_IN OMX_HANDLETYPE hComp,
4528 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4529 OMX_IN OMX_U32 port,
4530 OMX_IN OMX_PTR appData,
4531 OMX_IN OMX_U32 bytes,
4532 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004533{
Arun Menon906de572013-06-18 17:01:40 -07004534 OMX_ERRORTYPE error = OMX_ErrorNone;
4535 struct vdec_setbuffer_cmd setbuffers;
4536
Arun Menon8544ead2014-05-08 17:42:29 -07004537 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4538 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4539 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004540 }
Arun Menon906de572013-06-18 17:01:40 -07004541 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004542 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004543 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004544 }
Arun Menon906de572013-06-18 17:01:40 -07004545 if (port == OMX_CORE_INPUT_PORT_INDEX)
4546 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4547 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4548 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4549 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004550 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004551 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552 }
Arun Menon906de572013-06-18 17:01:40 -07004553 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4554 if (error == OMX_ErrorNone) {
4555 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4556 // Send the callback now
4557 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4558 post_event(OMX_CommandStateSet,OMX_StateIdle,
4559 OMX_COMPONENT_GENERATE_EVENT);
4560 }
4561 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4562 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4563 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4564 post_event(OMX_CommandPortEnable,
4565 OMX_CORE_INPUT_PORT_INDEX,
4566 OMX_COMPONENT_GENERATE_EVENT);
4567 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4568 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4569 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4570 post_event(OMX_CommandPortEnable,
4571 OMX_CORE_OUTPUT_PORT_INDEX,
4572 OMX_COMPONENT_GENERATE_EVENT);
4573 }
4574 }
4575 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576}
4577
4578OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004579 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580{
Arun Menon906de572013-06-18 17:01:40 -07004581 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4582 if (m_inp_heap_ptr[bufferindex].pBuffer)
4583 free(m_inp_heap_ptr[bufferindex].pBuffer);
4584 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4585 }
4586 if (pmem_bufferHdr)
4587 free_input_buffer(pmem_bufferHdr);
4588 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004589}
4590
4591OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4592{
Arun Menon906de572013-06-18 17:01:40 -07004593 unsigned int index = 0;
4594 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4595 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004596 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004597
Arun Menon906de572013-06-18 17:01:40 -07004598 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004599 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004600
4601 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004602 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004603 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4604 struct vdec_setbuffer_cmd setbuffers;
4605 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4606 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4607 sizeof (vdec_bufferpayload));
4608 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004609 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004610 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004611 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004612 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4613 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4614 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4615 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4616 }
4617 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4618 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4619 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4620 free(m_desc_buffer_ptr[index].buf_addr);
4621 m_desc_buffer_ptr[index].buf_addr = NULL;
4622 m_desc_buffer_ptr[index].desc_data_size = 0;
4623 }
4624#ifdef USE_ION
4625 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4626#endif
4627 }
4628 }
4629
4630 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004631}
4632
4633OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4634{
Arun Menon906de572013-06-18 17:01:40 -07004635 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004636
Arun Menon906de572013-06-18 17:01:40 -07004637 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4638 return OMX_ErrorBadParameter;
4639 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004640
Arun Menon906de572013-06-18 17:01:40 -07004641 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004642 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004643
Arun Menon906de572013-06-18 17:01:40 -07004644 if (index < drv_ctx.op_buf.actualcount
4645 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004646 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004647 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648
Arun Menon906de572013-06-18 17:01:40 -07004649 struct vdec_setbuffer_cmd setbuffers;
4650 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4651 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4652 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004653
4654 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004656 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004657 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004658 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4659 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4660 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4661 }
Arun Menon906de572013-06-18 17:01:40 -07004662 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004663 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4664 } else {
4665#endif
4666 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4667 if (!secure_mode) {
4668 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4669 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4670 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4671 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4672 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4673 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4674 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4675 }
4676 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4677 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004678#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004679 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004680#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004681 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004684#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004685 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004686 if (release_output_done()) {
4687 free_extradata();
4688 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004689 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004690
Arun Menon906de572013-06-18 17:01:40 -07004691 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004692
4693}
4694
4695OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004696 OMX_BUFFERHEADERTYPE **bufferHdr,
4697 OMX_U32 port,
4698 OMX_PTR appData,
4699 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004700{
Arun Menon906de572013-06-18 17:01:40 -07004701 OMX_BUFFERHEADERTYPE *input = NULL;
4702 unsigned char *buf_addr = NULL;
4703 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4704 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705
Arun Menon906de572013-06-18 17:01:40 -07004706 /* Sanity Check*/
4707 if (bufferHdr == NULL) {
4708 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004709 }
4710
Arun Menon906de572013-06-18 17:01:40 -07004711 if (m_inp_heap_ptr == NULL) {
4712 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4713 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4714 drv_ctx.ip_buf.actualcount);
4715 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4716 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4717 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004718
Arun Menon8544ead2014-05-08 17:42:29 -07004719 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4720 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004721 return OMX_ErrorInsufficientResources;
4722 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004723 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004724
Arun Menon906de572013-06-18 17:01:40 -07004725 /*Find a Free index*/
4726 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4727 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004728 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004729 break;
4730 }
4731 }
4732
4733 if (i < drv_ctx.ip_buf.actualcount) {
4734 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4735
4736 if (buf_addr == NULL) {
4737 return OMX_ErrorInsufficientResources;
4738 }
4739
4740 *bufferHdr = (m_inp_heap_ptr + i);
4741 input = *bufferHdr;
4742 BITMASK_SET(&m_heap_inp_bm_count,i);
4743
4744 input->pBuffer = (OMX_U8 *)buf_addr;
4745 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4746 input->nVersion.nVersion = OMX_SPEC_VERSION;
4747 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4748 input->pAppPrivate = appData;
4749 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004750 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004751 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004752 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004753 /*Add the Buffers to freeq*/
4754 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4755 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004756 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004757 return OMX_ErrorInsufficientResources;
4758 }
4759 } else {
4760 return OMX_ErrorBadParameter;
4761 }
4762
4763 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004764
4765}
4766
4767
4768/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004769 FUNCTION
4770 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004771
Arun Menon906de572013-06-18 17:01:40 -07004772 DESCRIPTION
4773 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004774
Arun Menon906de572013-06-18 17:01:40 -07004775 PARAMETERS
4776 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004777
Arun Menon906de572013-06-18 17:01:40 -07004778 RETURN VALUE
4779 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004780
Arun Menon906de572013-06-18 17:01:40 -07004781 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004783 OMX_IN OMX_HANDLETYPE hComp,
4784 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4785 OMX_IN OMX_U32 port,
4786 OMX_IN OMX_PTR appData,
4787 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004788{
4789
Arun Menon906de572013-06-18 17:01:40 -07004790 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4791 struct vdec_setbuffer_cmd setbuffers;
4792 OMX_BUFFERHEADERTYPE *input = NULL;
4793 unsigned i = 0;
4794 unsigned char *buf_addr = NULL;
4795 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004796
Arun Menon906de572013-06-18 17:01:40 -07004797 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004798 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004799 bytes, drv_ctx.ip_buf.buffer_size);
4800 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004801 }
4802
Arun Menon906de572013-06-18 17:01:40 -07004803 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004804 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004805 drv_ctx.ip_buf.actualcount,
4806 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004807
Arun Menon906de572013-06-18 17:01:40 -07004808 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4809 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4810
4811 if (m_inp_mem_ptr == NULL) {
4812 return OMX_ErrorInsufficientResources;
4813 }
4814
4815 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4816 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4817
4818 if (drv_ctx.ptr_inputbuffer == NULL) {
4819 return OMX_ErrorInsufficientResources;
4820 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004821#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004822 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4823 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824
Arun Menon906de572013-06-18 17:01:40 -07004825 if (drv_ctx.ip_buf_ion_info == NULL) {
4826 return OMX_ErrorInsufficientResources;
4827 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004828#endif
4829
Arun Menon906de572013-06-18 17:01:40 -07004830 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4831 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004832#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004833 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004835 }
4836 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004837
Arun Menon906de572013-06-18 17:01:40 -07004838 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4839 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004840 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004841 break;
4842 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004843 }
Arun Menon906de572013-06-18 17:01:40 -07004844
4845 if (i < drv_ctx.ip_buf.actualcount) {
4846 struct v4l2_buffer buf;
4847 struct v4l2_plane plane;
4848 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004849 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004850#ifdef USE_ION
4851 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4852 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4853 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4854 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4855 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4856 return OMX_ErrorInsufficientResources;
4857 }
4858 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4859#else
4860 pmem_fd = open (MEM_DEVICE,O_RDWR);
4861
4862 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004863 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004864 return OMX_ErrorInsufficientResources;
4865 }
4866
4867 if (pmem_fd == 0) {
4868 pmem_fd = open (MEM_DEVICE,O_RDWR);
4869
4870 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004871 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004872 return OMX_ErrorInsufficientResources;
4873 }
4874 }
4875
4876 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4877 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004878 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004879 close(pmem_fd);
4880 return OMX_ErrorInsufficientResources;
4881 }
4882#endif
4883 if (!secure_mode) {
4884 buf_addr = (unsigned char *)mmap(NULL,
4885 drv_ctx.ip_buf.buffer_size,
4886 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4887
4888 if (buf_addr == MAP_FAILED) {
4889 close(pmem_fd);
4890#ifdef USE_ION
4891 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4892#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004893 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004894 return OMX_ErrorInsufficientResources;
4895 }
4896 }
4897 *bufferHdr = (m_inp_mem_ptr + i);
4898 if (secure_mode)
4899 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4900 else
4901 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4902 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4903 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4904 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4905 drv_ctx.ptr_inputbuffer [i].offset = 0;
4906
4907
4908 buf.index = i;
4909 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4910 buf.memory = V4L2_MEMORY_USERPTR;
4911 plane.bytesused = 0;
4912 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4913 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4914 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4915 plane.reserved[1] = 0;
4916 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4917 buf.m.planes = &plane;
4918 buf.length = 1;
4919
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004920 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004921 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4922
4923 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4924
4925 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004926 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004927 /*TODO: How to handle this case */
4928 return OMX_ErrorInsufficientResources;
4929 }
4930
4931 input = *bufferHdr;
4932 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004933 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004934 if (secure_mode)
4935 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4936 else
4937 input->pBuffer = (OMX_U8 *)buf_addr;
4938 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4939 input->nVersion.nVersion = OMX_SPEC_VERSION;
4940 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4941 input->pAppPrivate = appData;
4942 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4943 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4944
4945 if (drv_ctx.disable_dmx) {
4946 eRet = allocate_desc_buffer(i);
4947 }
4948 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004949 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004950 eRet = OMX_ErrorInsufficientResources;
4951 }
4952 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004953}
4954
4955
4956/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004957 FUNCTION
4958 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959
Arun Menon906de572013-06-18 17:01:40 -07004960 DESCRIPTION
4961 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004962
Arun Menon906de572013-06-18 17:01:40 -07004963 PARAMETERS
4964 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004965
Arun Menon906de572013-06-18 17:01:40 -07004966 RETURN VALUE
4967 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004968
Arun Menon906de572013-06-18 17:01:40 -07004969 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004970OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004971 OMX_IN OMX_HANDLETYPE hComp,
4972 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4973 OMX_IN OMX_U32 port,
4974 OMX_IN OMX_PTR appData,
4975 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976{
Arun Menon906de572013-06-18 17:01:40 -07004977 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4978 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4979 unsigned i= 0; // Temporary counter
4980 struct vdec_setbuffer_cmd setbuffers;
4981 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004983 int ion_device_fd =-1;
4984 struct ion_allocation_data ion_alloc_data;
4985 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004986#endif
Arun Menon906de572013-06-18 17:01:40 -07004987 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004988 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004989 drv_ctx.op_buf.actualcount,
4990 drv_ctx.op_buf.buffer_size);
4991 int nBufHdrSize = 0;
4992 int nPlatformEntrySize = 0;
4993 int nPlatformListSize = 0;
4994 int nPMEMInfoSize = 0;
4995 int pmem_fd = -1;
4996 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004997
Arun Menon906de572013-06-18 17:01:40 -07004998 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4999 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5000 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005001
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005002 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005003 drv_ctx.op_buf.actualcount);
5004 nBufHdrSize = drv_ctx.op_buf.actualcount *
5005 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005006
Arun Menon906de572013-06-18 17:01:40 -07005007 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5008 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5009 nPlatformListSize = drv_ctx.op_buf.actualcount *
5010 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5011 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5012 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005014 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005015 sizeof(OMX_BUFFERHEADERTYPE),
5016 nPMEMInfoSize,
5017 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005018 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005019 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005020#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005021 ion_device_fd = alloc_map_ion_memory(
5022 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5023 drv_ctx.op_buf.alignment,
5024 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5025 if (ion_device_fd < 0) {
5026 return OMX_ErrorInsufficientResources;
5027 }
5028 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005029#else
Arun Menon906de572013-06-18 17:01:40 -07005030 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005031
Arun Menon906de572013-06-18 17:01:40 -07005032 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005033 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005034 drv_ctx.op_buf.buffer_size);
5035 return OMX_ErrorInsufficientResources;
5036 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005037
Arun Menon906de572013-06-18 17:01:40 -07005038 if (pmem_fd == 0) {
5039 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005040
Arun Menon906de572013-06-18 17:01:40 -07005041 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005042 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005043 drv_ctx.op_buf.buffer_size);
5044 return OMX_ErrorInsufficientResources;
5045 }
5046 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005047
Arun Menon906de572013-06-18 17:01:40 -07005048 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5049 drv_ctx.op_buf.actualcount,
5050 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005051 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005052 close(pmem_fd);
5053 return OMX_ErrorInsufficientResources;
5054 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005055#endif
Arun Menon906de572013-06-18 17:01:40 -07005056 if (!secure_mode) {
5057 pmem_baseaddress = (unsigned char *)mmap(NULL,
5058 (drv_ctx.op_buf.buffer_size *
5059 drv_ctx.op_buf.actualcount),
5060 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5061 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005062 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005063 drv_ctx.op_buf.buffer_size);
5064 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005065#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005066 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005067#endif
Arun Menon906de572013-06-18 17:01:40 -07005068 return OMX_ErrorInsufficientResources;
5069 }
5070 }
5071 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5072 // Alloc mem for platform specific info
5073 char *pPtr=NULL;
5074 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5075 nPMEMInfoSize,1);
5076 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5077 calloc (sizeof(struct vdec_bufferpayload),
5078 drv_ctx.op_buf.actualcount);
5079 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5080 calloc (sizeof (struct vdec_output_frameinfo),
5081 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005082 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5083 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5084 return OMX_ErrorInsufficientResources;
5085 }
5086
Arun Menon906de572013-06-18 17:01:40 -07005087#ifdef USE_ION
5088 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5089 calloc (sizeof(struct vdec_ion),
5090 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005091 if (!drv_ctx.op_buf_ion_info) {
5092 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5093 return OMX_ErrorInsufficientResources;
5094 }
Arun Menon906de572013-06-18 17:01:40 -07005095#endif
5096
5097 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5098 && drv_ctx.ptr_respbuffer) {
5099 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5100 (drv_ctx.op_buf.buffer_size *
5101 drv_ctx.op_buf.actualcount);
5102 bufHdr = m_out_mem_ptr;
5103 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5104 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5105 (((char *) m_platform_list) + nPlatformListSize);
5106 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5107 (((char *) m_platform_entry) + nPlatformEntrySize);
5108 pPlatformList = m_platform_list;
5109 pPlatformEntry = m_platform_entry;
5110 pPMEMInfo = m_pmem_info;
5111
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005112 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005113
5114 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005115 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5116 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005117 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5118 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5119 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5120 // Set the values when we determine the right HxW param
5121 bufHdr->nAllocLen = bytes;
5122 bufHdr->nFilledLen = 0;
5123 bufHdr->pAppPrivate = appData;
5124 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5125 // Platform specific PMEM Information
5126 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005127 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005128 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5129 pPlatformEntry->entry = pPMEMInfo;
5130 // Initialize the Platform List
5131 pPlatformList->nEntries = 1;
5132 pPlatformList->entryList = pPlatformEntry;
5133 // Keep pBuffer NULL till vdec is opened
5134 bufHdr->pBuffer = NULL;
5135 bufHdr->nOffset = 0;
5136
5137 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5138 pPMEMInfo->pmem_fd = 0;
5139 bufHdr->pPlatformPrivate = pPlatformList;
5140
5141 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5142 m_pmem_info[i].pmem_fd = pmem_fd;
5143#ifdef USE_ION
5144 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5145 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5146 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5147#endif
5148
5149 /*Create a mapping between buffers*/
5150 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5151 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5152 &drv_ctx.ptr_outputbuffer[i];
5153 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5154 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5155 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305156 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5157 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5158 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005159
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005160 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005161 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5162 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5163 // Move the buffer and buffer header pointers
5164 bufHdr++;
5165 pPMEMInfo++;
5166 pPlatformEntry++;
5167 pPlatformList++;
5168 }
5169 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005170 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005171 m_out_mem_ptr, pPtr);
5172 if (m_out_mem_ptr) {
5173 free(m_out_mem_ptr);
5174 m_out_mem_ptr = NULL;
5175 }
5176 if (pPtr) {
5177 free(pPtr);
5178 pPtr = NULL;
5179 }
5180 if (drv_ctx.ptr_outputbuffer) {
5181 free(drv_ctx.ptr_outputbuffer);
5182 drv_ctx.ptr_outputbuffer = NULL;
5183 }
5184 if (drv_ctx.ptr_respbuffer) {
5185 free(drv_ctx.ptr_respbuffer);
5186 drv_ctx.ptr_respbuffer = NULL;
5187 }
5188#ifdef USE_ION
5189 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005190 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005191 free(drv_ctx.op_buf_ion_info);
5192 drv_ctx.op_buf_ion_info = NULL;
5193 }
5194#endif
5195 eRet = OMX_ErrorInsufficientResources;
5196 }
5197 if (eRet == OMX_ErrorNone)
5198 eRet = allocate_extradata();
5199 }
5200
5201 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5202 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005203 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005204 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005205 }
5206 }
Arun Menon906de572013-06-18 17:01:40 -07005207
5208 if (eRet == OMX_ErrorNone) {
5209 if (i < drv_ctx.op_buf.actualcount) {
5210 struct v4l2_buffer buf;
5211 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5212 int rc;
5213 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5214
5215 drv_ctx.ptr_outputbuffer[i].buffer_len =
5216 drv_ctx.op_buf.buffer_size;
5217
5218 *bufferHdr = (m_out_mem_ptr + i );
5219 if (secure_mode) {
5220 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5221 }
5222 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5223
5224 buf.index = i;
5225 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5226 buf.memory = V4L2_MEMORY_USERPTR;
5227 plane[0].length = drv_ctx.op_buf.buffer_size;
5228 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5229 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005230#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005231 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005232#endif
Arun Menon906de572013-06-18 17:01:40 -07005233 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5234 plane[0].data_offset = 0;
5235 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5236 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5237 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5238 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 -07005239#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005240 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005241#endif
Arun Menon906de572013-06-18 17:01:40 -07005242 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5243 plane[extra_idx].data_offset = 0;
5244 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005245 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005246 return OMX_ErrorBadParameter;
5247 }
5248 buf.m.planes = plane;
5249 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005250 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 -07005251 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5252 if (rc) {
5253 /*TODO: How to handle this case */
5254 return OMX_ErrorInsufficientResources;
5255 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005256
Arun Menon906de572013-06-18 17:01:40 -07005257 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5258 enum v4l2_buf_type buf_type;
5259 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5260 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5261 if (rc) {
5262 return OMX_ErrorInsufficientResources;
5263 } else {
5264 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005265 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005266 }
5267 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005268
Arun Menon906de572013-06-18 17:01:40 -07005269 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5270 (*bufferHdr)->pAppPrivate = appData;
5271 BITMASK_SET(&m_out_bm_count,i);
5272 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005273 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005274 eRet = OMX_ErrorInsufficientResources;
5275 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005276 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005277
Arun Menon906de572013-06-18 17:01:40 -07005278 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005279}
5280
5281
5282// AllocateBuffer -- API Call
5283/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005284 FUNCTION
5285 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005286
Arun Menon906de572013-06-18 17:01:40 -07005287 DESCRIPTION
5288 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005289
Arun Menon906de572013-06-18 17:01:40 -07005290 PARAMETERS
5291 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005292
Arun Menon906de572013-06-18 17:01:40 -07005293 RETURN VALUE
5294 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005295
Arun Menon906de572013-06-18 17:01:40 -07005296 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005297OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005298 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5299 OMX_IN OMX_U32 port,
5300 OMX_IN OMX_PTR appData,
5301 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302{
5303 unsigned i = 0;
5304 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5305
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005306 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005307 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005308 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005309 return OMX_ErrorInvalidState;
5310 }
5311
Arun Menon906de572013-06-18 17:01:40 -07005312 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5313 if (arbitrary_bytes) {
5314 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5315 } else {
5316 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5317 }
5318 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005319 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5320 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005321 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005322 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005323 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324 }
5325 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005326 if (eRet == OMX_ErrorNone) {
5327 if (allocate_done()) {
5328 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005329 // Send the callback now
5330 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5331 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005332 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005333 }
5334 }
Arun Menon906de572013-06-18 17:01:40 -07005335 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5336 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5337 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5338 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005339 OMX_CORE_INPUT_PORT_INDEX,
5340 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005342 }
Arun Menon906de572013-06-18 17:01:40 -07005343 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5344 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5345 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005346 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005347 OMX_CORE_OUTPUT_PORT_INDEX,
5348 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005349 }
5350 }
5351 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005352 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005353 return eRet;
5354}
5355
5356// Free Buffer - API call
5357/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005358 FUNCTION
5359 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005360
Arun Menon906de572013-06-18 17:01:40 -07005361 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362
Arun Menon906de572013-06-18 17:01:40 -07005363 PARAMETERS
5364 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365
Arun Menon906de572013-06-18 17:01:40 -07005366 RETURN VALUE
5367 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005368
Arun Menon906de572013-06-18 17:01:40 -07005369 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005370OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005371 OMX_IN OMX_U32 port,
5372 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005373{
5374 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5375 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005376 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005377
Arun Menon906de572013-06-18 17:01:40 -07005378 if (m_state == OMX_StateIdle &&
5379 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005380 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005381 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5382 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005383 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005384 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5385 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5386 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5387 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005388 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005389 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005390 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005392 OMX_ErrorPortUnpopulated,
5393 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005394
5395 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005396 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005397 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005398 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005399 OMX_ErrorPortUnpopulated,
5400 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401 }
5402
Arun Menon906de572013-06-18 17:01:40 -07005403 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5404 /*Check if arbitrary bytes*/
5405 if (!arbitrary_bytes && !input_use_buffer)
5406 nPortIndex = buffer - m_inp_mem_ptr;
5407 else
5408 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005410 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005411 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5412 // Clear the bit associated with it.
5413 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5414 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5415 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005416
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005417 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005418 if (m_phdr_pmem_ptr)
5419 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5420 } else {
5421 if (arbitrary_bytes) {
5422 if (m_phdr_pmem_ptr)
5423 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5424 else
5425 free_input_buffer(nPortIndex,NULL);
5426 } else
5427 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005428 }
Arun Menon906de572013-06-18 17:01:40 -07005429 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305430 if(release_input_done())
5431 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005432 /*Free the Buffer Header*/
5433 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005434 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005435 free_input_buffer_header();
5436 }
5437 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005438 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439 eRet = OMX_ErrorBadPortIndex;
5440 }
5441
Arun Menon906de572013-06-18 17:01:40 -07005442 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5443 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005444 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005445 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5446 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005447 OMX_CORE_INPUT_PORT_INDEX,
5448 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449 }
Arun Menon906de572013-06-18 17:01:40 -07005450 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005451 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005452 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005453 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005454 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455 // Clear the bit associated with it.
5456 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5457 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005458 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005459
Surajit Podder12aefac2013-08-06 18:43:32 +05305460 if(release_output_done()) {
5461 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5462 }
Arun Menon906de572013-06-18 17:01:40 -07005463 if (release_output_done()) {
5464 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465 }
Arun Menon906de572013-06-18 17:01:40 -07005466 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005467 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468 eRet = OMX_ErrorBadPortIndex;
5469 }
Arun Menon906de572013-06-18 17:01:40 -07005470 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5471 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005472 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005473
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005474 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005475 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005477 if (m_enable_android_native_buffers) {
5478 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5479 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481#endif
5482
Arun Menon906de572013-06-18 17:01:40 -07005483 post_event(OMX_CommandPortDisable,
5484 OMX_CORE_OUTPUT_PORT_INDEX,
5485 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005486 }
Arun Menon906de572013-06-18 17:01:40 -07005487 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488 eRet = OMX_ErrorBadPortIndex;
5489 }
Arun Menon906de572013-06-18 17:01:40 -07005490 if ((eRet == OMX_ErrorNone) &&
5491 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5492 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005493 // Send the callback now
5494 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5495 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005496 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497 }
5498 }
5499 return eRet;
5500}
5501
5502
5503/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005504 FUNCTION
5505 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005506
Arun Menon906de572013-06-18 17:01:40 -07005507 DESCRIPTION
5508 This routine is used to push the encoded video frames to
5509 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510
Arun Menon906de572013-06-18 17:01:40 -07005511 PARAMETERS
5512 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005513
Arun Menon906de572013-06-18 17:01:40 -07005514 RETURN VALUE
5515 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516
Arun Menon906de572013-06-18 17:01:40 -07005517 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005518OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005519 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005520{
Arun Menon906de572013-06-18 17:01:40 -07005521 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5522 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523
Arun Menon906de572013-06-18 17:01:40 -07005524 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005525 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005526 return OMX_ErrorInvalidState;
5527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528
Arun Menon906de572013-06-18 17:01:40 -07005529 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005530 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005531 return OMX_ErrorBadParameter;
5532 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533
Arun Menon906de572013-06-18 17:01:40 -07005534 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005535 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005536 return OMX_ErrorIncorrectStateOperation;
5537 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005538
Arun Menon906de572013-06-18 17:01:40 -07005539 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005540 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005541 return OMX_ErrorBadPortIndex;
5542 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005543
5544#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005545 if (iDivXDrmDecrypt) {
5546 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5547 if (drmErr != OMX_ErrorNone) {
5548 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005549 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005550 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005552#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005553 if (perf_flag) {
5554 if (!latency) {
5555 dec_time.stop();
5556 latency = dec_time.processing_time_us();
5557 dec_time.start();
5558 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005559 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005560
Arun Menon906de572013-06-18 17:01:40 -07005561 if (arbitrary_bytes) {
5562 nBufferIndex = buffer - m_inp_heap_ptr;
5563 } else {
5564 if (input_use_buffer == true) {
5565 nBufferIndex = buffer - m_inp_heap_ptr;
5566 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5567 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5568 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5569 buffer = &m_inp_mem_ptr[nBufferIndex];
5570 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5571 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5572 } else {
5573 nBufferIndex = buffer - m_inp_mem_ptr;
5574 }
5575 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005576
Arun Menon906de572013-06-18 17:01:40 -07005577 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005578 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005579 return OMX_ErrorBadParameter;
5580 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005581
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005582 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5583 codec_config_flag = true;
5584 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5585 }
5586
Arun Menon906de572013-06-18 17:01:40 -07005587 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5588 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5589 if (arbitrary_bytes) {
5590 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005592 } else {
Arun Menon906de572013-06-18 17:01:40 -07005593 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5594 }
5595 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005596}
5597
5598/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005599 FUNCTION
5600 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005601
Arun Menon906de572013-06-18 17:01:40 -07005602 DESCRIPTION
5603 This routine is used to push the encoded video frames to
5604 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005605
Arun Menon906de572013-06-18 17:01:40 -07005606 PARAMETERS
5607 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608
Arun Menon906de572013-06-18 17:01:40 -07005609 RETURN VALUE
5610 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005611
Arun Menon906de572013-06-18 17:01:40 -07005612 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005613OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005614 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615{
Arun Menon906de572013-06-18 17:01:40 -07005616 int push_cnt = 0,i=0;
5617 unsigned nPortIndex = 0;
5618 OMX_ERRORTYPE ret = OMX_ErrorNone;
5619 struct vdec_input_frameinfo frameinfo;
5620 struct vdec_bufferpayload *temp_buffer;
5621 struct vdec_seqheader seq_header;
5622 bool port_setting_changed = true;
5623 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005624
Arun Menon906de572013-06-18 17:01:40 -07005625 /*Should we generate a Aync error event*/
5626 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005627 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005628 return OMX_ErrorBadParameter;
5629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630
Arun Menon906de572013-06-18 17:01:40 -07005631 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632
Arun Menon906de572013-06-18 17:01:40 -07005633 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005634 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005635 nPortIndex);
5636 return OMX_ErrorBadParameter;
5637 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005638
Arun Menon906de572013-06-18 17:01:40 -07005639 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640
Arun Menon906de572013-06-18 17:01:40 -07005641 /* return zero length and not an EOS buffer */
5642 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5643 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005644 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005645 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5646 OMX_COMPONENT_GENERATE_EBD);
5647 return OMX_ErrorNone;
5648 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649
5650
Arun Menon906de572013-06-18 17:01:40 -07005651 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5652 mp4StreamType psBits;
5653 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5654 psBits.numBytes = buffer->nFilledLen;
5655 mp4_headerparser.parseHeader(&psBits);
5656 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5657 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5658 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005659 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005660 buffer->nFilledLen,frame_count);
5661 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005662 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005663 not_coded_vop = false;
5664 buffer->nFilledLen = 0;
5665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005666 }
5667 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005668
Arun Menon906de572013-06-18 17:01:40 -07005669 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005670
Arun Menon906de572013-06-18 17:01:40 -07005671 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005672
Arun Menon906de572013-06-18 17:01:40 -07005673 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005674 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005675 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5676 OMX_COMPONENT_GENERATE_EBD);
5677 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005678 }
5679
Arun Menon906de572013-06-18 17:01:40 -07005680 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005681
Surajit Podderd2644d52013-08-28 17:59:06 +05305682 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005683 return OMX_ErrorBadParameter;
5684 }
5685 /* If its first frame, H264 codec and reject is true, then parse the nal
5686 and get the profile. Based on this, reject the clip playback */
5687 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5688 m_reject_avc_1080p_mp) {
5689 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005690 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005691 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5692 NALU_TYPE_SPS);
5693 m_profile = h264_parser->get_profile();
5694 ret = is_video_session_supported();
5695 if (ret) {
5696 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5697 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5698 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5699 m_state = OMX_StateInvalid;
5700 return OMX_ErrorNone;
5701 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702 }
5703
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005704 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005705 /*for use buffer we need to memcpy the data*/
5706 temp_buffer->buffer_len = buffer->nFilledLen;
5707
5708 if (input_use_buffer) {
5709 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5710 if (arbitrary_bytes) {
5711 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5712 } else {
5713 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5714 buffer->nFilledLen);
5715 }
5716 } else {
5717 return OMX_ErrorBadParameter;
5718 }
5719
5720 }
5721
5722 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5723 frameinfo.client_data = (void *) buffer;
5724 frameinfo.datalen = temp_buffer->buffer_len;
5725 frameinfo.flags = 0;
5726 frameinfo.offset = buffer->nOffset;
5727 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5728 frameinfo.pmem_offset = temp_buffer->offset;
5729 frameinfo.timestamp = buffer->nTimeStamp;
5730 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5731 DEBUG_PRINT_LOW("ETB: dmx enabled");
5732 if (m_demux_entries == 0) {
5733 extract_demux_addr_offsets(buffer);
5734 }
5735
5736 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5737 handle_demux_data(buffer);
5738 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5739 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5740 } else {
5741 frameinfo.desc_addr = NULL;
5742 frameinfo.desc_size = 0;
5743 }
5744 if (!arbitrary_bytes) {
5745 frameinfo.flags |= buffer->nFlags;
5746 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005747
5748#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005749 if (m_debug_timestamp) {
5750 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005751 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005752 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5753 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005754 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005755 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5756 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005757 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005758#endif
5759
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005760log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005761
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005762if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005763 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5764 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005766
Arun Menon906de572013-06-18 17:01:40 -07005767 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005768 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005769 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5770 h264_scratch.nFilledLen = 0;
5771 nal_count = 0;
5772 look_ahead_nal = false;
5773 frame_count = 0;
5774 if (m_frame_parser.mutils)
5775 m_frame_parser.mutils->initialize_frame_checking_environment();
5776 m_frame_parser.flush();
5777 h264_last_au_ts = LLONG_MAX;
5778 h264_last_au_flags = 0;
5779 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5780 m_demux_entries = 0;
5781 }
5782 struct v4l2_buffer buf;
5783 struct v4l2_plane plane;
5784 memset( (void *)&buf, 0, sizeof(buf));
5785 memset( (void *)&plane, 0, sizeof(plane));
5786 int rc;
5787 unsigned long print_count;
5788 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005789 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005790 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005791 }
5792 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5793 buf.index = nPortIndex;
5794 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5795 buf.memory = V4L2_MEMORY_USERPTR;
5796 plane.bytesused = temp_buffer->buffer_len;
5797 plane.length = drv_ctx.ip_buf.buffer_size;
5798 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5799 (unsigned long)temp_buffer->offset;
5800 plane.reserved[0] = temp_buffer->pmem_fd;
5801 plane.reserved[1] = temp_buffer->offset;
5802 plane.data_offset = 0;
5803 buf.m.planes = &plane;
5804 buf.length = 1;
5805 if (frameinfo.timestamp >= LLONG_MAX) {
5806 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5807 }
5808 //assumption is that timestamp is in milliseconds
5809 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5810 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5811 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5812 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005813
Arun Menon906de572013-06-18 17:01:40 -07005814 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5815 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005816 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005817 return OMX_ErrorHardware;
5818 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005819 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5820 codec_config_flag = false;
5821 }
Arun Menon906de572013-06-18 17:01:40 -07005822 if (!streaming[OUTPUT_PORT]) {
5823 enum v4l2_buf_type buf_type;
5824 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005825
Arun Menon906de572013-06-18 17:01:40 -07005826 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005827 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005828 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5829 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005830 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005831 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005832 } else if (errno == EBUSY) {
5833 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5834 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5835 OMX_COMPONENT_GENERATE_EBD);
5836 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005837 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005838 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005839 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08005840 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07005841 OMX_COMPONENT_GENERATE_EBD);
5842 return OMX_ErrorBadParameter;
5843 }
5844 }
5845 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5846 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5847 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005848
Arun Menon906de572013-06-18 17:01:40 -07005849 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005850}
5851
5852/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005853 FUNCTION
5854 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855
Arun Menon906de572013-06-18 17:01:40 -07005856 DESCRIPTION
5857 IL client uses this method to release the frame buffer
5858 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005859
Arun Menon906de572013-06-18 17:01:40 -07005860 PARAMETERS
5861 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005862
Arun Menon906de572013-06-18 17:01:40 -07005863 RETURN VALUE
5864 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005865
Arun Menon906de572013-06-18 17:01:40 -07005866 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005867OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005868 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005869{
Arun Menonbdb80b02013-08-12 17:45:54 -07005870 if (dynamic_buf_mode) {
5871 private_handle_t *handle = NULL;
5872 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005873 unsigned int nPortIndex = 0;
5874
5875 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07005876 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07005877 return OMX_ErrorBadParameter;
5878 }
5879
5880 //get the buffer type and fd info
5881 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5882 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005883 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5884
5885 if (!handle) {
5886 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5887 return OMX_ErrorBadParameter;
5888 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005889 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5890 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5891 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005892 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005893
5894 //Store private handle from GraphicBuffer
5895 native_buffer[nPortIndex].privatehandle = handle;
5896 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07005897
5898 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
5899 //this with a more sane size so that we don't compensate in rest of code
5900 //We'll restore this size later on, so that it's transparent to client
5901 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07005902 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07005903 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005904
Arun Menon906de572013-06-18 17:01:40 -07005905 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005906 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005907 return OMX_ErrorInvalidState;
5908 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005909
Arun Menon906de572013-06-18 17:01:40 -07005910 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005911 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005912 return OMX_ErrorIncorrectStateOperation;
5913 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005914
Arun Menon906de572013-06-18 17:01:40 -07005915 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305916 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005917 return OMX_ErrorBadParameter;
5918 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919
Arun Menon906de572013-06-18 17:01:40 -07005920 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005921 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005922 return OMX_ErrorBadPortIndex;
5923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924
Arun Menon906de572013-06-18 17:01:40 -07005925 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5926 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5927 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005928}
5929/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005930 FUNCTION
5931 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005932
Arun Menon906de572013-06-18 17:01:40 -07005933 DESCRIPTION
5934 IL client uses this method to release the frame buffer
5935 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005936
Arun Menon906de572013-06-18 17:01:40 -07005937 PARAMETERS
5938 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005939
Arun Menon906de572013-06-18 17:01:40 -07005940 RETURN VALUE
5941 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005942
Arun Menon906de572013-06-18 17:01:40 -07005943 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005944OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005945 OMX_IN OMX_HANDLETYPE hComp,
5946 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947{
Arun Menon906de572013-06-18 17:01:40 -07005948 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5949 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5950 unsigned nPortIndex = 0;
5951 struct vdec_fillbuffer_cmd fillbuffer;
5952 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5953 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005954
Arun Menon906de572013-06-18 17:01:40 -07005955 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005956
Arun Menon906de572013-06-18 17:01:40 -07005957 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5958 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005959
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005960 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005961 bufferAdd, bufferAdd->pBuffer);
5962 /*Return back the output buffer to client*/
5963 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005964 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005965 buffer->nFilledLen = 0;
5966 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5967 return OMX_ErrorNone;
5968 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005969
5970 if (dynamic_buf_mode) {
5971 //map the buffer handle based on the size set on output port definition.
5972 if (!secure_mode) {
5973 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5974 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5975 PROT_READ|PROT_WRITE, MAP_SHARED,
5976 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5977 }
5978 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5979 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5980 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5981 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5982 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5983 }
5984
Arun Menon906de572013-06-18 17:01:40 -07005985 pending_output_buffers++;
5986 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5987 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5988 if (ptr_respbuffer) {
5989 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5990 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005991
Arun Menon906de572013-06-18 17:01:40 -07005992 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5993 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5994 buffer->nFilledLen = 0;
5995 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5996 pending_output_buffers--;
5997 return OMX_ErrorBadParameter;
5998 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005999
Arun Menon906de572013-06-18 17:01:40 -07006000 int rc = 0;
6001 struct v4l2_buffer buf;
6002 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6003 memset( (void *)&buf, 0, sizeof(buf));
6004 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006005 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006006
Arun Menon906de572013-06-18 17:01:40 -07006007 buf.index = nPortIndex;
6008 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6009 buf.memory = V4L2_MEMORY_USERPTR;
6010 plane[0].bytesused = buffer->nFilledLen;
6011 plane[0].length = drv_ctx.op_buf.buffer_size;
6012 plane[0].m.userptr =
6013 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6014 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6015 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6016 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6017 plane[0].data_offset = 0;
6018 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6019 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6020 plane[extra_idx].bytesused = 0;
6021 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6022 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 -07006023#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006024 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006025#endif
Arun Menon906de572013-06-18 17:01:40 -07006026 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6027 plane[extra_idx].data_offset = 0;
6028 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006029 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006030 return OMX_ErrorBadParameter;
6031 }
6032 buf.m.planes = plane;
6033 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006034 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006035 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6036
Arun Menon906de572013-06-18 17:01:40 -07006037 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6038 if (rc) {
6039 /*TODO: How to handle this case */
6040 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6041 }
Arun Menon906de572013-06-18 17:01:40 -07006042return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043}
6044
6045/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006046 FUNCTION
6047 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048
Arun Menon906de572013-06-18 17:01:40 -07006049 DESCRIPTION
6050 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006051
Arun Menon906de572013-06-18 17:01:40 -07006052 PARAMETERS
6053 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054
Arun Menon906de572013-06-18 17:01:40 -07006055 RETURN VALUE
6056 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057
Arun Menon906de572013-06-18 17:01:40 -07006058 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006059OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006060 OMX_IN OMX_CALLBACKTYPE* callbacks,
6061 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006062{
6063
Arun Menon906de572013-06-18 17:01:40 -07006064 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006065 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006066 m_cb.EventHandler,m_cb.FillBufferDone);
6067 m_app_data = appData;
6068 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069}
6070
6071/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006072 FUNCTION
6073 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006074
Arun Menon906de572013-06-18 17:01:40 -07006075 DESCRIPTION
6076 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006077
Arun Menon906de572013-06-18 17:01:40 -07006078 PARAMETERS
6079 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006080
Arun Menon906de572013-06-18 17:01:40 -07006081 RETURN VALUE
6082 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083
Arun Menon906de572013-06-18 17:01:40 -07006084 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6086{
6087#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006088 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006089 delete iDivXDrmDecrypt;
6090 iDivXDrmDecrypt=NULL;
6091 }
6092#endif //_ANDROID_
6093
Shalaj Jain286b0062013-02-21 20:35:48 -08006094 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006095 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006096 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006097 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006098 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006099 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006100 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006101 }
6102
6103 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006104 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006105 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006106 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6107 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108 }
6109#ifdef _ANDROID_ICS_
6110 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6111#endif
6112 }
6113
6114 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006115 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006116 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006117 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6118 if (m_inp_mem_ptr)
6119 free_input_buffer (i,&m_inp_mem_ptr[i]);
6120 else
6121 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006122 }
6123 }
6124 free_input_buffer_header();
6125 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006126 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006127 free(h264_scratch.pBuffer);
6128 h264_scratch.pBuffer = NULL;
6129 }
6130
Arun Menon906de572013-06-18 17:01:40 -07006131 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006132 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006133 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006134 }
6135
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006136 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006137 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006138 delete (m_frame_parser.mutils);
6139 m_frame_parser.mutils = NULL;
6140 }
6141
Arun Menon906de572013-06-18 17:01:40 -07006142 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006143 free(m_platform_list);
6144 m_platform_list = NULL;
6145 }
Arun Menon906de572013-06-18 17:01:40 -07006146 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147 free(m_vendor_config.pData);
6148 m_vendor_config.pData = NULL;
6149 }
6150
6151 // Reset counters in mesg queues
6152 m_ftb_q.m_size=0;
6153 m_cmd_q.m_size=0;
6154 m_etb_q.m_size=0;
6155 m_ftb_q.m_read = m_ftb_q.m_write =0;
6156 m_cmd_q.m_read = m_cmd_q.m_write =0;
6157 m_etb_q.m_read = m_etb_q.m_write =0;
6158#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006159 if (m_debug_timestamp) {
6160 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006161 }
6162#endif
6163
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006164 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006166 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006167 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006168
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006169 if (m_debug.infile) {
6170 fclose(m_debug.infile);
6171 m_debug.infile = NULL;
6172 }
6173 if (m_debug.outfile) {
6174 fclose(m_debug.outfile);
6175 m_debug.outfile = NULL;
6176 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006177#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006178 if (outputExtradataFile)
6179 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006180#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006181 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006182 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183}
6184
6185/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006186 FUNCTION
6187 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006188
Arun Menon906de572013-06-18 17:01:40 -07006189 DESCRIPTION
6190 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006191
Arun Menon906de572013-06-18 17:01:40 -07006192 PARAMETERS
6193 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006194
Arun Menon906de572013-06-18 17:01:40 -07006195 RETURN VALUE
6196 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006197
Arun Menon906de572013-06-18 17:01:40 -07006198 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006199OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006200 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6201 OMX_IN OMX_U32 port,
6202 OMX_IN OMX_PTR appData,
6203 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006204{
Arun Menon906de572013-06-18 17:01:40 -07006205 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6206 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6207 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006208
6209#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006210 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6211 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006212#else
Arun Menon906de572013-06-18 17:01:40 -07006213 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006215 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006216 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006217 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006218 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006220 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006221 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006222 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006223 }
6224 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6225 eglGetProcAddress("eglQueryImageKHR");
6226 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6227 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6228 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229#else //with OMX test app
6230 struct temp_egl {
6231 int pmem_fd;
6232 int offset;
6233 };
6234 struct temp_egl *temp_egl_id = NULL;
6235 void * pmemPtr = (void *) eglImage;
6236 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006237 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238 fd = temp_egl_id->pmem_fd;
6239 offset = temp_egl_id->offset;
6240 }
6241#endif
6242 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006243 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006244 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006245 }
6246 pmem_info.pmem_fd = (OMX_U32) fd;
6247 pmem_info.offset = (OMX_U32) offset;
6248 pmem_entry.entry = (void *) &pmem_info;
6249 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6250 pmem_list.entryList = &pmem_entry;
6251 pmem_list.nEntries = 1;
6252 ouput_egl_buffers = true;
6253 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6254 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6255 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006256 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006257 return OMX_ErrorInsufficientResources;
6258 }
6259 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006260}
6261
6262/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006263 FUNCTION
6264 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006265
Arun Menon906de572013-06-18 17:01:40 -07006266 DESCRIPTION
6267 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006268
Arun Menon906de572013-06-18 17:01:40 -07006269 PARAMETERS
6270 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271
Arun Menon906de572013-06-18 17:01:40 -07006272 RETURN VALUE
6273 OMX Error None if everything is successful.
6274 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006275OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006276 OMX_OUT OMX_U8* role,
6277 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006278{
Arun Menon906de572013-06-18 17:01:40 -07006279 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006280
Arun Menon906de572013-06-18 17:01:40 -07006281 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6282 if ((0 == index) && role) {
6283 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006284 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006285 } else {
6286 eRet = OMX_ErrorNoMore;
6287 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006288 }
Arun Menon906de572013-06-18 17:01:40 -07006289 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6290 if ((0 == index) && role) {
6291 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006292 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006293 } else {
6294 eRet = OMX_ErrorNoMore;
6295 }
6296 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6297 if ((0 == index) && role) {
6298 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006299 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006300 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006301 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006302 eRet = OMX_ErrorNoMore;
6303 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006304 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006305
Arun Menon906de572013-06-18 17:01:40 -07006306 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6307 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6308 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006309
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310 {
Arun Menon906de572013-06-18 17:01:40 -07006311 if ((0 == index) && role) {
6312 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006313 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006314 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006315 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006316 eRet = OMX_ErrorNoMore;
6317 }
6318 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6319 if ((0 == index) && role) {
6320 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006321 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006322 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006323 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006324 eRet = OMX_ErrorNoMore;
6325 }
6326 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6327 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6328 ) {
6329 if ((0 == index) && role) {
6330 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006331 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006332 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006333 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006334 eRet = OMX_ErrorNoMore;
6335 }
6336 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6337 if ((0 == index) && role) {
6338 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006339 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006340 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006341 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006342 eRet = OMX_ErrorNoMore;
6343 }
6344 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006345 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006346 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006347 }
Arun Menon906de572013-06-18 17:01:40 -07006348 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006349}
6350
6351
6352
6353
6354/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006355 FUNCTION
6356 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006357
Arun Menon906de572013-06-18 17:01:40 -07006358 DESCRIPTION
6359 Checks if entire buffer pool is allocated by IL Client or not.
6360 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006361
Arun Menon906de572013-06-18 17:01:40 -07006362 PARAMETERS
6363 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364
Arun Menon906de572013-06-18 17:01:40 -07006365 RETURN VALUE
6366 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006367
Arun Menon906de572013-06-18 17:01:40 -07006368 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006369bool omx_vdec::allocate_done(void)
6370{
Arun Menon906de572013-06-18 17:01:40 -07006371 bool bRet = false;
6372 bool bRet_In = false;
6373 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006374
Arun Menon906de572013-06-18 17:01:40 -07006375 bRet_In = allocate_input_done();
6376 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006377
Arun Menon906de572013-06-18 17:01:40 -07006378 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006379 bRet = true;
6380 }
Arun Menon906de572013-06-18 17:01:40 -07006381
6382 return bRet;
6383}
6384/* ======================================================================
6385 FUNCTION
6386 omx_vdec::AllocateInputDone
6387
6388 DESCRIPTION
6389 Checks if I/P buffer pool is allocated by IL Client or not.
6390
6391 PARAMETERS
6392 None.
6393
6394 RETURN VALUE
6395 true/false.
6396
6397 ========================================================================== */
6398bool omx_vdec::allocate_input_done(void)
6399{
6400 bool bRet = false;
6401 unsigned i=0;
6402
6403 if (m_inp_mem_ptr == NULL) {
6404 return bRet;
6405 }
6406 if (m_inp_mem_ptr ) {
6407 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6408 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6409 break;
6410 }
6411 }
6412 }
6413 if (i == drv_ctx.ip_buf.actualcount) {
6414 bRet = true;
6415 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6416 }
6417 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6418 m_inp_bPopulated = OMX_TRUE;
6419 }
6420 return bRet;
6421}
6422/* ======================================================================
6423 FUNCTION
6424 omx_vdec::AllocateOutputDone
6425
6426 DESCRIPTION
6427 Checks if entire O/P buffer pool is allocated by IL Client or not.
6428
6429 PARAMETERS
6430 None.
6431
6432 RETURN VALUE
6433 true/false.
6434
6435 ========================================================================== */
6436bool omx_vdec::allocate_output_done(void)
6437{
6438 bool bRet = false;
6439 unsigned j=0;
6440
6441 if (m_out_mem_ptr == NULL) {
6442 return bRet;
6443 }
6444
6445 if (m_out_mem_ptr) {
6446 for (; j < drv_ctx.op_buf.actualcount; j++) {
6447 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6448 break;
6449 }
6450 }
6451 }
6452
6453 if (j == drv_ctx.op_buf.actualcount) {
6454 bRet = true;
6455 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6456 if (m_out_bEnabled)
6457 m_out_bPopulated = OMX_TRUE;
6458 }
6459
6460 return bRet;
6461}
6462
6463/* ======================================================================
6464 FUNCTION
6465 omx_vdec::ReleaseDone
6466
6467 DESCRIPTION
6468 Checks if IL client has released all the buffers.
6469
6470 PARAMETERS
6471 None.
6472
6473 RETURN VALUE
6474 true/false
6475
6476 ========================================================================== */
6477bool omx_vdec::release_done(void)
6478{
6479 bool bRet = false;
6480
6481 if (release_input_done()) {
6482 if (release_output_done()) {
6483 bRet = true;
6484 }
6485 }
6486 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006487}
6488
6489
6490/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006491 FUNCTION
6492 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006493
Arun Menon906de572013-06-18 17:01:40 -07006494 DESCRIPTION
6495 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006496
Arun Menon906de572013-06-18 17:01:40 -07006497 PARAMETERS
6498 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006499
Arun Menon906de572013-06-18 17:01:40 -07006500 RETURN VALUE
6501 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006502
Arun Menon906de572013-06-18 17:01:40 -07006503 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006504bool omx_vdec::release_output_done(void)
6505{
Arun Menon906de572013-06-18 17:01:40 -07006506 bool bRet = false;
6507 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006508
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006509 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006510 if (m_out_mem_ptr) {
6511 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6512 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6513 break;
6514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006515 }
Arun Menon906de572013-06-18 17:01:40 -07006516 if (j == drv_ctx.op_buf.actualcount) {
6517 m_out_bm_count = 0;
6518 bRet = true;
6519 }
6520 } else {
6521 m_out_bm_count = 0;
6522 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006523 }
Arun Menon906de572013-06-18 17:01:40 -07006524 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006525}
6526/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006527 FUNCTION
6528 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006529
Arun Menon906de572013-06-18 17:01:40 -07006530 DESCRIPTION
6531 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006532
Arun Menon906de572013-06-18 17:01:40 -07006533 PARAMETERS
6534 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006535
Arun Menon906de572013-06-18 17:01:40 -07006536 RETURN VALUE
6537 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006538
Arun Menon906de572013-06-18 17:01:40 -07006539 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006540bool omx_vdec::release_input_done(void)
6541{
Arun Menon906de572013-06-18 17:01:40 -07006542 bool bRet = false;
6543 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006544
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006545 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006546 if (m_inp_mem_ptr) {
6547 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6548 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6549 break;
6550 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006551 }
Arun Menon906de572013-06-18 17:01:40 -07006552 if (j==drv_ctx.ip_buf.actualcount) {
6553 bRet = true;
6554 }
6555 } else {
6556 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006557 }
Arun Menon906de572013-06-18 17:01:40 -07006558 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006559}
6560
6561OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006562 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006563{
Arun Menon906de572013-06-18 17:01:40 -07006564 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306565 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006566 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006567 return OMX_ErrorBadParameter;
6568 } else if (output_flush_progress) {
6569 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6570 buffer->nFilledLen = 0;
6571 buffer->nTimeStamp = 0;
6572 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6573 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6574 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006575 }
6576
Arun Menon906de572013-06-18 17:01:40 -07006577 if (m_debug_extradata) {
6578 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006579 DEBUG_PRINT_HIGH("");
6580 DEBUG_PRINT_HIGH("***************************************************");
6581 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6582 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006583 }
6584
6585 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006586 DEBUG_PRINT_HIGH("");
6587 DEBUG_PRINT_HIGH("***************************************************");
6588 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6589 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006590 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006591 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006592
6593
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006594 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006595 buffer, buffer->pBuffer);
6596 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006597
Arun Menon906de572013-06-18 17:01:40 -07006598 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006599 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006600 if (!output_flush_progress)
6601 post_event((unsigned)NULL, (unsigned)NULL,
6602 OMX_COMPONENT_GENERATE_EOS_DONE);
6603
6604 if (psource_frame) {
6605 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6606 psource_frame = NULL;
6607 }
6608 if (pdest_frame) {
6609 pdest_frame->nFilledLen = 0;
6610 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6611 (unsigned)NULL);
6612 pdest_frame = NULL;
6613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006614 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006615
Shalaj Jain273b3e02012-06-22 19:08:03 -07006616
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006617 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6618 DEBUG_PRINT_LOW("Processing extradata");
6619 handle_extradata(buffer);
6620 }
6621
Arun Menon906de572013-06-18 17:01:40 -07006622 /* For use buffer we need to copy the data */
6623 if (!output_flush_progress) {
6624 /* This is the error check for non-recoverable errros */
6625 bool is_duplicate_ts_valid = true;
6626 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006627
Arun Menon906de572013-06-18 17:01:40 -07006628 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6629 output_capability == V4L2_PIX_FMT_MPEG2 ||
6630 output_capability == V4L2_PIX_FMT_DIVX ||
6631 output_capability == V4L2_PIX_FMT_DIVX_311)
6632 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006633
Arun Menon906de572013-06-18 17:01:40 -07006634 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006635 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006636 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306637 }
Arun Menon906de572013-06-18 17:01:40 -07006638 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306639
Arun Menon906de572013-06-18 17:01:40 -07006640 if (buffer->nFilledLen > 0) {
6641 time_stamp_dts.get_next_timestamp(buffer,
6642 is_interlaced && is_duplicate_ts_valid);
6643 if (m_debug_timestamp) {
6644 {
6645 OMX_TICKS expected_ts = 0;
6646 m_timestamp_list.pop_min_ts(expected_ts);
6647 if (is_interlaced && is_duplicate_ts_valid) {
6648 m_timestamp_list.pop_min_ts(expected_ts);
6649 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006650 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006651 buffer->nTimeStamp, expected_ts);
6652
6653 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006654 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006655 }
6656 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306657 }
Arun Menon906de572013-06-18 17:01:40 -07006658 } else {
Arun Menon906de572013-06-18 17:01:40 -07006659 time_stamp_dts.remove_time_stamp(
6660 buffer->nTimeStamp,
6661 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306662 }
Arun Menon906de572013-06-18 17:01:40 -07006663
6664
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006665 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006666
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006667 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6668 * to size of the handle. Do it _after_ handle_extradata() which
6669 * requires the respective sizes to be accurate. */
6670 if (dynamic_buf_mode) {
6671 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6672 buffer->nFilledLen = buffer->nFilledLen ?
6673 sizeof(struct VideoDecoderOutputMetaData) : 0;
6674 }
6675
Arun Menon906de572013-06-18 17:01:40 -07006676 if (m_cb.FillBufferDone) {
6677 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006678 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006679 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006680 else
6681 set_frame_rate(buffer->nTimeStamp);
6682
Arun Menon906de572013-06-18 17:01:40 -07006683 if (perf_flag) {
6684 if (!proc_frms) {
6685 dec_time.stop();
6686 latency = dec_time.processing_time_us() - latency;
6687 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6688 dec_time.start();
6689 fps_metrics.start();
6690 }
6691 proc_frms++;
6692 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6693 OMX_U64 proc_time = 0;
6694 fps_metrics.stop();
6695 proc_time = fps_metrics.processing_time_us();
6696 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006697 proc_frms, (float)proc_time / 1e6,
6698 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006699 proc_frms = 0;
6700 }
6701 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006702
6703#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006704 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006705
Arun Menon906de572013-06-18 17:01:40 -07006706 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6707 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6708 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6709 buffer->nFilledLen + 3)&(~3));
6710 while (p_extra &&
6711 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006712 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006713 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6714 if (p_extra->eType == OMX_ExtraDataNone) {
6715 break;
6716 }
6717 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6718 }
6719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006720#endif
Arun Menon906de572013-06-18 17:01:40 -07006721 }
6722 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6723 prev_ts = LLONG_MAX;
6724 rst_prev_ts = true;
6725 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006726
Arun Menon906de572013-06-18 17:01:40 -07006727 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6728 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6729 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006730 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006731 OMX_BUFFERHEADERTYPE *il_buffer;
6732 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006733
vivek mehta79cff222014-01-22 12:17:07 -08006734 if (il_buffer && m_last_rendered_TS >= 0) {
6735 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306736 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006737
6738 // Current frame can be send for rendering if
6739 // (a) current FPS is <= 60
6740 // (b) is the next frame after the frame with TS 0
6741 // (c) is the first frame after seek
6742 // (d) the delta TS b\w two consecutive frames is > 16 ms
6743 // (e) its TS is equal to previous frame TS
6744 // (f) if marked EOS
6745
6746 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6747 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6748 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006749 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006750 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006751 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006752 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006753 }
6754
6755 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6756 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6757 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006758 }
6759
vivek mehta79cff222014-01-22 12:17:07 -08006760 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006761 log_output_buffers(il_buffer);
6762 if (dynamic_buf_mode) {
6763 unsigned int nPortIndex = 0;
6764 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6765
6766 if (!secure_mode) {
6767 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6768 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6769 }
6770
6771 //Clear graphic buffer handles in dynamic mode
6772 native_buffer[nPortIndex].privatehandle = NULL;
6773 native_buffer[nPortIndex].nativehandle = NULL;
6774 }
Arun Menon906de572013-06-18 17:01:40 -07006775 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006776 } else {
Arun Menon906de572013-06-18 17:01:40 -07006777 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6778 return OMX_ErrorBadParameter;
6779 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006780 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006781 } else {
6782 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006784
Praveen Chavancf924182013-12-06 23:16:23 -08006785#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306786 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006787 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6788 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306789 private_handle_t *private_handle = NULL;
Pushkaraj Patil41588352014-02-25 20:51:34 +05306790 if (is_down_scalar_enabled) {
6791 dim.sliceWidth = drv_ctx.video_resolution.stride;
6792 dim.sliceHeight = drv_ctx.video_resolution.scan_lines;
6793 } else {
6794 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6795 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6796 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306797 if (native_buffer[buf_index].privatehandle)
6798 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006799 if (private_handle) {
6800 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6801 dim.sliceWidth, dim.sliceHeight);
6802 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6803 }
6804 }
6805#endif
6806
Arun Menon906de572013-06-18 17:01:40 -07006807 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006808}
6809
6810OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006811 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006812{
6813
Surajit Podderd2644d52013-08-28 17:59:06 +05306814 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006815 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006816 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006817 }
6818
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006819 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006820 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006821 pending_input_buffers--;
6822
Arun Menon906de572013-06-18 17:01:40 -07006823 if (arbitrary_bytes) {
6824 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006825 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006826 pdest_frame = buffer;
6827 buffer->nFilledLen = 0;
6828 buffer->nTimeStamp = LLONG_MAX;
6829 push_input_buffer (hComp);
6830 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006831 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006832 buffer->nFilledLen = 0;
6833 if (!m_input_free_q.insert_entry((unsigned)buffer,
6834 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006835 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006836 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006837 }
Arun Menon906de572013-06-18 17:01:40 -07006838 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006839 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006840 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006841 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6842 }
6843 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6844 }
6845 return OMX_ErrorNone;
6846}
6847
Shalaj Jain273b3e02012-06-22 19:08:03 -07006848int omx_vdec::async_message_process (void *context, void* message)
6849{
Arun Menon906de572013-06-18 17:01:40 -07006850 omx_vdec* omx = NULL;
6851 struct vdec_msginfo *vdec_msg = NULL;
6852 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6853 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6854 struct vdec_output_frameinfo *output_respbuf = NULL;
6855 int rc=1;
6856 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006857 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006858 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006859 }
Arun Menon906de572013-06-18 17:01:40 -07006860 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006861
Arun Menon906de572013-06-18 17:01:40 -07006862 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006863
Arun Menon906de572013-06-18 17:01:40 -07006864 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006865
Arun Menon906de572013-06-18 17:01:40 -07006866 case VDEC_MSG_EVT_HW_ERROR:
6867 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6868 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6869 break;
6870
Deepak Verma24720fb2014-01-29 16:57:40 +05306871 case VDEC_MSG_EVT_HW_OVERLOAD:
6872 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6873 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
6874 break;
6875
Arun Menon906de572013-06-18 17:01:40 -07006876 case VDEC_MSG_RESP_START_DONE:
6877 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6878 OMX_COMPONENT_GENERATE_START_DONE);
6879 break;
6880
6881 case VDEC_MSG_RESP_STOP_DONE:
6882 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6883 OMX_COMPONENT_GENERATE_STOP_DONE);
6884 break;
6885
6886 case VDEC_MSG_RESP_RESUME_DONE:
6887 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6888 OMX_COMPONENT_GENERATE_RESUME_DONE);
6889 break;
6890
6891 case VDEC_MSG_RESP_PAUSE_DONE:
6892 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6893 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6894 break;
6895
6896 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6897 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6898 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6899 break;
6900 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6901 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6902 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6903 break;
6904 case VDEC_MSG_RESP_INPUT_FLUSHED:
6905 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6906
6907 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6908 vdec_msg->msgdata.input_frame_clientdata; */
6909
6910 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6911 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6912 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306913 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006914 omxhdr = NULL;
6915 vdec_msg->status_code = VDEC_S_EFATAL;
6916 }
6917 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6918 DEBUG_PRINT_HIGH("Unsupported input");
6919 omx->omx_report_error ();
6920 }
6921 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6922 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6923 }
6924 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6925 OMX_COMPONENT_GENERATE_EBD);
6926 break;
6927 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6928 int64_t *timestamp;
6929 timestamp = (int64_t *) malloc(sizeof(int64_t));
6930 if (timestamp) {
6931 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6932 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6933 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006934 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006935 vdec_msg->msgdata.output_frame.time_stamp);
6936 }
6937 break;
6938 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6939 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6940
6941 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6942 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6943 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6944 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6945 vdec_msg->msgdata.output_frame.pic_type);
6946
6947 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306948 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006949 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306950 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006951 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07006952 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6953 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6954 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6955 omxhdr->nFlags = 0;
6956
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006957 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006958 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6959 //rc = -1;
6960 }
6961 if (omxhdr->nFilledLen) {
6962 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6963 }
6964 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6965 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6966 } else {
6967 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6968 }
6969 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6970 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6971 }
6972 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6973 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6974 }
Arun Menon7b6fd642014-02-13 16:48:36 -08006975
6976 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
6977 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
6978 }
6979
Arun Menonbdb80b02013-08-12 17:45:54 -07006980 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006981 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006982 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6983 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6984 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006985 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6986 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6987 omxhdr->nOffset);
6988 }
Arun Menon906de572013-06-18 17:01:40 -07006989 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6990 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006991 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006992 omx->time_stamp_dts.remove_time_stamp(
6993 omxhdr->nTimeStamp,
6994 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6995 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006996 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6997 OMX_COMPONENT_GENERATE_FTB);
6998 break;
6999 }
7000 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7001 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7002 }
7003 vdec_msg->msgdata.output_frame.bufferaddr =
7004 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
7005 int format_notably_changed = 0;
7006 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307007 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07007008 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7009 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007010 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07007011 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7012 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
7013 format_notably_changed = 1;
Surajit Podderdfade372014-05-27 22:39:36 +05307014
7015 struct v4l2_format fmt;
7016 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7017 fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
7018 fmt.fmt.pix_mp.height = omx->drv_ctx.video_resolution.frame_height;
7019 fmt.fmt.pix_mp.width = omx->drv_ctx.video_resolution.frame_width;
7020
7021 if (!ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt)) {
7022 omx->update_resolution(fmt.fmt.pix_mp.width,
7023 fmt.fmt.pix_mp.height,
7024 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7025 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7026 }
Arun Menon906de572013-06-18 17:01:40 -07007027 }
7028 }
7029 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
7030 vdec_msg->msgdata.output_frame.framesize.left)
7031 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
7032 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
7033 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
7034 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
7035 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
7036 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
7037 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007038 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07007039 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
7040 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
7041 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007042 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07007043 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
7044 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07007045 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
7046 omx->drv_ctx.video_resolution.frame_width) {
7047 vdec_msg->msgdata.output_frame.framesize.left = 0;
7048 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
7049 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
7050 }
7051 }
7052 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
7053 omx->drv_ctx.video_resolution.frame_height) {
7054 vdec_msg->msgdata.output_frame.framesize.top = 0;
7055 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
7056 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
7057 }
7058 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007059 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 -07007060 vdec_msg->msgdata.output_frame.framesize.left,
7061 vdec_msg->msgdata.output_frame.framesize.top,
7062 vdec_msg->msgdata.output_frame.framesize.right,
7063 vdec_msg->msgdata.output_frame.framesize.bottom,
7064 omx->drv_ctx.video_resolution.frame_width,
7065 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07007066 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7067 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7068 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7069 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
7070 format_notably_changed = 1;
7071 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007072 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07007073 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
7074 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007075 if (format_notably_changed) {
7076 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05307077 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07007078 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7079 } else {
7080 if (!omx->client_buffers.update_buffer_req()) {
7081 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7082 }
7083 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7084 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7085 }
7086 }
7087 if (omxhdr->nFilledLen)
7088 omx->prev_n_filled_len = omxhdr->nFilledLen;
7089
7090 output_respbuf = (struct vdec_output_frameinfo *)\
7091 omxhdr->pOutputPortPrivate;
7092 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7093 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
7094 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7095 output_respbuf->pic_type = PICTURE_TYPE_I;
7096 }
7097 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7098 output_respbuf->pic_type = PICTURE_TYPE_P;
7099 }
7100 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7101 output_respbuf->pic_type = PICTURE_TYPE_B;
7102 }
7103
7104 if (omx->output_use_buffer)
7105 memcpy ( omxhdr->pBuffer, (void *)
7106 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7107 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7108 vdec_msg->msgdata.output_frame.len);
7109 } else
7110 omxhdr->nFilledLen = 0;
7111 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7112 OMX_COMPONENT_GENERATE_FBD);
7113 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
7114 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7115 OMX_COMPONENT_GENERATE_EOS_DONE);
7116 else
7117 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7118 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7119 break;
7120 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007121 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007122 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7123 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7124 break;
7125 default:
7126 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007127 }
Arun Menon906de572013-06-18 17:01:40 -07007128 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007129}
7130
7131OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007132 OMX_HANDLETYPE hComp,
7133 OMX_BUFFERHEADERTYPE *buffer
7134 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007135{
Arun Menon906de572013-06-18 17:01:40 -07007136 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007137 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007138
Arun Menon906de572013-06-18 17:01:40 -07007139 if (buffer == NULL) {
7140 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007141 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007142 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7143 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007144 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7145
7146 /* return zero length and not an EOS buffer */
7147 /* return buffer if input flush in progress */
7148 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7149 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007150 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007151 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7152 return OMX_ErrorNone;
7153 }
7154
7155 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007156 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007157 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007158 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007159 push_input_buffer (hComp);
7160 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007161 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007162 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7163 (unsigned)NULL)) {
7164 return OMX_ErrorBadParameter;
7165 }
7166 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007167
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007168 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7169 codec_config_flag = false;
7170 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007171
Arun Menon906de572013-06-18 17:01:40 -07007172 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007173}
7174
7175OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7176{
Arun Menon906de572013-06-18 17:01:40 -07007177 unsigned address,p2,id;
7178 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007179
Arun Menon906de572013-06-18 17:01:40 -07007180 if (pdest_frame == NULL || psource_frame == NULL) {
7181 /*Check if we have a destination buffer*/
7182 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007183 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007184 if (m_input_free_q.m_size) {
7185 m_input_free_q.pop_entry(&address,&p2,&id);
7186 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7187 pdest_frame->nFilledLen = 0;
7188 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007189 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007190 }
7191 }
7192
7193 /*Check if we have a destination buffer*/
7194 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007195 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007196 if (m_input_pending_q.m_size) {
7197 m_input_pending_q.pop_entry(&address,&p2,&id);
7198 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007199 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007200 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007201 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007202 psource_frame->nFlags,psource_frame->nFilledLen);
7203
7204 }
7205 }
7206
Shalaj Jain273b3e02012-06-22 19:08:03 -07007207 }
7208
Arun Menon906de572013-06-18 17:01:40 -07007209 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7210 switch (codec_type_parse) {
7211 case CODEC_TYPE_MPEG4:
7212 case CODEC_TYPE_H263:
7213 case CODEC_TYPE_MPEG2:
7214 ret = push_input_sc_codec(hComp);
7215 break;
7216 case CODEC_TYPE_H264:
7217 ret = push_input_h264(hComp);
7218 break;
7219 case CODEC_TYPE_VC1:
7220 ret = push_input_vc1(hComp);
7221 break;
7222 default:
7223 break;
7224 }
7225 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007226 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007227 omx_report_error ();
7228 break;
7229 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007230 }
7231
Arun Menon906de572013-06-18 17:01:40 -07007232 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007233}
7234
7235OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7236{
Arun Menon906de572013-06-18 17:01:40 -07007237 OMX_U32 partial_frame = 1;
7238 OMX_BOOL generate_ebd = OMX_TRUE;
7239 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007240
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007241 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007242 psource_frame,psource_frame->nTimeStamp);
7243 if (m_frame_parser.parse_sc_frame(psource_frame,
7244 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007245 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007246 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007247 }
Arun Menon906de572013-06-18 17:01:40 -07007248
7249 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007250 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007251 pdest_frame->nFilledLen,psource_frame,frame_count);
7252
7253
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007254 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007255 /*First Parsed buffer will have only header Hence skip*/
7256 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007257 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007258
7259 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7260 codec_type_parse == CODEC_TYPE_DIVX) {
7261 mp4StreamType psBits;
7262 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7263 psBits.numBytes = pdest_frame->nFilledLen;
7264 mp4_headerparser.parseHeader(&psBits);
7265 }
7266
7267 frame_count++;
7268 } else {
7269 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7270 if (pdest_frame->nFilledLen) {
7271 /*Push the frame to the Decoder*/
7272 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7273 return OMX_ErrorBadParameter;
7274 }
7275 frame_count++;
7276 pdest_frame = NULL;
7277
7278 if (m_input_free_q.m_size) {
7279 m_input_free_q.pop_entry(&address,&p2,&id);
7280 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7281 pdest_frame->nFilledLen = 0;
7282 }
7283 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007284 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007285 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7286 (unsigned)NULL);
7287 pdest_frame = NULL;
7288 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007289 }
Arun Menon906de572013-06-18 17:01:40 -07007290 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007291 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007292 /*Check if Destination Buffer is full*/
7293 if (pdest_frame->nAllocLen ==
7294 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007295 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007296 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007297 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007298 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007299
Arun Menon906de572013-06-18 17:01:40 -07007300 if (psource_frame->nFilledLen == 0) {
7301 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7302 if (pdest_frame) {
7303 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007304 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007305 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007306 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007307 pdest_frame->nFilledLen,frame_count++);
7308 /*Push the frame to the Decoder*/
7309 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7310 return OMX_ErrorBadParameter;
7311 }
7312 frame_count++;
7313 pdest_frame = NULL;
7314 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007315 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007316 generate_ebd = OMX_FALSE;
7317 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007318 }
Arun Menon906de572013-06-18 17:01:40 -07007319 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007320 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007321 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7322 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007323
Arun Menon906de572013-06-18 17:01:40 -07007324 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007325 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007326 m_input_pending_q.pop_entry(&address,&p2,&id);
7327 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007328 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007329 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007330 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007331 psource_frame->nFlags,psource_frame->nFilledLen);
7332 }
7333 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007334 }
Arun Menon906de572013-06-18 17:01:40 -07007335 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007336}
7337
7338OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7339{
Arun Menon906de572013-06-18 17:01:40 -07007340 OMX_U32 partial_frame = 1;
7341 unsigned address = 0, p2 = 0, id = 0;
7342 OMX_BOOL isNewFrame = OMX_FALSE;
7343 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007344
Arun Menon906de572013-06-18 17:01:40 -07007345 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007346 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007347 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007348 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007349 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007350 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007351 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007352 if (h264_scratch.nFilledLen && look_ahead_nal) {
7353 look_ahead_nal = false;
7354 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7355 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007356 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7357 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7358 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007359 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007360 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007361 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007362 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007363 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007364 }
Arun Menon906de572013-06-18 17:01:40 -07007365 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007366
7367 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7368 in EOS flag getting associated with the destination
7369 */
7370 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7371 pdest_frame->nFilledLen) {
7372 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7373 generate_ebd = OMX_FALSE;
7374 }
7375
Arun Menon906de572013-06-18 17:01:40 -07007376 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007377 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007378 if (m_frame_parser.parse_sc_frame(psource_frame,
7379 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007380 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007381 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007382 }
Arun Menon906de572013-06-18 17:01:40 -07007383 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007384 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007385 if (m_frame_parser.parse_h264_nallength(psource_frame,
7386 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007387 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007388 return OMX_ErrorBadParameter;
7389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007391
Arun Menon906de572013-06-18 17:01:40 -07007392 if (partial_frame == 0) {
7393 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007394 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007395 nal_count++;
7396 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7397 h264_scratch.nFlags = psource_frame->nFlags;
7398 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007399 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007400 if (h264_scratch.nFilledLen) {
7401 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7402 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007403#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007404 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7405 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7406 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7407 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7408 // If timeinfo is present frame info from SEI is already processed
7409 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7410 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007411#endif
Arun Menon906de572013-06-18 17:01:40 -07007412 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7413 nal_count++;
7414 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7415 pdest_frame->nTimeStamp = h264_last_au_ts;
7416 pdest_frame->nFlags = h264_last_au_flags;
7417#ifdef PANSCAN_HDLR
7418 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7419 h264_parser->update_panscan_data(h264_last_au_ts);
7420#endif
7421 }
7422 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7423 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7424 h264_last_au_ts = h264_scratch.nTimeStamp;
7425 h264_last_au_flags = h264_scratch.nFlags;
7426#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7427 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7428 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7429 if (!VALID_TS(h264_last_au_ts))
7430 h264_last_au_ts = ts_in_sei;
7431 }
7432#endif
7433 } else
7434 h264_last_au_ts = LLONG_MAX;
7435 }
7436
7437 if (!isNewFrame) {
7438 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7439 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007440 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007441 h264_scratch.nFilledLen);
7442 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7443 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7444 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7445 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7446 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7447 h264_scratch.nFilledLen = 0;
7448 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007449 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007450 return OMX_ErrorBadParameter;
7451 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007452 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007453 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007454 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007455 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007457 pdest_frame->nFilledLen,frame_count++);
7458
7459 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007460 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007461 look_ahead_nal = false;
7462 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7463 h264_scratch.nFilledLen) {
7464 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7465 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7466 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7467 h264_scratch.nFilledLen = 0;
7468 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007469 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007470 return OMX_ErrorBadParameter;
7471 }
7472 } else {
7473 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007474 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007475 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7476 }
7477 /*Push the frame to the Decoder*/
7478 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7479 return OMX_ErrorBadParameter;
7480 }
7481 //frame_count++;
7482 pdest_frame = NULL;
7483 if (m_input_free_q.m_size) {
7484 m_input_free_q.pop_entry(&address,&p2,&id);
7485 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007486 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007487 pdest_frame->nFilledLen = 0;
7488 pdest_frame->nFlags = 0;
7489 pdest_frame->nTimeStamp = LLONG_MAX;
7490 }
7491 }
7492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007493 }
Arun Menon906de572013-06-18 17:01:40 -07007494 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007495 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007496 /*Check if Destination Buffer is full*/
7497 if (h264_scratch.nAllocLen ==
7498 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007499 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007500 return OMX_ErrorStreamCorrupt;
7501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007502 }
Arun Menon906de572013-06-18 17:01:40 -07007503
7504 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007505 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007506
7507 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7508 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007509 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007510 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7511 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007512 if(pdest_frame->nFilledLen == 0) {
7513 /* No residual frame from before, send whatever
7514 * we have left */
7515 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7516 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7517 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7518 h264_scratch.nFilledLen = 0;
7519 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7520 } else {
7521 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7522 if(!isNewFrame) {
7523 /* Have a residual frame, but we know that the
7524 * AU in this frame is belonging to whatever
7525 * frame we had left over. So append it */
7526 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7527 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7528 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7529 h264_scratch.nFilledLen = 0;
7530 pdest_frame->nTimeStamp = h264_last_au_ts;
7531 } else {
7532 /* Completely new frame, let's just push what
7533 * we have now. The resulting EBD would trigger
7534 * another push */
7535 generate_ebd = OMX_FALSE;
7536 pdest_frame->nTimeStamp = h264_last_au_ts;
7537 h264_last_au_ts = h264_scratch.nTimeStamp;
7538 }
7539 }
Arun Menon906de572013-06-18 17:01:40 -07007540 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007541 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007542 return OMX_ErrorBadParameter;
7543 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007544
7545 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7546 if(generate_ebd == OMX_TRUE) {
7547 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7548 }
Arun Menon906de572013-06-18 17:01:40 -07007549
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007550 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007551 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007552 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007553#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7554 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7555 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7556 if (!VALID_TS(pdest_frame->nTimeStamp))
7557 pdest_frame->nTimeStamp = ts_in_sei;
7558 }
7559#endif
7560 /*Push the frame to the Decoder*/
7561 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7562 return OMX_ErrorBadParameter;
7563 }
7564 frame_count++;
7565 pdest_frame = NULL;
7566 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007567 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007568 pdest_frame,h264_scratch.nFilledLen);
7569 generate_ebd = OMX_FALSE;
7570 }
7571 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007572 }
Arun Menon906de572013-06-18 17:01:40 -07007573 if (generate_ebd && !psource_frame->nFilledLen) {
7574 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7575 psource_frame = NULL;
7576 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007577 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007578 m_input_pending_q.pop_entry(&address,&p2,&id);
7579 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007580 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007581 psource_frame->nFlags,psource_frame->nFilledLen);
7582 }
7583 }
7584 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007585}
7586
7587OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7588{
7589 OMX_U8 *buf, *pdest;
7590 OMX_U32 partial_frame = 1;
7591 OMX_U32 buf_len, dest_len;
7592
Arun Menon906de572013-06-18 17:01:40 -07007593 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007594 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007595 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007596 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007597 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007598 buf = psource_frame->pBuffer;
7599 buf_len = psource_frame->nFilledLen;
7600
7601 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007602 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007603 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007604 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007605 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007606 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007607 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007608 return OMX_ErrorStreamCorrupt;
7609 }
Arun Menon906de572013-06-18 17:01:40 -07007610 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007611 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7612 pdest_frame->nOffset;
7613 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007614 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007615
Arun Menon906de572013-06-18 17:01:40 -07007616 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007617 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007618 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007619 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007620 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7621 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7622 }
7623 }
7624 }
7625
Arun Menon906de572013-06-18 17:01:40 -07007626 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007627 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007628 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007629 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007630 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007631 return OMX_ErrorBadParameter;
7632 }
Arun Menon906de572013-06-18 17:01:40 -07007633 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007634
7635 case VC1_SP_MP_RCV:
7636 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007637 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007638 return OMX_ErrorBadParameter;
7639 }
7640 return OMX_ErrorNone;
7641}
7642
David Ng38e2d232013-03-15 20:05:58 -07007643#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007644bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007645 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007646{
Arun Menon906de572013-06-18 17:01:40 -07007647 struct pmem_allocation allocation;
7648 allocation.size = buffer_size;
7649 allocation.align = clip2(alignment);
7650 if (allocation.align < 4096) {
7651 allocation.align = 4096;
7652 }
7653 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007654 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007655 allocation.align, allocation.size);
7656 return false;
7657 }
7658 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007659}
David Ng38e2d232013-03-15 20:05:58 -07007660#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007661#ifdef USE_ION
7662int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007663 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7664 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007665{
Arun Menon906de572013-06-18 17:01:40 -07007666 int fd = -EINVAL;
7667 int rc = -EINVAL;
7668 int ion_dev_flag;
7669 struct vdec_ion ion_buf_info;
7670 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007671 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007672 return -EINVAL;
7673 }
7674 ion_dev_flag = O_RDONLY;
7675 fd = open (MEM_DEVICE, ion_dev_flag);
7676 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007677 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007678 return fd;
7679 }
7680 alloc_data->flags = 0;
7681 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7682 alloc_data->flags |= ION_FLAG_CACHED;
7683 }
7684 alloc_data->len = buffer_size;
7685 alloc_data->align = clip2(alignment);
7686 if (alloc_data->align < 4096) {
7687 alloc_data->align = 4096;
7688 }
7689 if ((secure_mode) && (flag & ION_SECURE))
7690 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007691
Arun Menon906de572013-06-18 17:01:40 -07007692 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307693 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007694 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7695 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7696 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007697 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007698 alloc_data->handle = NULL;
7699 close(fd);
7700 fd = -ENOMEM;
7701 return fd;
7702 }
7703 fd_data->handle = alloc_data->handle;
7704 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7705 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007706 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007707 ion_buf_info.ion_alloc_data = *alloc_data;
7708 ion_buf_info.ion_device_fd = fd;
7709 ion_buf_info.fd_ion_data = *fd_data;
7710 free_ion_memory(&ion_buf_info);
7711 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007712 fd = -ENOMEM;
7713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007714
Arun Menon906de572013-06-18 17:01:40 -07007715 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007716}
7717
Arun Menon906de572013-06-18 17:01:40 -07007718void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7719{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007720
Arun Menon906de572013-06-18 17:01:40 -07007721 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007722 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007723 return;
7724 }
7725 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7726 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007727 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007728 }
7729 close(buf_ion_info->ion_device_fd);
7730 buf_ion_info->ion_device_fd = -1;
7731 buf_ion_info->ion_alloc_data.handle = NULL;
7732 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007733}
7734#endif
7735void omx_vdec::free_output_buffer_header()
7736{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007737 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007738 output_use_buffer = false;
7739 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007740
Arun Menon906de572013-06-18 17:01:40 -07007741 if (m_out_mem_ptr) {
7742 free (m_out_mem_ptr);
7743 m_out_mem_ptr = NULL;
7744 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007745
Arun Menon906de572013-06-18 17:01:40 -07007746 if (m_platform_list) {
7747 free(m_platform_list);
7748 m_platform_list = NULL;
7749 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007750
Arun Menon906de572013-06-18 17:01:40 -07007751 if (drv_ctx.ptr_respbuffer) {
7752 free (drv_ctx.ptr_respbuffer);
7753 drv_ctx.ptr_respbuffer = NULL;
7754 }
7755 if (drv_ctx.ptr_outputbuffer) {
7756 free (drv_ctx.ptr_outputbuffer);
7757 drv_ctx.ptr_outputbuffer = NULL;
7758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007759#ifdef USE_ION
7760 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007761 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007762 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007763 drv_ctx.op_buf_ion_info = NULL;
7764 }
7765#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007766 if (out_dynamic_list) {
7767 free(out_dynamic_list);
7768 out_dynamic_list = NULL;
7769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007770}
7771
7772void omx_vdec::free_input_buffer_header()
7773{
7774 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007775 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007776 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007777 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007778 free (m_inp_heap_ptr);
7779 m_inp_heap_ptr = NULL;
7780 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007781
Arun Menon906de572013-06-18 17:01:40 -07007782 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007783 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007784 free (m_phdr_pmem_ptr);
7785 m_phdr_pmem_ptr = NULL;
7786 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007787 }
Arun Menon906de572013-06-18 17:01:40 -07007788 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007789 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007790 free (m_inp_mem_ptr);
7791 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007792 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007793 /* We just freed all the buffer headers, every thing in m_input_free_q,
7794 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007795 while (m_input_free_q.m_size) {
7796 unsigned address, p2, id;
7797 m_input_free_q.pop_entry(&address, &p2, &id);
7798 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007799 while (m_input_pending_q.m_size) {
7800 unsigned address, p2, id;
7801 m_input_pending_q.pop_entry(&address, &p2, &id);
7802 }
7803 pdest_frame = NULL;
7804 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007805 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007806 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007807 free (drv_ctx.ptr_inputbuffer);
7808 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007809 }
7810#ifdef USE_ION
7811 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007812 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007813 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007814 drv_ctx.ip_buf_ion_info = NULL;
7815 }
7816#endif
7817}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007818
7819int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007820{
Arun Menon906de572013-06-18 17:01:40 -07007821 enum v4l2_buf_type btype;
7822 int rc = 0;
7823 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007824
Arun Menon906de572013-06-18 17:01:40 -07007825 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7826 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7827 v4l2_port = OUTPUT_PORT;
7828 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7829 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7830 v4l2_port = CAPTURE_PORT;
7831 } else if (port == OMX_ALL) {
7832 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7833 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007834
Arun Menon906de572013-06-18 17:01:40 -07007835 if (!rc_input)
7836 return rc_input;
7837 else
7838 return rc_output;
7839 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007840
Arun Menon906de572013-06-18 17:01:40 -07007841 if (!streaming[v4l2_port]) {
7842 // already streamed off, warn and move on
7843 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7844 " which is already streamed off", v4l2_port);
7845 return 0;
7846 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007847
Arun Menon906de572013-06-18 17:01:40 -07007848 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007849
Arun Menon906de572013-06-18 17:01:40 -07007850 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7851 if (rc) {
7852 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007853 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007854 } else {
7855 streaming[v4l2_port] = false;
7856 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007857
Arun Menon906de572013-06-18 17:01:40 -07007858 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007859}
7860
7861OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7862{
Arun Menon906de572013-06-18 17:01:40 -07007863 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7864 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07007865 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307866 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007867 struct v4l2_format fmt;
7868 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007869 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007870 buffer_prop->actualcount, buffer_prop->buffer_size);
7871 bufreq.memory = V4L2_MEMORY_USERPTR;
7872 bufreq.count = 1;
7873 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7874 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7875 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7876 fmt.fmt.pix_mp.pixelformat = output_capability;
7877 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7878 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7879 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7880 fmt.fmt.pix_mp.pixelformat = capture_capability;
7881 } else {
7882 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007883 }
Arun Menon906de572013-06-18 17:01:40 -07007884 if (eRet==OMX_ErrorNone) {
7885 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007886 }
Arun Menon906de572013-06-18 17:01:40 -07007887 if (ret) {
7888 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7889 /*TODO: How to handle this case */
7890 eRet = OMX_ErrorInsufficientResources;
7891 return eRet;
7892 } else {
7893 buffer_prop->actualcount = bufreq.count;
7894 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007895 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896 }
Arun Menon906de572013-06-18 17:01:40 -07007897 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7898 buffer_prop->actualcount, buffer_prop->buffer_size);
7899
7900 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7901 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7902
7903 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7904
7905 update_resolution(fmt.fmt.pix_mp.width,
7906 fmt.fmt.pix_mp.height,
7907 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7908 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7909 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7910 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007911 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007912
7913 if (ret) {
7914 /*TODO: How to handle this case */
7915 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7916 eRet = OMX_ErrorInsufficientResources;
7917 } else {
7918 int extra_idx = 0;
7919
7920 eRet = is_video_session_supported();
7921 if (eRet)
7922 return eRet;
7923
7924 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7925 buf_size = buffer_prop->buffer_size;
7926 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7927 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7928 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7929 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007930 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007931 return OMX_ErrorBadParameter;
7932 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007933
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07007934 default_extra_data_size = VENUS_EXTRADATA_SIZE(
7935 drv_ctx.video_resolution.frame_height,
7936 drv_ctx.video_resolution.frame_width);
7937 final_extra_data_size = extra_data_size > default_extra_data_size ?
7938 extra_data_size : default_extra_data_size;
7939
7940 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
7941 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07007942
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307943 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007944 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307945 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05307946 if (!secure_mode)
7947 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007948 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7949 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7950 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08007951 if (extra_data_size)
7952 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
7953 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
7954
Arun Menon906de572013-06-18 17:01:40 -07007955 if (in_reconfig) // BufReq will be set to driver when port is disabled
7956 buffer_prop->buffer_size = buf_size;
7957 else if (buf_size != buffer_prop->buffer_size) {
7958 buffer_prop->buffer_size = buf_size;
7959 eRet = set_buffer_req(buffer_prop);
7960 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007961 }
Arun Menon906de572013-06-18 17:01:40 -07007962 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7963 buffer_prop->actualcount, buffer_prop->buffer_size);
7964 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007965}
7966
7967OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7968{
Arun Menon906de572013-06-18 17:01:40 -07007969 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7970 unsigned buf_size = 0;
7971 struct v4l2_format fmt;
7972 struct v4l2_requestbuffers bufreq;
7973 int ret;
7974 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7975 buffer_prop->actualcount, buffer_prop->buffer_size);
7976 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7977 if (buf_size != buffer_prop->buffer_size) {
7978 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7979 buffer_prop->buffer_size, buf_size);
7980 eRet = OMX_ErrorBadParameter;
7981 } else {
7982 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7983 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007984
Arun Menon906de572013-06-18 17:01:40 -07007985 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7986 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7987 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007988 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007989 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7990 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7991 fmt.fmt.pix_mp.pixelformat = capture_capability;
7992 } else {
7993 eRet = OMX_ErrorBadParameter;
7994 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007995
Arun Menon906de572013-06-18 17:01:40 -07007996 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7997 if (ret) {
7998 /*TODO: How to handle this case */
7999 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8000 eRet = OMX_ErrorInsufficientResources;
8001 }
8002
8003 bufreq.memory = V4L2_MEMORY_USERPTR;
8004 bufreq.count = buffer_prop->actualcount;
8005 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8006 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8007 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8008 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8009 } else {
8010 eRet = OMX_ErrorBadParameter;
8011 }
8012
8013 if (eRet==OMX_ErrorNone) {
8014 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8015 }
8016
8017 if (ret) {
8018 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8019 /*TODO: How to handle this case */
8020 eRet = OMX_ErrorInsufficientResources;
8021 } else if (bufreq.count < buffer_prop->actualcount) {
8022 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8023 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8024 buffer_prop->actualcount, bufreq.count);
8025 eRet = OMX_ErrorInsufficientResources;
8026 } else {
8027 if (!client_buffers.update_buffer_req()) {
8028 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8029 eRet = OMX_ErrorInsufficientResources;
8030 }
8031 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008032 }
Arun Menon906de572013-06-18 17:01:40 -07008033 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008034}
8035
Shalaj Jain273b3e02012-06-22 19:08:03 -07008036OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8037{
Arun Menon906de572013-06-18 17:01:40 -07008038 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8039 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008040}
8041
8042OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8043{
Arun Menon906de572013-06-18 17:01:40 -07008044 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308045 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008046 if (!portDefn) {
8047 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008048 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008049 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008050 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8051 portDefn->nSize = sizeof(portDefn);
8052 portDefn->eDomain = OMX_PortDomainVideo;
8053 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008054 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8055 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008056 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008057 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008058 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008059 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308060 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008061 if (0 == portDefn->nPortIndex) {
8062 portDefn->eDir = OMX_DirInput;
8063 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8064 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8065 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8066 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8067 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8068 portDefn->bEnabled = m_inp_bEnabled;
8069 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308070
8071 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8072 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008073 } else if (1 == portDefn->nPortIndex) {
8074 unsigned int buf_size = 0;
8075 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008076 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008077 return OMX_ErrorHardware;
8078 }
8079 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008080 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008081 return OMX_ErrorHardware;
8082 }
8083 portDefn->nBufferSize = buf_size;
8084 portDefn->eDir = OMX_DirOutput;
8085 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8086 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8087 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8088 portDefn->bEnabled = m_out_bEnabled;
8089 portDefn->bPopulated = m_out_bPopulated;
8090 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008091 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008092 return OMX_ErrorHardware;
8093 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308094 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8095 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008096 } else {
8097 portDefn->eDir = OMX_DirMax;
8098 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8099 (int)portDefn->nPortIndex);
8100 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008101 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308102 if (is_down_scalar_enabled) {
8103 int ret = 0;
8104 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8105 if (ret) {
8106 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8107 return OMX_ErrorHardware;
8108 } else {
8109 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8110 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8111 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8112 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8113 }
8114 } else {
8115 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8116 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8117 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8118 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8119 }
8120
Praveen Chavandb7776f2014-02-06 18:17:25 -08008121 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8122 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308123 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8124 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8125 }
8126 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8127 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8128 portDefn->nPortIndex,
8129 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008130 portDefn->format.video.nFrameHeight,
8131 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308132 portDefn->format.video.nSliceHeight,
8133 portDefn->format.video.eColorFormat,
8134 portDefn->nBufferSize,
8135 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008136
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308137 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008138}
8139
8140OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8141{
Arun Menon906de572013-06-18 17:01:40 -07008142 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8143 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8144 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008145
Arun Menon906de572013-06-18 17:01:40 -07008146 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008147 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008148 int nBufHdrSize = 0;
8149 int nPlatformEntrySize = 0;
8150 int nPlatformListSize = 0;
8151 int nPMEMInfoSize = 0;
8152 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8153 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8154 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008155
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008156 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008157 drv_ctx.op_buf.actualcount);
8158 nBufHdrSize = drv_ctx.op_buf.actualcount *
8159 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008160
Arun Menon906de572013-06-18 17:01:40 -07008161 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8162 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8163 nPlatformListSize = drv_ctx.op_buf.actualcount *
8164 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8165 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8166 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008167
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008168 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008169 sizeof(OMX_BUFFERHEADERTYPE),
8170 nPMEMInfoSize,
8171 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008172 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008173 m_out_bm_count);
8174 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8175 // Alloc mem for platform specific info
8176 char *pPtr=NULL;
8177 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8178 nPMEMInfoSize,1);
8179 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8180 calloc (sizeof(struct vdec_bufferpayload),
8181 drv_ctx.op_buf.actualcount);
8182 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8183 calloc (sizeof (struct vdec_output_frameinfo),
8184 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008185 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8186 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8187 return OMX_ErrorInsufficientResources;
8188 }
8189
Shalaj Jain273b3e02012-06-22 19:08:03 -07008190#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008191 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8192 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008193 if (!drv_ctx.op_buf_ion_info) {
8194 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8195 return OMX_ErrorInsufficientResources;
8196 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008197#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008198 if (dynamic_buf_mode) {
8199 out_dynamic_list = (struct dynamic_buf_list *) \
8200 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8201 }
Arun Menon906de572013-06-18 17:01:40 -07008202 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8203 && drv_ctx.ptr_respbuffer) {
8204 bufHdr = m_out_mem_ptr;
8205 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8206 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8207 (((char *) m_platform_list) + nPlatformListSize);
8208 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8209 (((char *) m_platform_entry) + nPlatformEntrySize);
8210 pPlatformList = m_platform_list;
8211 pPlatformEntry = m_platform_entry;
8212 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008213
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008214 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008215
Arun Menon906de572013-06-18 17:01:40 -07008216 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008217 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008218 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008219 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008220 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8221 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8222 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8223 // Set the values when we determine the right HxW param
8224 bufHdr->nAllocLen = 0;
8225 bufHdr->nFilledLen = 0;
8226 bufHdr->pAppPrivate = NULL;
8227 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8228 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8229 pPlatformEntry->entry = pPMEMInfo;
8230 // Initialize the Platform List
8231 pPlatformList->nEntries = 1;
8232 pPlatformList->entryList = pPlatformEntry;
8233 // Keep pBuffer NULL till vdec is opened
8234 bufHdr->pBuffer = NULL;
8235 pPMEMInfo->offset = 0;
8236 pPMEMInfo->pmem_fd = 0;
8237 bufHdr->pPlatformPrivate = pPlatformList;
8238 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008239#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008240 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008241#endif
Arun Menon906de572013-06-18 17:01:40 -07008242 /*Create a mapping between buffers*/
8243 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8244 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8245 &drv_ctx.ptr_outputbuffer[i];
8246 // Move the buffer and buffer header pointers
8247 bufHdr++;
8248 pPMEMInfo++;
8249 pPlatformEntry++;
8250 pPlatformList++;
8251 }
8252 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008253 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008254 m_out_mem_ptr, pPtr);
8255 if (m_out_mem_ptr) {
8256 free(m_out_mem_ptr);
8257 m_out_mem_ptr = NULL;
8258 }
8259 if (pPtr) {
8260 free(pPtr);
8261 pPtr = NULL;
8262 }
8263 if (drv_ctx.ptr_outputbuffer) {
8264 free(drv_ctx.ptr_outputbuffer);
8265 drv_ctx.ptr_outputbuffer = NULL;
8266 }
8267 if (drv_ctx.ptr_respbuffer) {
8268 free(drv_ctx.ptr_respbuffer);
8269 drv_ctx.ptr_respbuffer = NULL;
8270 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008271#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008272 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008273 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008274 free(drv_ctx.op_buf_ion_info);
8275 drv_ctx.op_buf_ion_info = NULL;
8276 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008277#endif
Arun Menon906de572013-06-18 17:01:40 -07008278 eRet = OMX_ErrorInsufficientResources;
8279 }
8280 } else {
8281 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008282 }
Arun Menon906de572013-06-18 17:01:40 -07008283 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008284}
8285
8286void omx_vdec::complete_pending_buffer_done_cbs()
8287{
Arun Menon906de572013-06-18 17:01:40 -07008288 unsigned p1;
8289 unsigned p2;
8290 unsigned ident;
8291 omx_cmd_queue tmp_q, pending_bd_q;
8292 pthread_mutex_lock(&m_lock);
8293 // pop all pending GENERATE FDB from ftb queue
8294 while (m_ftb_q.m_size) {
8295 m_ftb_q.pop_entry(&p1,&p2,&ident);
8296 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8297 pending_bd_q.insert_entry(p1,p2,ident);
8298 } else {
8299 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008300 }
Arun Menon906de572013-06-18 17:01:40 -07008301 }
8302 //return all non GENERATE FDB to ftb queue
8303 while (tmp_q.m_size) {
8304 tmp_q.pop_entry(&p1,&p2,&ident);
8305 m_ftb_q.insert_entry(p1,p2,ident);
8306 }
8307 // pop all pending GENERATE EDB from etb queue
8308 while (m_etb_q.m_size) {
8309 m_etb_q.pop_entry(&p1,&p2,&ident);
8310 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8311 pending_bd_q.insert_entry(p1,p2,ident);
8312 } else {
8313 tmp_q.insert_entry(p1,p2,ident);
8314 }
8315 }
8316 //return all non GENERATE FDB to etb queue
8317 while (tmp_q.m_size) {
8318 tmp_q.pop_entry(&p1,&p2,&ident);
8319 m_etb_q.insert_entry(p1,p2,ident);
8320 }
8321 pthread_mutex_unlock(&m_lock);
8322 // process all pending buffer dones
8323 while (pending_bd_q.m_size) {
8324 pending_bd_q.pop_entry(&p1,&p2,&ident);
8325 switch (ident) {
8326 case OMX_COMPONENT_GENERATE_EBD:
8327 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008328 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008329 omx_report_error ();
8330 }
8331 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008332
Arun Menon906de572013-06-18 17:01:40 -07008333 case OMX_COMPONENT_GENERATE_FBD:
8334 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008335 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008336 omx_report_error ();
8337 }
8338 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008339 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008340 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008341}
8342
8343void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8344{
Arun Menon906de572013-06-18 17:01:40 -07008345 OMX_U32 new_frame_interval = 0;
8346 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8347 && llabs(act_timestamp - prev_ts) > 2000) {
8348 new_frame_interval = client_set_fps ? frm_int :
8349 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008350 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008351 frm_int = new_frame_interval;
8352 if (frm_int) {
8353 drv_ctx.frame_rate.fps_numerator = 1e6;
8354 drv_ctx.frame_rate.fps_denominator = frm_int;
8355 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8356 frm_int, drv_ctx.frame_rate.fps_numerator /
8357 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008358
Arun Menon906de572013-06-18 17:01:40 -07008359 /* We need to report the difference between this FBD and the previous FBD
8360 * back to the driver for clock scaling purposes. */
8361 struct v4l2_outputparm oparm;
8362 /*XXX: we're providing timing info as seconds per frame rather than frames
8363 * per second.*/
8364 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8365 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008366
Arun Menon906de572013-06-18 17:01:40 -07008367 struct v4l2_streamparm sparm;
8368 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8369 sparm.parm.output = oparm;
8370 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8371 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8372 performance might be affected");
8373 }
8374
8375 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008376 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008377 }
Arun Menon906de572013-06-18 17:01:40 -07008378 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008379}
8380
8381void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8382{
Arun Menon906de572013-06-18 17:01:40 -07008383 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8384 prev_ts = act_timestamp;
8385 rst_prev_ts = false;
8386 } else if (VALID_TS(prev_ts)) {
8387 bool codec_cond = (drv_ctx.timestamp_adjust)?
8388 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8389 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8390 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8391 if (frm_int > 0 && codec_cond) {
8392 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8393 act_timestamp = prev_ts + frm_int;
8394 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8395 prev_ts = act_timestamp;
8396 } else
8397 set_frame_rate(act_timestamp);
8398 } else if (frm_int > 0) // In this case the frame rate was set along
8399 { // with the port definition, start ts with 0
8400 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8401 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008403}
8404
8405void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8406{
Arun Menon906de572013-06-18 17:01:40 -07008407 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8408 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308409 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008410 OMX_U32 frame_rate = 0;
8411 int consumed_len = 0;
8412 OMX_U32 num_MB_in_frame;
8413 OMX_U32 recovery_sei_flags = 1;
8414 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008415
Arun Menon906de572013-06-18 17:01:40 -07008416 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008417 if (buf_index >= drv_ctx.extradata_info.count) {
8418 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8419 buf_index, drv_ctx.extradata_info.count);
8420 return;
8421 }
Arun Menon906de572013-06-18 17:01:40 -07008422 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8423 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8424 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308425
Arun Menon906de572013-06-18 17:01:40 -07008426 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308427 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008428 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008429 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308430
8431 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8432 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8433 p_extra = NULL;
8434 return;
8435 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308436 if (!secure_mode)
8437 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008438 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308439 else
8440 p_extra = m_other_extradata;
8441
Arun Menon906de572013-06-18 17:01:40 -07008442 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308443 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8444 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008445 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308446 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008447 }
Arun Menon906de572013-06-18 17:01:40 -07008448 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008449 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008450 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8451 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308452 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008453 DEBUG_PRINT_LOW("Invalid extra data size");
8454 break;
8455 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308456 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008457 switch ((unsigned long)data->eType) {
8458 case EXTRADATA_INTERLACE_VIDEO:
8459 struct msm_vidc_interlace_payload *payload;
8460 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008461 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008462 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008463 switch (payload->format) {
8464 case INTERLACE_FRAME_PROGRESSIVE:
8465 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8466 enable = 0;
8467 break;
8468 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8469 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8470 break;
8471 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8472 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8473 break;
8474 default:
8475 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8476 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8477 }
Arun Menon906de572013-06-18 17:01:40 -07008478 }
8479 if (m_enable_android_native_buffers)
8480 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8481 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308482 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008483 append_interlace_extradata(p_extra, payload->format,
8484 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008485 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8486 }
8487 break;
8488 case EXTRADATA_FRAME_RATE:
8489 struct msm_vidc_framerate_payload *frame_rate_payload;
8490 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8491 frame_rate = frame_rate_payload->frame_rate;
8492 break;
8493 case EXTRADATA_TIMESTAMP:
8494 struct msm_vidc_ts_payload *time_stamp_payload;
8495 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308496 time_stamp = time_stamp_payload->timestamp_lo;
8497 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8498 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008499 break;
8500 case EXTRADATA_NUM_CONCEALED_MB:
8501 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8502 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8503 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8504 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8505 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8506 break;
8507 case EXTRADATA_INDEX:
8508 int *etype;
8509 etype = (int *)(data->data);
8510 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8511 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8512 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8513 if (aspect_ratio_payload) {
8514 ((struct vdec_output_frameinfo *)
8515 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8516 ((struct vdec_output_frameinfo *)
8517 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8518 }
8519 }
8520 break;
8521 case EXTRADATA_RECOVERY_POINT_SEI:
8522 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8523 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8524 recovery_sei_flags = recovery_sei_payload->flags;
8525 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8526 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008527 DEBUG_PRINT_HIGH("");
8528 DEBUG_PRINT_HIGH("***************************************************");
8529 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8530 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008531 }
8532 break;
8533 case EXTRADATA_PANSCAN_WINDOW:
8534 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8535 break;
8536 case EXTRADATA_MPEG2_SEQDISP:
8537 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8538 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8539 if (seqdisp_payload) {
8540 m_disp_hor_size = seqdisp_payload->disp_width;
8541 m_disp_vert_size = seqdisp_payload->disp_height;
8542 }
8543 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308544 case EXTRADATA_S3D_FRAME_PACKING:
8545 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8546 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308547 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308548 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8549 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8550 }
8551 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008552 case EXTRADATA_FRAME_QP:
8553 struct msm_vidc_frame_qp_payload *qp_payload;
8554 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308555 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008556 append_qp_extradata(p_extra, qp_payload);
8557 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8558 }
8559 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008560 case EXTRADATA_FRAME_BITS_INFO:
8561 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8562 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308563 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008564 append_bitsinfo_extradata(p_extra, bits_info_payload);
8565 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8566 }
8567 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008568 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308569 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008570 append_user_extradata(p_extra, data);
8571 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8572 }
8573 break;
Arun Menon906de572013-06-18 17:01:40 -07008574 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008575 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008576 goto unrecognized_extradata;
8577 }
8578 consumed_len += data->nSize;
8579 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8580 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308581 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008582 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8583 append_frame_info_extradata(p_extra,
8584 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308585 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008586 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008587 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008588 }
8589 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008590unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008591 if (client_extradata && p_extra) {
8592 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008593 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008594 }
8595
Arun Menonfd723932014-05-30 17:56:31 -07008596 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308597 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8598 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8599 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8600 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8601 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8602 }
Arun Menon906de572013-06-18 17:01:40 -07008603 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008604}
8605
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008606OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008607 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008608{
Arun Menon906de572013-06-18 17:01:40 -07008609 OMX_ERRORTYPE ret = OMX_ErrorNone;
8610 struct v4l2_control control;
8611 if (m_state != OMX_StateLoaded) {
8612 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8613 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008614 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008615 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008616 client_extradata, requested_extradata, enable, is_internal);
8617
8618 if (!is_internal) {
8619 if (enable)
8620 client_extradata |= requested_extradata;
8621 else
8622 client_extradata = client_extradata & ~requested_extradata;
8623 }
8624
8625 if (enable) {
8626 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8627 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8628 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8629 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8630 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008631 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008632 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308633 }
8634 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008635 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8636 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8637 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008638 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008639 }
8640 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8641 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8642 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008643 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008644 }
8645 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8646 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8647 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008648 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008649 }
8650 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8651 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8652 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008653 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008654 }
8655 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8656 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8657 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008658 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008659 }
8660 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8661 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8662 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8663 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008664 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008665 }
8666 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308667 }
8668 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008669 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8670 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8671 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008672 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008673 }
8674 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308675 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8676 if (output_capability == V4L2_PIX_FMT_H264) {
8677 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8678 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8679 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8680 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8681 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8682 }
8683 } else {
8684 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8685 }
8686 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008687 if (requested_extradata & OMX_QP_EXTRADATA) {
8688 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8689 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8690 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8691 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8692 }
8693 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008694 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8695 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8696 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8697 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8698 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8699 }
8700 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008701 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8702 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8703 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8704 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8705 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8706 }
8707 }
Arun Menon906de572013-06-18 17:01:40 -07008708 }
8709 ret = get_buffer_req(&drv_ctx.op_buf);
8710 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008711}
8712
8713OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8714{
Arun Menon906de572013-06-18 17:01:40 -07008715 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8716 OMX_U8 *data_ptr = extra->data, data = 0;
8717 while (byte_count < extra->nDataSize) {
8718 data = *data_ptr;
8719 while (data) {
8720 num_MB += (data&0x01);
8721 data >>= 1;
8722 }
8723 data_ptr++;
8724 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008725 }
Arun Menon906de572013-06-18 17:01:40 -07008726 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8727 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8728 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008729}
8730
8731void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8732{
Arun Menon906de572013-06-18 17:01:40 -07008733 if (!m_debug_extradata)
8734 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008735
8736 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308737 "============== Extra Data ==============\n"
8738 " Size: %lu\n"
8739 " Version: %lu\n"
8740 " PortIndex: %lu\n"
8741 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008742 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008743 extra->nSize, extra->nVersion.nVersion,
8744 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008745
Arun Menon906de572013-06-18 17:01:40 -07008746 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8747 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8748 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308749 "------ Interlace Format ------\n"
8750 " Size: %lu\n"
8751 " Version: %lu\n"
8752 " PortIndex: %lu\n"
8753 " Is Interlace Format: %d\n"
8754 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008755 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008756 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8757 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8758 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8759 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8760
8761 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308762 "-------- Frame Format --------\n"
8763 " Picture Type: %d\n"
8764 " Interlace Type: %d\n"
8765 " Pan Scan Total Frame Num: %lu\n"
8766 " Concealed Macro Blocks: %lu\n"
8767 " frame rate: %lu\n"
8768 " Time Stamp: %llu\n"
8769 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008770 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008771 fminfo->ePicType,
8772 fminfo->interlaceType,
8773 fminfo->panScan.numWindows,
8774 fminfo->nConcealedMacroblocks,
8775 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308776 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008777 fminfo->aspectRatio.aspectRatioX,
8778 fminfo->aspectRatio.aspectRatioY);
8779
8780 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8781 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008782 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308783 " Pan Scan Frame Num: %lu\n"
8784 " Rectangle x: %ld\n"
8785 " Rectangle y: %ld\n"
8786 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008787 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008788 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8789 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8790 }
8791
8792 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308793 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8794 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8795 DEBUG_PRINT_HIGH(
8796 "------------------ Framepack Format ----------\n"
8797 " id: %lu \n"
8798 " cancel_flag: %lu \n"
8799 " type: %lu \n"
8800 " quincunx_sampling_flagFormat: %lu \n"
8801 " content_interpretation_type: %lu \n"
8802 " content_interpretation_type: %lu \n"
8803 " spatial_flipping_flag: %lu \n"
8804 " frame0_flipped_flag: %lu \n"
8805 " field_views_flag: %lu \n"
8806 " current_frame_is_frame0_flag: %lu \n"
8807 " frame0_self_contained_flag: %lu \n"
8808 " frame1_self_contained_flag: %lu \n"
8809 " frame0_grid_position_x: %lu \n"
8810 " frame0_grid_position_y: %lu \n"
8811 " frame1_grid_position_x: %lu \n"
8812 " frame1_grid_position_y: %lu \n"
8813 " reserved_byte: %lu \n"
8814 " repetition_period: %lu \n"
8815 " extension_flag: %lu \n"
8816 "================== End of Framepack ===========",
8817 framepack->id,
8818 framepack->cancel_flag,
8819 framepack->type,
8820 framepack->quincunx_sampling_flag,
8821 framepack->content_interpretation_type,
8822 framepack->spatial_flipping_flag,
8823 framepack->frame0_flipped_flag,
8824 framepack->field_views_flag,
8825 framepack->current_frame_is_frame0_flag,
8826 framepack->frame0_self_contained_flag,
8827 framepack->frame1_self_contained_flag,
8828 framepack->frame0_grid_position_x,
8829 framepack->frame0_grid_position_y,
8830 framepack->frame1_grid_position_x,
8831 framepack->frame1_grid_position_y,
8832 framepack->reserved_byte,
8833 framepack->repetition_period,
8834 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008835 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8836 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8837 DEBUG_PRINT_HIGH(
8838 "---- QP (Frame quantization parameter) ----\n"
8839 " Frame QP: %lu \n"
8840 "================ End of QP ================\n",
8841 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008842 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8843 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8844 DEBUG_PRINT_HIGH(
8845 "--------- Input bits information --------\n"
8846 " Header bits: %lu \n"
8847 " Frame bits: %lu \n"
8848 "===== End of Input bits information =====\n",
8849 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008850 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
8851 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
8852 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
8853 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
8854 OMX_U32 i = 0;
8855 DEBUG_PRINT_HIGH(
8856 "-------------- Userdata -------------\n"
8857 " Stream userdata type: %d\n"
8858 " userdata size: %d\n"
8859 " STREAM_USERDATA:",
8860 userdata->type, userdata_size);
8861 for (i = 0; i < userdata_size; i+=4) {
8862 DEBUG_PRINT_HIGH(" %x %x %x %x",
8863 data_ptr[i], data_ptr[i+1],
8864 data_ptr[i+2], data_ptr[i+3]);
8865 }
8866 DEBUG_PRINT_HIGH(
8867 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07008868 } else if (extra->eType == OMX_ExtraDataNone) {
8869 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8870 } else {
8871 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008872 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008873}
8874
8875void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08008876 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008877{
Arun Menon906de572013-06-18 17:01:40 -07008878 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08008879
Arun Menon906de572013-06-18 17:01:40 -07008880 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8881 return;
8882 }
8883 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8884 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8885 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8886 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8887 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8888 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8889 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8890 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8891 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08008892
8893 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07008894 interlace_format->bInterlaceFormat = OMX_FALSE;
8895 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8896 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008897 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008898 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008899 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008900 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008901 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008902 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008903 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008904 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008905 } else {
8906 interlace_format->bInterlaceFormat = OMX_TRUE;
8907 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8908 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8909 }
8910 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008911}
8912
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008913void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008914 struct vdec_aspectratioinfo *aspect_ratio_info,
8915 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008916{
Arun Menon906de572013-06-18 17:01:40 -07008917 m_extradata = frame_info;
8918 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8919 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308920 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008921 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008922}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008923
8924void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008925 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308926 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008927 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008928{
Arun Menon906de572013-06-18 17:01:40 -07008929 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8930 struct msm_vidc_panscan_window *panscan_window;
8931 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008932 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008933 }
Arun Menon906de572013-06-18 17:01:40 -07008934 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8935 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8936 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8937 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8938 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8939 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8940 switch (picture_type) {
8941 case PICTURE_TYPE_I:
8942 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8943 break;
8944 case PICTURE_TYPE_P:
8945 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8946 break;
8947 case PICTURE_TYPE_B:
8948 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8949 break;
8950 default:
8951 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8952 }
8953 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8954 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8955 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8956 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8957 else
8958 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8959 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8960 frame_info->nConcealedMacroblocks = num_conceal_mb;
8961 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308962 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008963 frame_info->panScan.numWindows = 0;
8964 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8965 if (m_disp_hor_size && m_disp_vert_size) {
8966 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8967 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05308968 } else {
8969 frame_info->displayAspectRatio.displayHorizontalSize = 0;
8970 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07008971 }
8972 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008973
Arun Menon906de572013-06-18 17:01:40 -07008974 if (panscan_payload) {
8975 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8976 panscan_window = &panscan_payload->wnd[0];
8977 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8978 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8979 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8980 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8981 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8982 panscan_window++;
8983 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008984 }
Arun Menon906de572013-06-18 17:01:40 -07008985 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8986 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008987}
8988
8989void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8990{
Arun Menon906de572013-06-18 17:01:40 -07008991 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8992 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8993 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8994 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8995 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8996 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8997 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8998 *portDefn = m_port_def;
8999 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009000 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009001 portDefn->format.video.nFrameWidth,
9002 portDefn->format.video.nStride,
9003 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009004}
9005
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309006void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9007 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9008{
9009 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9010 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9011 DEBUG_PRINT_ERROR("frame packing size mismatch");
9012 return;
9013 }
9014 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9015 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9016 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9017 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9018 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9019 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9020 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9021 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9022 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9023 memcpy(&framepack->id, s3d_frame_packing_payload,
9024 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9025 memcpy(&m_frame_pack_arrangement, framepack,
9026 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9027 print_debug_extradata(extra);
9028}
9029
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009030void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9031 struct msm_vidc_frame_qp_payload *qp_payload)
9032{
9033 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9034 if (!qp_payload) {
9035 DEBUG_PRINT_ERROR("QP payload is NULL");
9036 return;
9037 }
9038 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9039 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9040 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9041 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9042 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9043 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9044 qp->nQP = qp_payload->frame_qp;
9045 print_debug_extradata(extra);
9046}
9047
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009048void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9049 struct msm_vidc_frame_bits_info_payload *bits_payload)
9050{
9051 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9052 if (!bits_payload) {
9053 DEBUG_PRINT_ERROR("bits info payload is NULL");
9054 return;
9055 }
9056 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9057 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9058 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9059 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9060 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9061 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9062 bits->frame_bits = bits_payload->frame_bits;
9063 bits->header_bits = bits_payload->header_bits;
9064 print_debug_extradata(extra);
9065}
9066
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009067void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9068 OMX_OTHER_EXTRADATATYPE *p_user)
9069{
9070 int userdata_size = 0;
9071 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9072 userdata_payload =
9073 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9074 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009075 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009076 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9077 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9078 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9079 extra->nDataSize = userdata_size;
9080 if (extra->data && p_user->data && extra->nDataSize)
9081 memcpy(extra->data, p_user->data, extra->nDataSize);
9082 print_debug_extradata(extra);
9083}
9084
Shalaj Jain273b3e02012-06-22 19:08:03 -07009085void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9086{
Arun Menon906de572013-06-18 17:01:40 -07009087 if (!client_extradata) {
9088 return;
9089 }
9090 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9091 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9092 extra->eType = OMX_ExtraDataNone;
9093 extra->nDataSize = 0;
9094 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009095
Arun Menon906de572013-06-18 17:01:40 -07009096 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009097}
9098
9099OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9100{
Arun Menon906de572013-06-18 17:01:40 -07009101 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9102 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009103 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009104 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009105 }
Arun Menon906de572013-06-18 17:01:40 -07009106 if (m_desc_buffer_ptr == NULL) {
9107 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9108 calloc( (sizeof(desc_buffer_hdr)),
9109 drv_ctx.ip_buf.actualcount);
9110 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009111 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009112 return OMX_ErrorInsufficientResources;
9113 }
9114 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009115
Arun Menon906de572013-06-18 17:01:40 -07009116 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9117 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009118 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009119 return OMX_ErrorInsufficientResources;
9120 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009121
Arun Menon906de572013-06-18 17:01:40 -07009122 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009123}
9124
9125void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9126{
Arun Menon906de572013-06-18 17:01:40 -07009127 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9128 if (m_demux_entries < 8192) {
9129 m_demux_offsets[m_demux_entries++] = address_offset;
9130 }
9131 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009132}
9133
9134void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9135{
Arun Menon906de572013-06-18 17:01:40 -07009136 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9137 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9138 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009139
Arun Menon906de572013-06-18 17:01:40 -07009140 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009141
Arun Menon906de572013-06-18 17:01:40 -07009142 while (index < bytes_to_parse) {
9143 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9144 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9145 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9146 (buf[index+2] == 0x01)) ) {
9147 //Found start code, insert address offset
9148 insert_demux_addr_offset(index);
9149 if (buf[index+2] == 0x01) // 3 byte start code
9150 index += 3;
9151 else //4 byte start code
9152 index += 4;
9153 } else
9154 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009155 }
Arun Menon906de572013-06-18 17:01:40 -07009156 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9157 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009158}
9159
9160OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9161{
Arun Menon906de572013-06-18 17:01:40 -07009162 //fix this, handle 3 byte start code, vc1 terminator entry
9163 OMX_U8 *p_demux_data = NULL;
9164 OMX_U32 desc_data = 0;
9165 OMX_U32 start_addr = 0;
9166 OMX_U32 nal_size = 0;
9167 OMX_U32 suffix_byte = 0;
9168 OMX_U32 demux_index = 0;
9169 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009170
Arun Menon906de572013-06-18 17:01:40 -07009171 if (m_desc_buffer_ptr == NULL) {
9172 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9173 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009175
Arun Menon906de572013-06-18 17:01:40 -07009176 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9177 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9178 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9179 return OMX_ErrorBadParameter;
9180 }
9181
9182 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9183
9184 if ( ((OMX_U8*)p_demux_data == NULL) ||
9185 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9186 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9187 return OMX_ErrorBadParameter;
9188 } else {
9189 for (; demux_index < m_demux_entries; demux_index++) {
9190 desc_data = 0;
9191 start_addr = m_demux_offsets[demux_index];
9192 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9193 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9194 } else {
9195 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9196 }
9197 if (demux_index < (m_demux_entries - 1)) {
9198 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9199 } else {
9200 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9201 }
9202 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9203 (void *)start_addr,
9204 suffix_byte,
9205 nal_size,
9206 demux_index);
9207 desc_data = (start_addr >> 3) << 1;
9208 desc_data |= (start_addr & 7) << 21;
9209 desc_data |= suffix_byte << 24;
9210
9211 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9212 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9213 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9214 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9215
9216 p_demux_data += 16;
9217 }
9218 if (codec_type_parse == CODEC_TYPE_VC1) {
9219 DEBUG_PRINT_LOW("VC1 terminator entry");
9220 desc_data = 0;
9221 desc_data = 0x82 << 24;
9222 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9223 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9224 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9225 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9226 p_demux_data += 16;
9227 m_demux_entries++;
9228 }
9229 //Add zero word to indicate end of descriptors
9230 memset(p_demux_data, 0, sizeof(OMX_U32));
9231
9232 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9233 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9234 }
9235 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9236 m_demux_entries = 0;
9237 DEBUG_PRINT_LOW("Demux table complete!");
9238 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009239}
9240
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009241OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009242{
Arun Menon906de572013-06-18 17:01:40 -07009243 OMX_ERRORTYPE err = OMX_ErrorNone;
9244 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9245 if (iDivXDrmDecrypt) {
9246 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9247 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009248 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009249 delete iDivXDrmDecrypt;
9250 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009251 }
9252 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009253 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009254 err = OMX_ErrorUndefined;
9255 }
9256 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009257}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009258
Vinay Kaliada4f4422013-01-09 10:45:03 -08009259omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9260{
Arun Menon906de572013-06-18 17:01:40 -07009261 enabled = false;
9262 omx = NULL;
9263 init_members();
9264 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009265 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009266}
9267
9268void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9269{
Arun Menon906de572013-06-18 17:01:40 -07009270 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009271}
9272
Arun Menon906de572013-06-18 17:01:40 -07009273void omx_vdec::allocate_color_convert_buf::init_members()
9274{
9275 allocated_count = 0;
9276 buffer_size_req = 0;
9277 buffer_alignment_req = 0;
9278 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9279 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9280 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9281 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009282#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009283 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009284#endif
Arun Menon906de572013-06-18 17:01:40 -07009285 for (int i = 0; i < MAX_COUNT; i++)
9286 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009287}
9288
Arun Menon906de572013-06-18 17:01:40 -07009289omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9290{
9291 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009292}
9293
9294bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9295{
Arun Menon906de572013-06-18 17:01:40 -07009296 bool status = true;
9297 unsigned int src_size = 0, destination_size = 0;
9298 OMX_COLOR_FORMATTYPE drv_color_format;
9299 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009300 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009301 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009302 }
Arun Menon906de572013-06-18 17:01:40 -07009303 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009304 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009305 return status;
9306 }
9307 pthread_mutex_lock(&omx->c_lock);
9308 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9309 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009310 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009311 status = false;
9312 goto fail_update_buf_req;
9313 }
9314 c2d.close();
9315 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9316 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009317 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009318 if (status) {
9319 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9320 if (status)
9321 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9322 }
9323 if (status) {
9324 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9325 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009326 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009327 "driver size %d destination size %d",
9328 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9329 status = false;
9330 c2d.close();
9331 buffer_size_req = 0;
9332 } else {
9333 buffer_size_req = destination_size;
9334 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9335 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9336 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9337 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9338 }
9339 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009340fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009341 pthread_mutex_unlock(&omx->c_lock);
9342 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009343}
9344
9345bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009346 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009347{
Arun Menon906de572013-06-18 17:01:40 -07009348 bool status = true;
9349 OMX_COLOR_FORMATTYPE drv_color_format;
9350 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009351 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009352 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009353 }
Arun Menon906de572013-06-18 17:01:40 -07009354 pthread_mutex_lock(&omx->c_lock);
9355 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9356 drv_color_format = (OMX_COLOR_FORMATTYPE)
9357 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9358 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009359 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009360 status = false;
9361 }
9362 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009363 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009364 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9365 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009366 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009367 status = false;
9368 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009369 ColorFormat = dest_color_format;
9370 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9371 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009372 if (enabled)
9373 c2d.destroy();
9374 enabled = false;
9375 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009376 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009377 status = false;
9378 } else
9379 enabled = true;
9380 }
9381 } else {
9382 if (enabled)
9383 c2d.destroy();
9384 enabled = false;
9385 }
9386 pthread_mutex_unlock(&omx->c_lock);
9387 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009388}
9389
9390OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9391{
Arun Menon906de572013-06-18 17:01:40 -07009392 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009393 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009394 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009395 }
Arun Menon906de572013-06-18 17:01:40 -07009396 if (!enabled)
9397 return omx->m_out_mem_ptr;
9398 return m_out_mem_ptr_client;
9399}
9400
9401 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9402(OMX_BUFFERHEADERTYPE *bufadd)
9403{
9404 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009405 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009406 return NULL;
9407 }
9408 if (!enabled)
9409 return bufadd;
9410
9411 unsigned index = 0;
9412 index = bufadd - omx->m_out_mem_ptr;
9413 if (index < omx->drv_ctx.op_buf.actualcount) {
9414 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9415 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9416 bool status;
9417 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9418 pthread_mutex_lock(&omx->c_lock);
9419 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9420 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9421 pmem_baseaddress[index], pmem_baseaddress[index]);
9422 pthread_mutex_unlock(&omx->c_lock);
9423 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9424 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009425 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009426 m_out_mem_ptr_client[index].nFilledLen = 0;
9427 return &m_out_mem_ptr_client[index];
9428 }
9429 } else
9430 m_out_mem_ptr_client[index].nFilledLen = 0;
9431 return &m_out_mem_ptr_client[index];
9432 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009433 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009434 return NULL;
9435}
9436
9437 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9438(OMX_BUFFERHEADERTYPE *bufadd)
9439{
9440 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009441 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009442 return NULL;
9443 }
9444 if (!enabled)
9445 return bufadd;
9446 unsigned index = 0;
9447 index = bufadd - m_out_mem_ptr_client;
9448 if (index < omx->drv_ctx.op_buf.actualcount) {
9449 return &omx->m_out_mem_ptr[index];
9450 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009451 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009452 return NULL;
9453}
9454 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9455(unsigned int &buffer_size)
9456{
9457 bool status = true;
9458 pthread_mutex_lock(&omx->c_lock);
9459 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009460 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009461 else {
9462 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009463 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009464 status = false;
9465 goto fail_get_buffer_size;
9466 }
9467 }
9468 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9469 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9470 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9471 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009472fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009473 pthread_mutex_unlock(&omx->c_lock);
9474 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009475}
9476OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009477 OMX_BUFFERHEADERTYPE *bufhdr)
9478{
9479 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009480
Arun Menon906de572013-06-18 17:01:40 -07009481 if (!enabled)
9482 return omx->free_output_buffer(bufhdr);
9483 if (enabled && omx->is_component_secure())
9484 return OMX_ErrorNone;
9485 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009486 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009487 return OMX_ErrorBadParameter;
9488 }
9489 index = bufhdr - m_out_mem_ptr_client;
9490 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009491 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009492 return OMX_ErrorBadParameter;
9493 }
9494 if (pmem_fd[index] > 0) {
9495 munmap(pmem_baseaddress[index], buffer_size_req);
9496 close(pmem_fd[index]);
9497 }
9498 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009499#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009500 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009501#endif
Arun Menon906de572013-06-18 17:01:40 -07009502 m_heap_ptr[index].video_heap_ptr = NULL;
9503 if (allocated_count > 0)
9504 allocated_count--;
9505 else
9506 allocated_count = 0;
9507 if (!allocated_count) {
9508 pthread_mutex_lock(&omx->c_lock);
9509 c2d.close();
9510 init_members();
9511 pthread_mutex_unlock(&omx->c_lock);
9512 }
9513 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009514}
9515
9516OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009517 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009518{
Arun Menon906de572013-06-18 17:01:40 -07009519 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9520 if (!enabled) {
9521 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9522 return eRet;
9523 }
9524 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009525 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009526 omx->is_component_secure());
9527 return OMX_ErrorUnsupportedSetting;
9528 }
9529 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009530 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9531 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009532 buffer_size_req,bytes);
9533 return OMX_ErrorBadParameter;
9534 }
9535 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009536 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009537 return OMX_ErrorInsufficientResources;
9538 }
9539 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9540 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9541 port,appData,omx->drv_ctx.op_buf.buffer_size);
9542 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009543 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009544 return eRet;
9545 }
9546 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309547 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009548 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009549 (temp_bufferHdr - omx->m_out_mem_ptr));
9550 return OMX_ErrorUndefined;
9551 }
9552 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009553#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009554 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9555 buffer_size_req,buffer_alignment_req,
9556 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9557 0);
9558 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9559 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009560 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009561 return OMX_ErrorInsufficientResources;
9562 }
9563 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9564 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009565
Arun Menon906de572013-06-18 17:01:40 -07009566 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009567 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009568 close(pmem_fd[i]);
9569 omx->free_ion_memory(&op_buf_ion_info[i]);
9570 return OMX_ErrorInsufficientResources;
9571 }
9572 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9573 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9574 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009575#endif
Arun Menon906de572013-06-18 17:01:40 -07009576 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9577 m_pmem_info_client[i].offset = 0;
9578 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9579 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9580 m_platform_list_client[i].nEntries = 1;
9581 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9582 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9583 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9584 m_out_mem_ptr_client[i].nFilledLen = 0;
9585 m_out_mem_ptr_client[i].nFlags = 0;
9586 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9587 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9588 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9589 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9590 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9591 m_out_mem_ptr_client[i].pAppPrivate = appData;
9592 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009593 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009594 allocated_count++;
9595 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009596}
9597
9598bool omx_vdec::is_component_secure()
9599{
Arun Menon906de572013-06-18 17:01:40 -07009600 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009601}
9602
9603bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9604{
Arun Menon906de572013-06-18 17:01:40 -07009605 bool status = true;
9606 if (!enabled) {
9607 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9608 dest_color_format = (OMX_COLOR_FORMATTYPE)
9609 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9610 else
9611 status = false;
9612 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009613 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9614 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9615 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009616 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009617 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009618 }
9619 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009620}
Arun Menonbdb80b02013-08-12 17:45:54 -07009621
Arun Menonbdb80b02013-08-12 17:45:54 -07009622void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9623{
9624 int i = 0;
9625 bool buf_present = false;
9626 pthread_mutex_lock(&m_lock);
9627 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9628 //check the buffer fd, offset, uv addr with list contents
9629 //If present increment reference.
9630 if ((out_dynamic_list[i].fd == fd) &&
9631 (out_dynamic_list[i].offset == offset)) {
9632 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009633 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009634 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9635 buf_present = true;
9636 break;
9637 }
9638 }
9639 if (!buf_present) {
9640 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9641 //search for a entry to insert details of the new buffer
9642 if (out_dynamic_list[i].dup_fd == 0) {
9643 out_dynamic_list[i].fd = fd;
9644 out_dynamic_list[i].offset = offset;
9645 out_dynamic_list[i].dup_fd = dup(fd);
9646 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009647 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009648 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9649 break;
9650 }
9651 }
9652 }
9653 pthread_mutex_unlock(&m_lock);
9654}
9655
9656void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9657{
9658 int i = 0;
9659 pthread_mutex_lock(&m_lock);
9660 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9661 //check the buffer fd, offset, uv addr with list contents
9662 //If present decrement reference.
9663 if ((out_dynamic_list[i].fd == fd) &&
9664 (out_dynamic_list[i].offset == offset)) {
9665 out_dynamic_list[i].ref_count--;
9666 if (out_dynamic_list[i].ref_count == 0) {
9667 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009668 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009669 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9670 out_dynamic_list[i].dup_fd = 0;
9671 out_dynamic_list[i].fd = 0;
9672 out_dynamic_list[i].offset = 0;
9673 }
9674 break;
9675 }
9676 }
9677 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009678 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009679 }
9680 pthread_mutex_unlock(&m_lock);
9681}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009682
Arun Menon1fc764f2014-04-17 15:41:27 -07009683OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9684 unsigned long nMaxFrameHeight)
9685{
9686
9687 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9688 int ret = 0;
9689 unsigned long min_res_buf_count = 0;
9690
9691 eRet = enable_smoothstreaming();
9692 if (eRet != OMX_ErrorNone) {
9693 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9694 return eRet;
9695 }
9696
9697 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9698 nMaxFrameWidth,
9699 nMaxFrameHeight);
9700 m_smoothstreaming_mode = true;
9701 m_smoothstreaming_width = nMaxFrameWidth;
9702 m_smoothstreaming_height = nMaxFrameHeight;
9703
9704 //Get upper limit buffer count for min supported resolution
9705 struct v4l2_format fmt;
9706 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9707 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9708 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9709 fmt.fmt.pix_mp.pixelformat = output_capability;
9710
9711 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9712 if (ret) {
9713 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9714 m_decoder_capability.min_height,
9715 m_decoder_capability.min_width);
9716 return OMX_ErrorUnsupportedSetting;
9717 }
9718
9719 eRet = get_buffer_req(&drv_ctx.op_buf);
9720 if (eRet != OMX_ErrorNone) {
9721 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9722 return eRet;
9723 }
9724
9725 min_res_buf_count = drv_ctx.op_buf.mincount;
9726 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9727 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9728
9729 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9730 m_smoothstreaming_width, m_smoothstreaming_height);
9731 eRet = is_video_session_supported();
9732 if (eRet != OMX_ErrorNone) {
9733 DEBUG_PRINT_ERROR("video session is not supported");
9734 return eRet;
9735 }
9736
9737 //Get upper limit buffer size for max smooth streaming resolution set
9738 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9739 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9740 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9741 fmt.fmt.pix_mp.pixelformat = output_capability;
9742 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9743 if (ret) {
9744 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9745 return OMX_ErrorUnsupportedSetting;
9746 }
9747
9748 eRet = get_buffer_req(&drv_ctx.op_buf);
9749 if (eRet != OMX_ErrorNone) {
9750 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
9751 return eRet;
9752 }
9753 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
9754 drv_ctx.op_buf.buffer_size);
9755
9756 drv_ctx.op_buf.mincount = min_res_buf_count;
9757 drv_ctx.op_buf.actualcount = min_res_buf_count;
9758 eRet = set_buffer_req(&drv_ctx.op_buf);
9759 if (eRet != OMX_ErrorNone) {
9760 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9761 return eRet;
9762 }
9763
9764 eRet = get_buffer_req(&drv_ctx.op_buf);
9765 if (eRet != OMX_ErrorNone) {
9766 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9767 return eRet;
9768 }
9769 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9770 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9771 return eRet;
9772}
9773
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009774#ifdef _MSM8974_
9775void omx_vdec::send_codec_config() {
9776 if (codec_config_flag) {
9777 unsigned p1 = 0; // Parameter - 1
9778 unsigned p2 = 0; // Parameter - 2
9779 unsigned ident = 0;
9780 pthread_mutex_lock(&m_lock);
9781 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9782 while (m_etb_q.m_size) {
9783 m_etb_q.pop_entry(&p1,&p2,&ident);
9784 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9785 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9786 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9787 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9788 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9789 omx_report_error();
9790 }
9791 } else {
9792 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9793 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9794 }
9795 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9796 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9797 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9798 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9799 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9800 omx_report_error ();
9801 }
9802 } else {
9803 pending_input_buffers++;
9804 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9805 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9806 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9807 }
9808 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9809 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9810 (OMX_BUFFERHEADERTYPE *)p1);
9811 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9812 }
9813 }
9814 pthread_mutex_unlock(&m_lock);
9815 }
9816}
9817#endif