blob: 2d225d21e353d6980cc293b6a5d9d22263cbdd0e [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Maheshwar Ajja507d6552014-01-03 14:54:29 +05302Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080053#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070054
55#ifndef _ANDROID_
56#include <sys/ioctl.h>
57#include <sys/mman.h>
58#endif //_ANDROID_
59
60#ifdef _ANDROID_
61#include <cutils/properties.h>
62#undef USE_EGL_IMAGE_GPU
63#endif
64
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070065#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070066
67#ifdef _ANDROID_
68#include "DivXDrmDecrypt.h"
69#endif //_ANDROID_
70
Arun Menon45346052013-11-13 12:40:08 -080071#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070072#include "QComOMXMetadata.h"
73#endif
74
Shalaj Jain273b3e02012-06-22 19:08:03 -070075#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070081
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070082#define BUFFER_LOG_LOC "/data/misc/media"
83
Shalaj Jain273b3e02012-06-22 19:08:03 -070084#ifdef OUTPUT_EXTRADATA_LOG
85FILE *outputExtradataFile;
86char ouputextradatafilename [] = "/data/extradata";
87#endif
88
89#define DEFAULT_FPS 30
90#define MAX_INPUT_ERROR DEFAULT_FPS
91#define MAX_SUPPORTED_FPS 120
Deepak Vermaa2efdb12013-12-26 12:30:05 +053092#define DEFAULT_WIDTH_ALIGNMENT 128
93#define DEFAULT_HEIGHT_ALIGNMENT 32
Shalaj Jain273b3e02012-06-22 19:08:03 -070094
95#define VC1_SP_MP_START_CODE 0xC5000000
96#define VC1_SP_MP_START_CODE_MASK 0xFF000000
97#define VC1_AP_SEQ_START_CODE 0x0F010000
98#define VC1_STRUCT_C_PROFILE_MASK 0xF0
99#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
100#define VC1_SIMPLE_PROFILE 0
101#define VC1_MAIN_PROFILE 1
102#define VC1_ADVANCE_PROFILE 3
103#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
104#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
105#define VC1_STRUCT_C_LEN 4
106#define VC1_STRUCT_C_POS 8
107#define VC1_STRUCT_A_POS 12
108#define VC1_STRUCT_B_POS 24
109#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700110#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700111
112#define MEM_DEVICE "/dev/ion"
113#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
114
115#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700116extern "C" {
117#include<utils/Log.h>
118}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119#endif//_ANDROID_
120
Vinay Kalia53fa6832012-10-11 17:55:30 -0700121#define SZ_4K 0x1000
122#define SZ_1M 0x100000
123
Shalaj Jain273b3e02012-06-22 19:08:03 -0700124#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
125#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 -0700126#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
127
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800128#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800129#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700130
131int debug_level = PRIO_ERROR;
132
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530133static OMX_U32 maxSmoothStreamingWidth = 1920;
134static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800135
Shalaj Jain273b3e02012-06-22 19:08:03 -0700136void* async_message_thread (void *input)
137{
Arun Menon906de572013-06-18 17:01:40 -0700138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
141 struct v4l2_buffer v4l2_buf;
142 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
143 struct v4l2_event dqevent;
144 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
145 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
146 pfd.fd = omx->drv_ctx.video_driver_fd;
147 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700148 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700149 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
150 while (1) {
151 rc = poll(&pfd, 1, POLL_TIMEOUT);
152 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700153 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700154 break;
155 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700156 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700157 break;
158 }
159 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
160 struct vdec_msginfo vdec_msg;
161 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
162 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
163 v4l2_buf.length = omx->drv_ctx.num_planes;
164 v4l2_buf.m.planes = plane;
165 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
166 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
167 vdec_msg.status_code=VDEC_S_SUCCESS;
168 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
169 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
170 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
171 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
172 (uint64_t)v4l2_buf.timestamp.tv_usec;
173 if (vdec_msg.msgdata.output_frame.len) {
174 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
175 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
176 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
177 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
178 }
179 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700180 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700181 break;
182 }
183 }
184 }
185 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
186 struct vdec_msginfo vdec_msg;
187 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
188 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
189 v4l2_buf.length = 1;
190 v4l2_buf.m.planes = plane;
191 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
192 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
193 vdec_msg.status_code=VDEC_S_SUCCESS;
194 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
195 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700196 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700197 break;
198 }
199 }
200 }
201 if (pfd.revents & POLLPRI) {
202 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
203 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
204 struct vdec_msginfo vdec_msg;
205 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
206 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700207 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700208 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700209 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700210 break;
211 }
212 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
213 struct vdec_msginfo vdec_msg;
214 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
215 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700216 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700217 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700218 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700219 break;
220 }
221 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
222 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700223 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700224 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700225 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700226 break;
227 }
228 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700229 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700230 break;
231 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
232 struct vdec_msginfo vdec_msg;
233 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
234 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700235 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700236 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700237 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700238 break;
239 }
Arun Menon45346052013-11-13 12:40:08 -0800240 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700241 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700242 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700243 omx->buf_ref_remove(ptr[0], ptr[1]);
244 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
245 unsigned int *ptr = (unsigned int *)dqevent.u.data;
246 struct vdec_msginfo vdec_msg;
247
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700248 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700249
250 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
251 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
252 v4l2_buf.length = omx->drv_ctx.num_planes;
253 v4l2_buf.m.planes = plane;
254 v4l2_buf.index = ptr[5];
255 v4l2_buf.flags = 0;
256
257 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
258 vdec_msg.status_code = VDEC_S_SUCCESS;
259 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
260 vdec_msg.msgdata.output_frame.len = 0;
261 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
262 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
263 (uint64_t)ptr[4];
264 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700265 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700266 break;
267 }
268 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700269 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700270 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700271 continue;
272 }
273 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700274 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700275 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700276 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700277}
278
279void* message_thread(void *input)
280{
Arun Menon906de572013-06-18 17:01:40 -0700281 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
282 unsigned char id;
283 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700284
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700285 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700286 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
287 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700288
Arun Menon906de572013-06-18 17:01:40 -0700289 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700290
Arun Menon906de572013-06-18 17:01:40 -0700291 if (0 == n) {
292 break;
293 }
294
295 if (1 == n) {
296 omx->process_event_cb(omx, id);
297 }
298 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700299 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700300 break;
301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700303 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700304 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700305}
306
307void post_message(omx_vdec *omx, unsigned char id)
308{
Arun Menon906de572013-06-18 17:01:40 -0700309 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700310 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700311 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700312 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700313}
314
315// omx_cmd_queue destructor
316omx_vdec::omx_cmd_queue::~omx_cmd_queue()
317{
Arun Menon906de572013-06-18 17:01:40 -0700318 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700319}
320
321// omx cmd queue constructor
322omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
323{
324 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
325}
326
327// omx cmd queue insert
328bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
329{
Arun Menon906de572013-06-18 17:01:40 -0700330 bool ret = true;
331 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
332 m_q[m_write].id = id;
333 m_q[m_write].param1 = p1;
334 m_q[m_write].param2 = p2;
335 m_write++;
336 m_size ++;
337 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
338 m_write = 0;
339 }
340 } else {
341 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700342 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700343 }
Arun Menon906de572013-06-18 17:01:40 -0700344 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700345}
346
347// omx cmd queue pop
348bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
349{
Arun Menon906de572013-06-18 17:01:40 -0700350 bool ret = true;
351 if (m_size > 0) {
352 *id = m_q[m_read].id;
353 *p1 = m_q[m_read].param1;
354 *p2 = m_q[m_read].param2;
355 // Move the read pointer ahead
356 ++m_read;
357 --m_size;
358 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
359 m_read = 0;
360 }
361 } else {
362 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700363 }
Arun Menon906de572013-06-18 17:01:40 -0700364 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700365}
366
367// Retrieve the first mesg type in the queue
368unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
369{
370 return m_q[m_read].id;
371}
372
373#ifdef _ANDROID_
374omx_vdec::ts_arr_list::ts_arr_list()
375{
Arun Menon906de572013-06-18 17:01:40 -0700376 //initialize timestamps array
377 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700378}
379omx_vdec::ts_arr_list::~ts_arr_list()
380{
Arun Menon906de572013-06-18 17:01:40 -0700381 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700382}
383
384bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
385{
Arun Menon906de572013-06-18 17:01:40 -0700386 bool ret = true;
387 bool duplicate_ts = false;
388 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700389
Arun Menon906de572013-06-18 17:01:40 -0700390 //insert at the first available empty location
391 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
392 if (!m_ts_arr_list[idx].valid) {
393 //found invalid or empty entry, save timestamp
394 m_ts_arr_list[idx].valid = true;
395 m_ts_arr_list[idx].timestamp = ts;
396 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
397 ts, idx);
398 break;
399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700401
Arun Menon906de572013-06-18 17:01:40 -0700402 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
403 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
404 ret = false;
405 }
406 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700407}
408
409bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
410{
Arun Menon906de572013-06-18 17:01:40 -0700411 bool ret = true;
412 int min_idx = -1;
413 OMX_TICKS min_ts = 0;
414 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415
Arun Menon906de572013-06-18 17:01:40 -0700416 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700417
Arun Menon906de572013-06-18 17:01:40 -0700418 if (m_ts_arr_list[idx].valid) {
419 //found valid entry, save index
420 if (min_idx < 0) {
421 //first valid entry
422 min_ts = m_ts_arr_list[idx].timestamp;
423 min_idx = idx;
424 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
425 min_ts = m_ts_arr_list[idx].timestamp;
426 min_idx = idx;
427 }
428 }
429
Shalaj Jain273b3e02012-06-22 19:08:03 -0700430 }
431
Arun Menon906de572013-06-18 17:01:40 -0700432 if (min_idx < 0) {
433 //no valid entries found
434 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
435 ts = 0;
436 ret = false;
437 } else {
438 ts = m_ts_arr_list[min_idx].timestamp;
439 m_ts_arr_list[min_idx].valid = false;
440 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
441 ts, min_idx);
442 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700443
Arun Menon906de572013-06-18 17:01:40 -0700444 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700445
446}
447
448
449bool omx_vdec::ts_arr_list::reset_ts_list()
450{
Arun Menon906de572013-06-18 17:01:40 -0700451 bool ret = true;
452 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700453
Arun Menon906de572013-06-18 17:01:40 -0700454 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
455 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
456 m_ts_arr_list[idx].valid = false;
457 }
458 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700459}
460#endif
461
462// factory function executed by the core to create instances
463void *get_omx_component_factory_fn(void)
464{
Arun Menon906de572013-06-18 17:01:40 -0700465 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700466}
467
468#ifdef _ANDROID_
469#ifdef USE_ION
470VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700471 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700472{
Arun Menon906de572013-06-18 17:01:40 -0700473 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700474}
475#else
476VideoHeap::VideoHeap(int fd, size_t size, void* base)
477{
478 // dup file descriptor, map once, use pmem
479 init(dup(fd), base, size, 0 , MEM_DEVICE);
480}
481#endif
482#endif // _ANDROID_
483/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700484 FUNCTION
485 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700486
Arun Menon906de572013-06-18 17:01:40 -0700487 DESCRIPTION
488 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700489
Arun Menon906de572013-06-18 17:01:40 -0700490 PARAMETERS
491 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700492
Arun Menon906de572013-06-18 17:01:40 -0700493 RETURN VALUE
494 None.
495 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800496omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700497 m_state(OMX_StateInvalid),
498 m_app_data(NULL),
499 m_inp_mem_ptr(NULL),
500 m_out_mem_ptr(NULL),
501 m_inp_err_count(0),
502 input_flush_progress (false),
503 output_flush_progress (false),
504 input_use_buffer (false),
505 output_use_buffer (false),
506 ouput_egl_buffers(false),
507 m_use_output_pmem(OMX_FALSE),
508 m_out_mem_region_smi(OMX_FALSE),
509 m_out_pvt_entry_pmem(OMX_FALSE),
510 pending_input_buffers(0),
511 pending_output_buffers(0),
512 m_out_bm_count(0),
513 m_inp_bm_count(0),
514 m_inp_bPopulated(OMX_FALSE),
515 m_out_bPopulated(OMX_FALSE),
516 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700517#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700518 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700519#endif
Arun Menon906de572013-06-18 17:01:40 -0700520 m_inp_bEnabled(OMX_TRUE),
521 m_out_bEnabled(OMX_TRUE),
522 m_in_alloc_cnt(0),
523 m_platform_list(NULL),
524 m_platform_entry(NULL),
525 m_pmem_info(NULL),
526 arbitrary_bytes (true),
527 psource_frame (NULL),
528 pdest_frame (NULL),
529 m_inp_heap_ptr (NULL),
530 m_phdr_pmem_ptr(NULL),
531 m_heap_inp_bm_count (0),
532 codec_type_parse ((codec_type)0),
533 first_frame_meta (true),
534 frame_count (0),
535 nal_count (0),
536 nal_length(0),
537 look_ahead_nal (false),
538 first_frame(0),
539 first_buffer(NULL),
540 first_frame_size (0),
541 m_device_file_ptr(NULL),
542 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700543 h264_last_au_ts(LLONG_MAX),
544 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530545 m_disp_hor_size(0),
546 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700547 prev_ts(LLONG_MAX),
548 rst_prev_ts(true),
549 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700550 in_reconfig(false),
551 m_display_id(NULL),
552 h264_parser(NULL),
553 client_extradata(0),
554 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530555 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700556#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700557 m_enable_android_native_buffers(OMX_FALSE),
558 m_use_android_native_buffers(OMX_FALSE),
559 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700560#endif
Arun Menon906de572013-06-18 17:01:40 -0700561 m_desc_buffer_ptr(NULL),
562 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530563 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800564 client_set_fps(false),
565 m_last_rendered_TS(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700566{
Arun Menon906de572013-06-18 17:01:40 -0700567 /* Assumption is that , to begin with , we have all the frames with decoder */
568 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700569 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700570#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700571 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700572 property_get("vidc.debug.level", property_value, "0");
573 debug_level = atoi(property_value);
574 property_value[0] = '\0';
575
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700576 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
577
Arun Menon906de572013-06-18 17:01:40 -0700578 property_get("vidc.dec.debug.perf", property_value, "0");
579 perf_flag = atoi(property_value);
580 if (perf_flag) {
581 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
582 dec_time.start();
583 proc_frms = latency = 0;
584 }
585 prev_n_filled_len = 0;
586 property_value[0] = '\0';
587 property_get("vidc.dec.debug.ts", property_value, "0");
588 m_debug_timestamp = atoi(property_value);
589 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
590 if (m_debug_timestamp) {
591 time_stamp_dts.set_timestamp_reorder_mode(true);
592 time_stamp_dts.enable_debug_print(true);
593 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700594
Arun Menon906de572013-06-18 17:01:40 -0700595 property_value[0] = '\0';
596 property_get("vidc.dec.debug.concealedmb", property_value, "0");
597 m_debug_concealedmb = atoi(property_value);
598 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700599
Arun Menon906de572013-06-18 17:01:40 -0700600 property_value[0] = '\0';
601 property_get("vidc.dec.profile.check", property_value, "0");
602 m_reject_avc_1080p_mp = atoi(property_value);
603 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530604
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700605 property_value[0] = '\0';
606 property_get("vidc.dec.log.in", property_value, "0");
607 m_debug.in_buffer_log = atoi(property_value);
608
609 property_value[0] = '\0';
610 property_get("vidc.dec.log.out", property_value, "0");
611 m_debug.out_buffer_log = atoi(property_value);
612 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
613
614 property_value[0] = '\0';
615 property_get("vidc.log.loc", property_value, "");
616 if (*property_value)
617 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800618
619 property_value[0] = '\0';
620 property_get("vidc.dec.120fps.enabled", property_value, "0");
621
622 //if this feature is not enabled then reset this value -ve
623 if(atoi(property_value)) {
624 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
625 m_last_rendered_TS = 0;
626 }
627
Shalaj Jain273b3e02012-06-22 19:08:03 -0700628#endif
Arun Menon906de572013-06-18 17:01:40 -0700629 memset(&m_cmp,0,sizeof(m_cmp));
630 memset(&m_cb,0,sizeof(m_cb));
631 memset (&drv_ctx,0,sizeof(drv_ctx));
632 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
633 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
634 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
635 m_demux_entries = 0;
636 msg_thread_id = 0;
637 async_thread_id = 0;
638 msg_thread_created = false;
639 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700640#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700641 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700642#endif
Arun Menon906de572013-06-18 17:01:40 -0700643 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530644 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700645 drv_ctx.timestamp_adjust = false;
646 drv_ctx.video_driver_fd = -1;
647 m_vendor_config.pData = NULL;
648 pthread_mutex_init(&m_lock, NULL);
649 pthread_mutex_init(&c_lock, NULL);
650 sem_init(&m_cmd_lock,0,0);
651 streaming[CAPTURE_PORT] =
652 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700653#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700654 char extradata_value[PROPERTY_VALUE_MAX] = {0};
655 property_get("vidc.dec.debug.extradata", extradata_value, "0");
656 m_debug_extradata = atoi(extradata_value);
657 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700658#endif
Arun Menon906de572013-06-18 17:01:40 -0700659 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
660 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700661 dynamic_buf_mode = false;
662 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800663 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800664 m_smoothstreaming_mode = false;
665 m_smoothstreaming_width = 0;
666 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530667 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700668}
669
Vinay Kalia85793762012-06-14 19:12:34 -0700670static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700671 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
672 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
673 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700674 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
675 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700676 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
677 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700678};
679
680static OMX_ERRORTYPE subscribe_to_events(int fd)
681{
Arun Menon906de572013-06-18 17:01:40 -0700682 OMX_ERRORTYPE eRet = OMX_ErrorNone;
683 struct v4l2_event_subscription sub;
684 int array_sz = sizeof(event_type)/sizeof(int);
685 int i,rc;
686 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700687 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700688 return OMX_ErrorBadParameter;
689 }
Vinay Kalia85793762012-06-14 19:12:34 -0700690
Arun Menon906de572013-06-18 17:01:40 -0700691 for (i = 0; i < array_sz; ++i) {
692 memset(&sub, 0, sizeof(sub));
693 sub.type = event_type[i];
694 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
695 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700696 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700697 break;
698 }
699 }
700 if (i < array_sz) {
701 for (--i; i >=0 ; i--) {
702 memset(&sub, 0, sizeof(sub));
703 sub.type = event_type[i];
704 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
705 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700706 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700707 }
708 eRet = OMX_ErrorNotImplemented;
709 }
710 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700711}
712
713
714static OMX_ERRORTYPE unsubscribe_to_events(int fd)
715{
Arun Menon906de572013-06-18 17:01:40 -0700716 OMX_ERRORTYPE eRet = OMX_ErrorNone;
717 struct v4l2_event_subscription sub;
718 int array_sz = sizeof(event_type)/sizeof(int);
719 int i,rc;
720 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700721 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700722 return OMX_ErrorBadParameter;
723 }
Vinay Kalia85793762012-06-14 19:12:34 -0700724
Arun Menon906de572013-06-18 17:01:40 -0700725 for (i = 0; i < array_sz; ++i) {
726 memset(&sub, 0, sizeof(sub));
727 sub.type = event_type[i];
728 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
729 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700730 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700731 break;
732 }
733 }
734 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700735}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700736
737/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700738 FUNCTION
739 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700740
Arun Menon906de572013-06-18 17:01:40 -0700741 DESCRIPTION
742 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700743
Arun Menon906de572013-06-18 17:01:40 -0700744 PARAMETERS
745 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700746
Arun Menon906de572013-06-18 17:01:40 -0700747 RETURN VALUE
748 None.
749 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700750omx_vdec::~omx_vdec()
751{
Arun Menon906de572013-06-18 17:01:40 -0700752 m_pmem_info = NULL;
753 struct v4l2_decoder_cmd dec;
754 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
755 if (m_pipe_in) close(m_pipe_in);
756 if (m_pipe_out) close(m_pipe_out);
757 m_pipe_in = -1;
758 m_pipe_out = -1;
759 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
760 if (msg_thread_created)
761 pthread_join(msg_thread_id,NULL);
762 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
763 dec.cmd = V4L2_DEC_CMD_STOP;
764 if (drv_ctx.video_driver_fd >=0 ) {
765 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700766 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700767 }
768 if (async_thread_created)
769 pthread_join(async_thread_id,NULL);
770 unsubscribe_to_events(drv_ctx.video_driver_fd);
771 close(drv_ctx.video_driver_fd);
772 pthread_mutex_destroy(&m_lock);
773 pthread_mutex_destroy(&c_lock);
774 sem_destroy(&m_cmd_lock);
775 if (perf_flag) {
776 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
777 dec_time.end();
778 }
779 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700780}
781
Arun Menon906de572013-06-18 17:01:40 -0700782int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
783{
784 struct v4l2_requestbuffers bufreq;
785 int rc = 0;
786 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
787 bufreq.memory = V4L2_MEMORY_USERPTR;
788 bufreq.count = 0;
789 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
790 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530791 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
792 bufreq.memory = V4L2_MEMORY_USERPTR;
793 bufreq.count = 0;
794 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
795 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700796 }
797 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700798}
799
Shalaj Jain273b3e02012-06-22 19:08:03 -0700800/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700801 FUNCTION
802 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803
Arun Menon906de572013-06-18 17:01:40 -0700804 DESCRIPTION
805 IL Client callbacks are generated through this routine. The decoder
806 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700807
Arun Menon906de572013-06-18 17:01:40 -0700808 PARAMETERS
809 ctxt -- Context information related to the self.
810 id -- Event identifier. This could be any of the following:
811 1. Command completion event
812 2. Buffer done callback event
813 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700814
Arun Menon906de572013-06-18 17:01:40 -0700815 RETURN VALUE
816 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700817
Arun Menon906de572013-06-18 17:01:40 -0700818 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700819void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
820{
Arun Menon906de572013-06-18 17:01:40 -0700821 signed p1; // Parameter - 1
822 signed p2; // Parameter - 2
823 unsigned ident;
824 unsigned qsize=0; // qsize
825 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700826
Arun Menon906de572013-06-18 17:01:40 -0700827 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700828 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700829 __func__);
830 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700831 }
832
Arun Menon906de572013-06-18 17:01:40 -0700833 // Protect the shared queue data structure
834 do {
835 /*Read the message id's from the queue*/
836 pthread_mutex_lock(&pThis->m_lock);
837 qsize = pThis->m_cmd_q.m_size;
838 if (qsize) {
839 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700840 }
Arun Menon906de572013-06-18 17:01:40 -0700841
842 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
843 qsize = pThis->m_ftb_q.m_size;
844 if (qsize) {
845 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
846 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700847 }
Arun Menon906de572013-06-18 17:01:40 -0700848
849 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
850 qsize = pThis->m_etb_q.m_size;
851 if (qsize) {
852 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
853 }
854 }
855 pthread_mutex_unlock(&pThis->m_lock);
856
857 /*process message if we have one*/
858 if (qsize > 0) {
859 id = ident;
860 switch (id) {
861 case OMX_COMPONENT_GENERATE_EVENT:
862 if (pThis->m_cb.EventHandler) {
863 switch (p1) {
864 case OMX_CommandStateSet:
865 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700866 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700867 pThis->m_state);
868 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
869 OMX_EventCmdComplete, p1, p2, NULL);
870 break;
871
872 case OMX_EventError:
873 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700874 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700875 pThis->m_state = (OMX_STATETYPE) p2;
876 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
877 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
878 } else if (p2 == OMX_ErrorHardware) {
879 pThis->omx_report_error();
880 } else {
881 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
882 OMX_EventError, p2, (OMX_U32)NULL, NULL );
883 }
884 break;
885
886 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700887 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700888 if (BITMASK_PRESENT(&pThis->m_flags,
889 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
890 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
891 break;
892 }
893 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
894 OMX_ERRORTYPE eRet = OMX_ErrorNone;
895 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
896 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700897 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700898 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
899 pThis->in_reconfig = false;
900 if (eRet != OMX_ErrorNone) {
901 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
902 pThis->omx_report_error();
903 break;
904 }
905 }
906 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
907 OMX_EventCmdComplete, p1, p2, NULL );
908 break;
909 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700910 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700911 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
912 OMX_EventCmdComplete, p1, p2, NULL );
913 break;
914
915 default:
916 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
917 OMX_EventCmdComplete, p1, p2, NULL );
918 break;
919
920 }
921 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700922 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700923 }
924 break;
925 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
926 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
927 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->omx_report_error ();
930 }
931 break;
932 case OMX_COMPONENT_GENERATE_ETB:
933 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
934 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700935 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700936 pThis->omx_report_error ();
937 }
938 break;
939
940 case OMX_COMPONENT_GENERATE_FTB:
941 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
942 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700943 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700944 pThis->omx_report_error ();
945 }
946 break;
947
948 case OMX_COMPONENT_GENERATE_COMMAND:
949 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
950 (OMX_U32)p2,(OMX_PTR)NULL);
951 break;
952
953 case OMX_COMPONENT_GENERATE_EBD:
954
955 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700956 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700957 pThis->omx_report_error ();
958 } else {
959 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
960 pThis->m_inp_err_count++;
961 pThis->time_stamp_dts.remove_time_stamp(
962 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
963 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
964 ?true:false);
965 } else {
966 pThis->m_inp_err_count = 0;
967 }
968 if ( pThis->empty_buffer_done(&pThis->m_cmp,
969 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700970 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700971 pThis->omx_report_error ();
972 }
973 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700974 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700975 pThis->omx_report_error ();
976 }
977 }
978 break;
979 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
980 int64_t *timestamp = (int64_t *)p1;
981 if (p1) {
982 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
983 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
984 ?true:false);
985 free(timestamp);
986 }
987 }
988 break;
989 case OMX_COMPONENT_GENERATE_FBD:
990 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700991 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700992 pThis->omx_report_error ();
993 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
994 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700995 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700996 pThis->omx_report_error ();
997 }
998 break;
999
1000 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001001 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001002 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001003 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001004 } else {
1005 pThis->execute_input_flush();
1006 if (pThis->m_cb.EventHandler) {
1007 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001008 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001009 pThis->omx_report_error ();
1010 } else {
1011 /*Check if we need generate event for Flush done*/
1012 if (BITMASK_PRESENT(&pThis->m_flags,
1013 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1014 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001015 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001016 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1017 OMX_EventCmdComplete,OMX_CommandFlush,
1018 OMX_CORE_INPUT_PORT_INDEX,NULL );
1019 }
1020 if (BITMASK_PRESENT(&pThis->m_flags,
1021 OMX_COMPONENT_IDLE_PENDING)) {
1022 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001023 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001024 pThis->omx_report_error ();
1025 } else {
1026 pThis->streaming[OUTPUT_PORT] = false;
1027 }
1028 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001029 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001030 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1031 OMX_COMPONENT_GENERATE_STOP_DONE);
1032 }
1033 }
1034 }
1035 } else {
1036 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1037 }
1038 }
1039 break;
1040
1041 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001042 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001043 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001044 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001045 } else {
1046 pThis->execute_output_flush();
1047 if (pThis->m_cb.EventHandler) {
1048 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001049 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001050 pThis->omx_report_error ();
1051 } else {
1052 /*Check if we need generate event for Flush done*/
1053 if (BITMASK_PRESENT(&pThis->m_flags,
1054 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001055 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001056 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1057 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1058 OMX_EventCmdComplete,OMX_CommandFlush,
1059 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1060 }
1061 if (BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001063 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001064 BITMASK_CLEAR (&pThis->m_flags,
1065 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1066 if (BITMASK_PRESENT(&pThis->m_flags,
1067 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1068 pThis->post_event(OMX_CommandPortDisable,
1069 OMX_CORE_OUTPUT_PORT_INDEX,
1070 OMX_COMPONENT_GENERATE_EVENT);
1071 BITMASK_CLEAR (&pThis->m_flags,
1072 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1073
1074 }
1075 }
1076
1077 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1078 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001079 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001080 pThis->omx_report_error ();
1081 break;
1082 }
1083 pThis->streaming[CAPTURE_PORT] = false;
1084 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001085 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001086 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1087 OMX_COMPONENT_GENERATE_STOP_DONE);
1088 }
1089 }
1090 }
1091 } else {
1092 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1093 }
1094 }
1095 break;
1096
1097 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001098 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001099
1100 if (pThis->m_cb.EventHandler) {
1101 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001102 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001103 pThis->omx_report_error ();
1104 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001105 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001106 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001107 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001108 // Send the callback now
1109 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1110 pThis->m_state = OMX_StateExecuting;
1111 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1112 OMX_EventCmdComplete,OMX_CommandStateSet,
1113 OMX_StateExecuting, NULL);
1114 } else if (BITMASK_PRESENT(&pThis->m_flags,
1115 OMX_COMPONENT_PAUSE_PENDING)) {
1116 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1117 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001118 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001119 pThis->omx_report_error ();
1120 }
1121 }
1122 }
1123 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001124 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001125 }
1126 break;
1127
1128 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001129 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001130 if (pThis->m_cb.EventHandler) {
1131 if (p2 != VDEC_S_SUCCESS) {
1132 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1133 pThis->omx_report_error ();
1134 } else {
1135 pThis->complete_pending_buffer_done_cbs();
1136 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001137 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001138 //Send the callback now
1139 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1140 pThis->m_state = OMX_StatePause;
1141 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1142 OMX_EventCmdComplete,OMX_CommandStateSet,
1143 OMX_StatePause, NULL);
1144 }
1145 }
1146 } else {
1147 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1148 }
1149
1150 break;
1151
1152 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001153 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001154 if (pThis->m_cb.EventHandler) {
1155 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001156 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001157 pThis->omx_report_error ();
1158 } else {
1159 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001160 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001161 // Send the callback now
1162 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1163 pThis->m_state = OMX_StateExecuting;
1164 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1165 OMX_EventCmdComplete,OMX_CommandStateSet,
1166 OMX_StateExecuting,NULL);
1167 }
1168 }
1169 } else {
1170 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1171 }
1172
1173 break;
1174
1175 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001176 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001177 if (pThis->m_cb.EventHandler) {
1178 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001179 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001180 pThis->omx_report_error ();
1181 } else {
1182 pThis->complete_pending_buffer_done_cbs();
1183 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001184 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001185 // Send the callback now
1186 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1187 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001188 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001189 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1190 OMX_EventCmdComplete,OMX_CommandStateSet,
1191 OMX_StateIdle,NULL);
1192 }
1193 }
1194 } else {
1195 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1196 }
1197
1198 break;
1199
1200 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001201 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001202
1203 if (p2 == OMX_IndexParamPortDefinition) {
1204 pThis->in_reconfig = true;
1205 }
1206 if (pThis->m_cb.EventHandler) {
1207 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1208 OMX_EventPortSettingsChanged, p1, p2, NULL );
1209 } else {
1210 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1211 }
1212
Arun Menon906de572013-06-18 17:01:40 -07001213 break;
1214
1215 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001216 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001217 if (pThis->m_cb.EventHandler) {
1218 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1219 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1220 } else {
1221 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1222 }
1223 pThis->prev_ts = LLONG_MAX;
1224 pThis->rst_prev_ts = true;
1225 break;
1226
1227 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001228 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001229 pThis->omx_report_error ();
1230 break;
1231
1232 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001233 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001234 pThis->omx_report_unsupported_setting();
1235 break;
1236
Arun Menon906de572013-06-18 17:01:40 -07001237 default:
1238 break;
1239 }
1240 }
1241 pthread_mutex_lock(&pThis->m_lock);
1242 qsize = pThis->m_cmd_q.m_size;
1243 if (pThis->m_state != OMX_StatePause)
1244 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1245 pthread_mutex_unlock(&pThis->m_lock);
1246 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001247
1248}
1249
Vinay Kaliab9e98102013-04-02 19:31:43 -07001250int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001251{
Arun Menon906de572013-06-18 17:01:40 -07001252 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301253 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1254 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001255 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001256 width, drv_ctx.video_resolution.frame_width,
1257 height,drv_ctx.video_resolution.frame_height);
1258 format_changed = 1;
1259 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001260 drv_ctx.video_resolution.frame_height = height;
1261 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001262 drv_ctx.video_resolution.scan_lines = scan_lines;
1263 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001264 rectangle.nLeft = 0;
1265 rectangle.nTop = 0;
1266 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1267 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001268 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001269}
1270
Arun Menon6836ba02013-02-19 20:37:40 -08001271OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1272{
Arun Menon906de572013-06-18 17:01:40 -07001273 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1274 OMX_MAX_STRINGNAME_SIZE) &&
1275 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1276 m_decoder_capability.max_width = 1280;
1277 m_decoder_capability.max_height = 720;
1278 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1279 }
Arun Menon888aa852013-05-30 11:24:42 -07001280
Arun Menon906de572013-06-18 17:01:40 -07001281 if ((drv_ctx.video_resolution.frame_width *
1282 drv_ctx.video_resolution.frame_height >
1283 m_decoder_capability.max_width *
1284 m_decoder_capability.max_height) ||
1285 (drv_ctx.video_resolution.frame_width*
1286 drv_ctx.video_resolution.frame_height <
1287 m_decoder_capability.min_width *
1288 m_decoder_capability.min_height)) {
1289 DEBUG_PRINT_ERROR(
1290 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1291 drv_ctx.video_resolution.frame_width,
1292 drv_ctx.video_resolution.frame_height,
1293 m_decoder_capability.min_width,
1294 m_decoder_capability.min_height,
1295 m_decoder_capability.max_width,
1296 m_decoder_capability.max_height);
1297 return OMX_ErrorUnsupportedSetting;
1298 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001299 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001300 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001301}
1302
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001303int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1304{
1305 if (m_debug.in_buffer_log && !m_debug.infile) {
1306 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1307 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1308 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1309 }
1310 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1311 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); }
1312 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1313 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1314 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1315 }
1316 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1317 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1318 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1319 }
1320 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1321 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1322 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1323 }
1324 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1325 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1326 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1327 }
1328 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1329 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1330 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1331 }
1332 m_debug.infile = fopen (m_debug.infile_name, "ab");
1333 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001334 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001335 m_debug.infile_name[0] = '\0';
1336 return -1;
1337 }
1338 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1339 struct ivf_file_header {
1340 OMX_U8 signature[4]; //='DKIF';
1341 OMX_U8 version ; //= 0;
1342 OMX_U8 headersize ; //= 32;
1343 OMX_U32 FourCC;
1344 OMX_U8 width;
1345 OMX_U8 height;
1346 OMX_U32 rate;
1347 OMX_U32 scale;
1348 OMX_U32 length;
1349 OMX_U8 unused[4];
1350 } file_header;
1351
1352 memset((void *)&file_header,0,sizeof(file_header));
1353 file_header.signature[0] = 'D';
1354 file_header.signature[1] = 'K';
1355 file_header.signature[2] = 'I';
1356 file_header.signature[3] = 'F';
1357 file_header.version = 0;
1358 file_header.headersize = 32;
1359 file_header.FourCC = 0x30385056;
1360 fwrite((const char *)&file_header,
1361 sizeof(file_header),1,m_debug.infile);
1362 }
1363 }
1364 if (m_debug.infile && buffer_addr && buffer_len) {
1365 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1366 struct vp8_ivf_frame_header {
1367 OMX_U32 framesize;
1368 OMX_U32 timestamp_lo;
1369 OMX_U32 timestamp_hi;
1370 } vp8_frame_header;
1371 vp8_frame_header.framesize = buffer_len;
1372 /* Currently FW doesn't use timestamp values */
1373 vp8_frame_header.timestamp_lo = 0;
1374 vp8_frame_header.timestamp_hi = 0;
1375 fwrite((const char *)&vp8_frame_header,
1376 sizeof(vp8_frame_header),1,m_debug.infile);
1377 }
1378 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1379 }
1380 return 0;
1381}
1382
1383int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1384 if (m_debug.out_buffer_log && !m_debug.outfile) {
1385 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1386 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1387 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1388 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001389 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001390 m_debug.outfile_name[0] = '\0';
1391 return -1;
1392 }
1393 }
1394 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1395 int buf_index = buffer - m_out_mem_ptr;
1396 int stride = drv_ctx.video_resolution.stride;
1397 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301398 if (m_smoothstreaming_mode) {
1399 stride = drv_ctx.video_resolution.frame_width;
1400 scanlines = drv_ctx.video_resolution.frame_height;
1401 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1402 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1403 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001404 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1405 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301406 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1407 drv_ctx.video_resolution.frame_width,
1408 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001409 int bytes_written = 0;
1410 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1411 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1412 temp += stride;
1413 }
1414 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1415 int stride_c = stride;
1416 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1417 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1418 temp += stride_c;
1419 }
1420 }
1421 return 0;
1422}
1423
Shalaj Jain273b3e02012-06-22 19:08:03 -07001424/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001425 FUNCTION
1426 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001427
Arun Menon906de572013-06-18 17:01:40 -07001428 DESCRIPTION
1429 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001430
Arun Menon906de572013-06-18 17:01:40 -07001431 PARAMETERS
1432 ctxt -- Context information related to the self.
1433 id -- Event identifier. This could be any of the following:
1434 1. Command completion event
1435 2. Buffer done callback event
1436 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001437
Arun Menon906de572013-06-18 17:01:40 -07001438 RETURN VALUE
1439 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001440
Arun Menon906de572013-06-18 17:01:40 -07001441 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001442OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1443{
1444
Arun Menon906de572013-06-18 17:01:40 -07001445 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1446 struct v4l2_fmtdesc fdesc;
1447 struct v4l2_format fmt;
1448 struct v4l2_requestbuffers bufreq;
1449 struct v4l2_control control;
1450 struct v4l2_frmsizeenum frmsize;
1451 unsigned int alignment = 0,buffer_size = 0;
1452 int fds[2];
1453 int r,ret=0;
1454 bool codec_ambiguous = false;
1455 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001456 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001457
1458#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001459 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001460 property_get("ro.board.platform", platform_name, "0");
1461 if (!strncmp(platform_name, "msm8610", 7)) {
1462 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301463 is_q6_platform = true;
1464 maxSmoothStreamingWidth = 1280;
1465 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001466 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001467#endif
1468
Arun Menon906de572013-06-18 17:01:40 -07001469 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1470 struct v4l2_control control;
1471 secure_mode = true;
1472 arbitrary_bytes = false;
1473 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301474 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1475 OMX_MAX_STRINGNAME_SIZE)){
1476 secure_mode = true;
1477 arbitrary_bytes = false;
1478 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001479 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001480
Arun Menon906de572013-06-18 17:01:40 -07001481 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001482
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001483 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001484 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001485
Arun Menon906de572013-06-18 17:01:40 -07001486 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001487 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001488 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1489 close(0);
1490 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001491
Arun Menon906de572013-06-18 17:01:40 -07001492 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001493 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001494 return OMX_ErrorInsufficientResources;
1495 }
1496 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1497 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001498
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001499 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001500 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001501 async_thread_created = true;
1502 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1503 }
1504 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001505 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001506 async_thread_created = false;
1507 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001508 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001509
Shalaj Jain273b3e02012-06-22 19:08:03 -07001510#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001511 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001512#endif
1513
Arun Menon906de572013-06-18 17:01:40 -07001514 // Copy the role information which provides the decoder kind
1515 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001516
Arun Menon906de572013-06-18 17:01:40 -07001517 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1518 OMX_MAX_STRINGNAME_SIZE)) {
1519 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1520 OMX_MAX_STRINGNAME_SIZE);
1521 drv_ctx.timestamp_adjust = true;
1522 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1523 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1524 output_capability=V4L2_PIX_FMT_MPEG4;
1525 /*Initialize Start Code for MPEG4*/
1526 codec_type_parse = CODEC_TYPE_MPEG4;
1527 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001528 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1529 OMX_MAX_STRINGNAME_SIZE)) {
1530 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1531 OMX_MAX_STRINGNAME_SIZE);
1532 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1533 output_capability = V4L2_PIX_FMT_MPEG2;
1534 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1535 /*Initialize Start Code for MPEG2*/
1536 codec_type_parse = CODEC_TYPE_MPEG2;
1537 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001538 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1539 OMX_MAX_STRINGNAME_SIZE)) {
1540 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001541 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001542 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1543 eCompressionFormat = OMX_VIDEO_CodingH263;
1544 output_capability = V4L2_PIX_FMT_H263;
1545 codec_type_parse = CODEC_TYPE_H263;
1546 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001547 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1548 OMX_MAX_STRINGNAME_SIZE)) {
1549 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001550 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001551 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1552 output_capability = V4L2_PIX_FMT_DIVX_311;
1553 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1554 codec_type_parse = CODEC_TYPE_DIVX;
1555 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001556
Arun Menon906de572013-06-18 17:01:40 -07001557 eRet = createDivxDrmContext();
1558 if (eRet != OMX_ErrorNone) {
1559 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1560 return eRet;
1561 }
1562 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1563 OMX_MAX_STRINGNAME_SIZE)) {
1564 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001565 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001566 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1567 output_capability = V4L2_PIX_FMT_DIVX;
1568 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1569 codec_type_parse = CODEC_TYPE_DIVX;
1570 codec_ambiguous = true;
1571 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001572
Arun Menon906de572013-06-18 17:01:40 -07001573 eRet = createDivxDrmContext();
1574 if (eRet != OMX_ErrorNone) {
1575 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1576 return eRet;
1577 }
1578 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1579 OMX_MAX_STRINGNAME_SIZE)) {
1580 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001581 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001582 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1583 output_capability = V4L2_PIX_FMT_DIVX;
1584 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1585 codec_type_parse = CODEC_TYPE_DIVX;
1586 codec_ambiguous = true;
1587 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001588
Arun Menon906de572013-06-18 17:01:40 -07001589 eRet = createDivxDrmContext();
1590 if (eRet != OMX_ErrorNone) {
1591 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1592 return eRet;
1593 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001594
Arun Menon906de572013-06-18 17:01:40 -07001595 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1596 OMX_MAX_STRINGNAME_SIZE)) {
1597 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1598 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1599 output_capability=V4L2_PIX_FMT_H264;
1600 eCompressionFormat = OMX_VIDEO_CodingAVC;
1601 codec_type_parse = CODEC_TYPE_H264;
1602 m_frame_parser.init_start_codes (codec_type_parse);
1603 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001604 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1605 OMX_MAX_STRINGNAME_SIZE)) {
1606 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1607 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1608 eCompressionFormat = OMX_VIDEO_CodingWMV;
1609 codec_type_parse = CODEC_TYPE_VC1;
1610 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1611 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001612 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1613 OMX_MAX_STRINGNAME_SIZE)) {
1614 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1615 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1616 eCompressionFormat = OMX_VIDEO_CodingWMV;
1617 codec_type_parse = CODEC_TYPE_VC1;
1618 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1619 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001620 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1621 OMX_MAX_STRINGNAME_SIZE)) {
1622 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1623 output_capability=V4L2_PIX_FMT_VP8;
1624 eCompressionFormat = OMX_VIDEO_CodingVPX;
1625 codec_type_parse = CODEC_TYPE_VP8;
1626 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001627
Arun Menon906de572013-06-18 17:01:40 -07001628 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001629 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001630 eRet = OMX_ErrorInvalidComponentName;
1631 }
Arun Menon906de572013-06-18 17:01:40 -07001632 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001633
Arun Menon906de572013-06-18 17:01:40 -07001634 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001635 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1636 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1637 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001638 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001639 eRet = OMX_ErrorInsufficientResources;
1640 }
1641
Arun Menon906de572013-06-18 17:01:40 -07001642 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001643
Arun Menon906de572013-06-18 17:01:40 -07001644 struct v4l2_capability cap;
1645 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1646 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001647 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001648 /*TODO: How to handle this case */
1649 } else {
1650 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001651 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001652 cap.bus_info, cap.version, cap.capabilities);
1653 }
1654 ret=0;
1655 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1656 fdesc.index=0;
1657 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001658 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001659 fdesc.pixelformat, fdesc.flags);
1660 fdesc.index++;
1661 }
1662 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1663 fdesc.index=0;
1664 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001666 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001667 fdesc.pixelformat, fdesc.flags);
1668 fdesc.index++;
1669 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001670 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001671 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1672 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1673 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1674 fmt.fmt.pix_mp.pixelformat = output_capability;
1675 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1676 if (ret) {
1677 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001678 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001679 return OMX_ErrorInsufficientResources;
1680 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001681 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001682 if (codec_ambiguous) {
1683 if (output_capability == V4L2_PIX_FMT_DIVX) {
1684 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001685
Arun Menon906de572013-06-18 17:01:40 -07001686 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1687 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1688 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1689 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1690 } else {
1691 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1692 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693
Arun Menon906de572013-06-18 17:01:40 -07001694 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1695 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1696 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001697 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001698 }
1699 } else {
1700 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1701 }
1702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001703
Jia Meng3a3c6492013-12-19 17:16:52 +08001704 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1705 m_conceal_color= atoi(property_value);
1706 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1707 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1708 control.value = m_conceal_color;
1709 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1710 if (ret) {
1711 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1712 }
1713
Arun Menon906de572013-06-18 17:01:40 -07001714 //Get the hardware capabilities
1715 memset((void *)&frmsize,0,sizeof(frmsize));
1716 frmsize.index = 0;
1717 frmsize.pixel_format = output_capability;
1718 ret = ioctl(drv_ctx.video_driver_fd,
1719 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1720 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001721 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001722 return OMX_ErrorHardware;
1723 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001724
Arun Menon906de572013-06-18 17:01:40 -07001725 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1726 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1727 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1728 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1729 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1730 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001731
Arun Menon906de572013-06-18 17:01:40 -07001732 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1733 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1734 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1735 fmt.fmt.pix_mp.pixelformat = capture_capability;
1736 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1737 if (ret) {
1738 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001739 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001740 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001741 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001742 if (secure_mode) {
1743 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1744 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001745 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001746 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1747 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001748 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001749 return OMX_ErrorInsufficientResources;
1750 }
1751 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001752
Arun Menon906de572013-06-18 17:01:40 -07001753 /*Get the Buffer requirements for input and output ports*/
1754 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1755 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1756 if (secure_mode) {
1757 drv_ctx.op_buf.alignment=SZ_1M;
1758 drv_ctx.ip_buf.alignment=SZ_1M;
1759 } else {
1760 drv_ctx.op_buf.alignment=SZ_4K;
1761 drv_ctx.ip_buf.alignment=SZ_4K;
1762 }
1763 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1764 drv_ctx.extradata = 0;
1765 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1766 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1767 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1768 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1769 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001770
Vinay Kalia5713bb32013-01-16 18:39:59 -08001771 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001772#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001773 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1774 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1775 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001776#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001777 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001778 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001779 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001780 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1781 if (m_frame_parser.mutils == NULL) {
1782 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001783
Arun Menon906de572013-06-18 17:01:40 -07001784 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001785 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001786 eRet = OMX_ErrorInsufficientResources;
1787 } else {
1788 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1789 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1790 h264_scratch.nFilledLen = 0;
1791 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001792
Arun Menon906de572013-06-18 17:01:40 -07001793 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001794 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001795 return OMX_ErrorInsufficientResources;
1796 }
1797 m_frame_parser.mutils->initialize_frame_checking_environment();
1798 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1799 }
1800 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001801
Arun Menon906de572013-06-18 17:01:40 -07001802 h264_parser = new h264_stream_parser();
1803 if (!h264_parser) {
1804 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1805 eRet = OMX_ErrorInsufficientResources;
1806 }
1807 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001808
Arun Menon906de572013-06-18 17:01:40 -07001809 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001810 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001811 eRet = OMX_ErrorInsufficientResources;
1812 } else {
1813 int temp1[2];
1814 if (fds[0] == 0 || fds[1] == 0) {
1815 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001816 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001817 return OMX_ErrorInsufficientResources;
1818 }
1819 //close (fds[0]);
1820 //close (fds[1]);
1821 fds[0] = temp1 [0];
1822 fds[1] = temp1 [1];
1823 }
1824 m_pipe_in = fds[0];
1825 m_pipe_out = fds[1];
1826 msg_thread_created = true;
1827 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001828
Arun Menon906de572013-06-18 17:01:40 -07001829 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001830 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001831 msg_thread_created = false;
1832 eRet = OMX_ErrorInsufficientResources;
1833 }
1834 }
1835 }
1836
1837 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001838 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001839 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001840 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001841 }
1842 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1843 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001844}
1845
1846/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001847 FUNCTION
1848 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849
Arun Menon906de572013-06-18 17:01:40 -07001850 DESCRIPTION
1851 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852
Arun Menon906de572013-06-18 17:01:40 -07001853 PARAMETERS
1854 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001855
Arun Menon906de572013-06-18 17:01:40 -07001856 RETURN VALUE
1857 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001858
Arun Menon906de572013-06-18 17:01:40 -07001859 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001860OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001861(
1862 OMX_IN OMX_HANDLETYPE hComp,
1863 OMX_OUT OMX_STRING componentName,
1864 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1865 OMX_OUT OMX_VERSIONTYPE* specVersion,
1866 OMX_OUT OMX_UUIDTYPE* componentUUID
1867 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001868{
Arun Menon906de572013-06-18 17:01:40 -07001869 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001870 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001871 return OMX_ErrorInvalidState;
1872 }
Arun Menon906de572013-06-18 17:01:40 -07001873 /* TBD -- Return the proper version */
1874 if (specVersion) {
1875 specVersion->nVersion = OMX_SPEC_VERSION;
1876 }
1877 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001878}
1879/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001880 FUNCTION
1881 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001882
Arun Menon906de572013-06-18 17:01:40 -07001883 DESCRIPTION
1884 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001885
Arun Menon906de572013-06-18 17:01:40 -07001886 PARAMETERS
1887 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001888
Arun Menon906de572013-06-18 17:01:40 -07001889 RETURN VALUE
1890 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891
Arun Menon906de572013-06-18 17:01:40 -07001892 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001893OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001894 OMX_IN OMX_COMMANDTYPE cmd,
1895 OMX_IN OMX_U32 param1,
1896 OMX_IN OMX_PTR cmdData
1897 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001898{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001899 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001900 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001901 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001902 return OMX_ErrorInvalidState;
1903 }
1904 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001905 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001906 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001907 "to invalid port: %lu", param1);
1908 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001909 }
1910 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1911 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001912 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001913 return OMX_ErrorNone;
1914}
1915
1916/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001917 FUNCTION
1918 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001919
Arun Menon906de572013-06-18 17:01:40 -07001920 DESCRIPTION
1921 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001922
Arun Menon906de572013-06-18 17:01:40 -07001923 PARAMETERS
1924 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001925
Arun Menon906de572013-06-18 17:01:40 -07001926 RETURN VALUE
1927 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001928
Arun Menon906de572013-06-18 17:01:40 -07001929 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001930OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001931 OMX_IN OMX_COMMANDTYPE cmd,
1932 OMX_IN OMX_U32 param1,
1933 OMX_IN OMX_PTR cmdData
1934 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001935{
Arun Menon906de572013-06-18 17:01:40 -07001936 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1937 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1938 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001939
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001940 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1941 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001942 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001943
Arun Menon906de572013-06-18 17:01:40 -07001944 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001945 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1946 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001947 /***************************/
1948 /* Current State is Loaded */
1949 /***************************/
1950 if (m_state == OMX_StateLoaded) {
1951 if (eState == OMX_StateIdle) {
1952 //if all buffers are allocated or all ports disabled
1953 if (allocate_done() ||
1954 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001955 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001956 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001957 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001958 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1959 // Skip the event notification
1960 bFlag = 0;
1961 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001962 }
Arun Menon906de572013-06-18 17:01:40 -07001963 /* Requesting transition from Loaded to Loaded */
1964 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001965 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001966 post_event(OMX_EventError,OMX_ErrorSameState,\
1967 OMX_COMPONENT_GENERATE_EVENT);
1968 eRet = OMX_ErrorSameState;
1969 }
1970 /* Requesting transition from Loaded to WaitForResources */
1971 else if (eState == OMX_StateWaitForResources) {
1972 /* Since error is None , we will post an event
1973 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001974 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001975 }
1976 /* Requesting transition from Loaded to Executing */
1977 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001978 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001979 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1980 OMX_COMPONENT_GENERATE_EVENT);
1981 eRet = OMX_ErrorIncorrectStateTransition;
1982 }
1983 /* Requesting transition from Loaded to Pause */
1984 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001985 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001986 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1987 OMX_COMPONENT_GENERATE_EVENT);
1988 eRet = OMX_ErrorIncorrectStateTransition;
1989 }
1990 /* Requesting transition from Loaded to Invalid */
1991 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001993 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1994 eRet = OMX_ErrorInvalidState;
1995 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001996 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001997 eState);
1998 eRet = OMX_ErrorBadParameter;
1999 }
2000 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002001
Arun Menon906de572013-06-18 17:01:40 -07002002 /***************************/
2003 /* Current State is IDLE */
2004 /***************************/
2005 else if (m_state == OMX_StateIdle) {
2006 if (eState == OMX_StateLoaded) {
2007 if (release_done()) {
2008 /*
2009 Since error is None , we will post an event at the end
2010 of this function definition
2011 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002012 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002013 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002015 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2016 // Skip the event notification
2017 bFlag = 0;
2018 }
2019 }
2020 /* Requesting transition from Idle to Executing */
2021 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002022 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002023 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2024 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002025 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002026 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002027 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002028 }
2029 /* Requesting transition from Idle to Idle */
2030 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002031 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002032 post_event(OMX_EventError,OMX_ErrorSameState,\
2033 OMX_COMPONENT_GENERATE_EVENT);
2034 eRet = OMX_ErrorSameState;
2035 }
2036 /* Requesting transition from Idle to WaitForResources */
2037 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002038 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002039 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2040 OMX_COMPONENT_GENERATE_EVENT);
2041 eRet = OMX_ErrorIncorrectStateTransition;
2042 }
2043 /* Requesting transition from Idle to Pause */
2044 else if (eState == OMX_StatePause) {
2045 /*To pause the Video core we need to start the driver*/
2046 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2047 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002048 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002049 omx_report_error ();
2050 eRet = OMX_ErrorHardware;
2051 } else {
2052 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002053 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002054 bFlag = 0;
2055 }
2056 }
2057 /* Requesting transition from Idle to Invalid */
2058 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002059 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002060 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2061 eRet = OMX_ErrorInvalidState;
2062 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002063 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002064 eRet = OMX_ErrorBadParameter;
2065 }
2066 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002067
Arun Menon906de572013-06-18 17:01:40 -07002068 /******************************/
2069 /* Current State is Executing */
2070 /******************************/
2071 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002072 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002073 /* Requesting transition from Executing to Idle */
2074 if (eState == OMX_StateIdle) {
2075 /* Since error is None , we will post an event
2076 at the end of this function definition
2077 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002078 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002079 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2080 if (!sem_posted) {
2081 sem_posted = 1;
2082 sem_post (&m_cmd_lock);
2083 execute_omx_flush(OMX_ALL);
2084 }
2085 bFlag = 0;
2086 }
2087 /* Requesting transition from Executing to Paused */
2088 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002089 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002090 m_state = OMX_StatePause;
2091 bFlag = 1;
2092 }
2093 /* Requesting transition from Executing to Loaded */
2094 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002095 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002096 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2097 OMX_COMPONENT_GENERATE_EVENT);
2098 eRet = OMX_ErrorIncorrectStateTransition;
2099 }
2100 /* Requesting transition from Executing to WaitForResources */
2101 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002102 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002103 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2104 OMX_COMPONENT_GENERATE_EVENT);
2105 eRet = OMX_ErrorIncorrectStateTransition;
2106 }
2107 /* Requesting transition from Executing to Executing */
2108 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002109 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002110 post_event(OMX_EventError,OMX_ErrorSameState,\
2111 OMX_COMPONENT_GENERATE_EVENT);
2112 eRet = OMX_ErrorSameState;
2113 }
2114 /* Requesting transition from Executing to Invalid */
2115 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002116 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002117 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2118 eRet = OMX_ErrorInvalidState;
2119 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002120 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002121 eRet = OMX_ErrorBadParameter;
2122 }
2123 }
2124 /***************************/
2125 /* Current State is Pause */
2126 /***************************/
2127 else if (m_state == OMX_StatePause) {
2128 /* Requesting transition from Pause to Executing */
2129 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002130 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002131 m_state = OMX_StateExecuting;
2132 bFlag = 1;
2133 }
2134 /* Requesting transition from Pause to Idle */
2135 else if (eState == OMX_StateIdle) {
2136 /* Since error is None , we will post an event
2137 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002138 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002139 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2140 if (!sem_posted) {
2141 sem_posted = 1;
2142 sem_post (&m_cmd_lock);
2143 execute_omx_flush(OMX_ALL);
2144 }
2145 bFlag = 0;
2146 }
2147 /* Requesting transition from Pause to loaded */
2148 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002149 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002150 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2151 OMX_COMPONENT_GENERATE_EVENT);
2152 eRet = OMX_ErrorIncorrectStateTransition;
2153 }
2154 /* Requesting transition from Pause to WaitForResources */
2155 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002156 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002157 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2158 OMX_COMPONENT_GENERATE_EVENT);
2159 eRet = OMX_ErrorIncorrectStateTransition;
2160 }
2161 /* Requesting transition from Pause to Pause */
2162 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002163 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002164 post_event(OMX_EventError,OMX_ErrorSameState,\
2165 OMX_COMPONENT_GENERATE_EVENT);
2166 eRet = OMX_ErrorSameState;
2167 }
2168 /* Requesting transition from Pause to Invalid */
2169 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002170 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002171 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2172 eRet = OMX_ErrorInvalidState;
2173 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002174 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002175 eRet = OMX_ErrorBadParameter;
2176 }
2177 }
2178 /***************************/
2179 /* Current State is WaitForResources */
2180 /***************************/
2181 else if (m_state == OMX_StateWaitForResources) {
2182 /* Requesting transition from WaitForResources to Loaded */
2183 if (eState == OMX_StateLoaded) {
2184 /* Since error is None , we will post an event
2185 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002186 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002187 }
2188 /* Requesting transition from WaitForResources to WaitForResources */
2189 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002190 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002191 post_event(OMX_EventError,OMX_ErrorSameState,
2192 OMX_COMPONENT_GENERATE_EVENT);
2193 eRet = OMX_ErrorSameState;
2194 }
2195 /* Requesting transition from WaitForResources to Executing */
2196 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002197 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002198 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2199 OMX_COMPONENT_GENERATE_EVENT);
2200 eRet = OMX_ErrorIncorrectStateTransition;
2201 }
2202 /* Requesting transition from WaitForResources to Pause */
2203 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002204 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002205 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2206 OMX_COMPONENT_GENERATE_EVENT);
2207 eRet = OMX_ErrorIncorrectStateTransition;
2208 }
2209 /* Requesting transition from WaitForResources to Invalid */
2210 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002212 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2213 eRet = OMX_ErrorInvalidState;
2214 }
2215 /* Requesting transition from WaitForResources to Loaded -
2216 is NOT tested by Khronos TS */
2217
2218 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002219 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002220 eRet = OMX_ErrorBadParameter;
2221 }
2222 }
2223 /********************************/
2224 /* Current State is Invalid */
2225 /*******************************/
2226 else if (m_state == OMX_StateInvalid) {
2227 /* State Transition from Inavlid to any state */
2228 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2229 || OMX_StateIdle || OMX_StateExecuting
2230 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002231 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002232 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2233 OMX_COMPONENT_GENERATE_EVENT);
2234 eRet = OMX_ErrorInvalidState;
2235 }
2236 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002237 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002238 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002239#ifdef _MSM8974_
2240 send_codec_config();
2241#endif
Arun Menon906de572013-06-18 17:01:40 -07002242 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2243 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2244 }
2245 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2246 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2247 }
2248 if (!sem_posted) {
2249 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002250 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002251 sem_post (&m_cmd_lock);
2252 execute_omx_flush(param1);
2253 }
2254 bFlag = 0;
2255 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002256 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002257 "with param1: %lu", param1);
2258 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2259 m_inp_bEnabled = OMX_TRUE;
2260
2261 if ( (m_state == OMX_StateLoaded &&
2262 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2263 || allocate_input_done()) {
2264 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2265 OMX_COMPONENT_GENERATE_EVENT);
2266 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002267 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002268 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2269 // Skip the event notification
2270 bFlag = 0;
2271 }
2272 }
2273 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002274 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002275 m_out_bEnabled = OMX_TRUE;
2276
2277 if ( (m_state == OMX_StateLoaded &&
2278 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2279 || (allocate_output_done())) {
2280 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2281 OMX_COMPONENT_GENERATE_EVENT);
2282
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_OUTPUT_ENABLE_PENDING);
2286 // Skip the event notification
2287 bFlag = 0;
2288 }
2289 }
2290 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002291 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002292 "with param1: %lu", param1);
2293 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002294 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002295 m_inp_bEnabled = OMX_FALSE;
2296 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2297 && release_input_done()) {
2298 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2299 OMX_COMPONENT_GENERATE_EVENT);
2300 } else {
2301 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2302 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2303 if (!sem_posted) {
2304 sem_posted = 1;
2305 sem_post (&m_cmd_lock);
2306 }
2307 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2308 }
2309
2310 // Skip the event notification
2311 bFlag = 0;
2312 }
2313 }
2314 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2315 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002316 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002317 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2318 && release_output_done()) {
2319 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2320 OMX_COMPONENT_GENERATE_EVENT);
2321 } else {
2322 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2323 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2324 if (!sem_posted) {
2325 sem_posted = 1;
2326 sem_post (&m_cmd_lock);
2327 }
2328 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2329 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2330 }
2331 // Skip the event notification
2332 bFlag = 0;
2333
2334 }
2335 }
2336 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002337 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002338 eRet = OMX_ErrorNotImplemented;
2339 }
2340 if (eRet == OMX_ErrorNone && bFlag) {
2341 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2342 }
2343 if (!sem_posted) {
2344 sem_post(&m_cmd_lock);
2345 }
2346
2347 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002348}
2349
2350/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002351 FUNCTION
2352 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002353
Arun Menon906de572013-06-18 17:01:40 -07002354 DESCRIPTION
2355 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002356
Arun Menon906de572013-06-18 17:01:40 -07002357 PARAMETERS
2358 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002359
Arun Menon906de572013-06-18 17:01:40 -07002360 RETURN VALUE
2361 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002362
Arun Menon906de572013-06-18 17:01:40 -07002363 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002364bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2365{
Arun Menon906de572013-06-18 17:01:40 -07002366 bool bRet = false;
2367 struct v4l2_plane plane;
2368 struct v4l2_buffer v4l2_buf;
2369 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302370 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002371 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2372 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002373
Arun Menon906de572013-06-18 17:01:40 -07002374 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002375
Arun Menon906de572013-06-18 17:01:40 -07002376 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2377 output_flush_progress = true;
2378 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2379 } else {
2380 /* XXX: The driver/hardware does not support flushing of individual ports
2381 * in all states. So we pretty much need to flush both ports internally,
2382 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2383 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2384 * we automatically omit sending the FLUSH done for the "opposite" port. */
2385 input_flush_progress = true;
2386 output_flush_progress = true;
2387 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2388 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002389
Arun Menon906de572013-06-18 17:01:40 -07002390 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002391 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002392 bRet = false;
2393 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002394
Arun Menon906de572013-06-18 17:01:40 -07002395 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002396}
2397/*=========================================================================
2398FUNCTION : execute_output_flush
2399
2400DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002401Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002402
2403PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002404None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002405
2406RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002407true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002408==========================================================================*/
2409bool omx_vdec::execute_output_flush()
2410{
Arun Menon906de572013-06-18 17:01:40 -07002411 unsigned p1 = 0; // Parameter - 1
2412 unsigned p2 = 0; // Parameter - 2
2413 unsigned ident = 0;
2414 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002415
Arun Menon906de572013-06-18 17:01:40 -07002416 /*Generate FBD for all Buffers in the FTBq*/
2417 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002418 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002419
2420 //reset last render TS
2421 if(m_last_rendered_TS > 0) {
2422 m_last_rendered_TS = 0;
2423 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002424
Arun Menon906de572013-06-18 17:01:40 -07002425 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002426 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002427 m_ftb_q.m_size,pending_output_buffers);
2428 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002429 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002430 if (ident == m_fill_output_msg ) {
2431 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2432 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2433 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002435 }
Arun Menon906de572013-06-18 17:01:40 -07002436 pthread_mutex_unlock(&m_lock);
2437 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002438
Arun Menon906de572013-06-18 17:01:40 -07002439 if (arbitrary_bytes) {
2440 prev_ts = LLONG_MAX;
2441 rst_prev_ts = true;
2442 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002443 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002444 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002445}
2446/*=========================================================================
2447FUNCTION : execute_input_flush
2448
2449DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002450Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002451
2452PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002453None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002454
2455RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002456true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002457==========================================================================*/
2458bool omx_vdec::execute_input_flush()
2459{
Arun Menon906de572013-06-18 17:01:40 -07002460 unsigned i =0;
2461 unsigned p1 = 0; // Parameter - 1
2462 unsigned p2 = 0; // Parameter - 2
2463 unsigned ident = 0;
2464 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002465
Arun Menon906de572013-06-18 17:01:40 -07002466 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002467 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002468
Arun Menon906de572013-06-18 17:01:40 -07002469 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002470 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002471 while (m_etb_q.m_size) {
2472 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002473
Arun Menon906de572013-06-18 17:01:40 -07002474 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002475 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002476 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2477 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2478 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002479 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002480 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2481 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2482 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002483 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002484 (OMX_BUFFERHEADERTYPE *)p1);
2485 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487 }
Arun Menon906de572013-06-18 17:01:40 -07002488 time_stamp_dts.flush_timestamp();
2489 /*Check if Heap Buffers are to be flushed*/
2490 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002491 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002492 h264_scratch.nFilledLen = 0;
2493 nal_count = 0;
2494 look_ahead_nal = false;
2495 frame_count = 0;
2496 h264_last_au_ts = LLONG_MAX;
2497 h264_last_au_flags = 0;
2498 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2499 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002500 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002501 if (m_frame_parser.mutils) {
2502 m_frame_parser.mutils->initialize_frame_checking_environment();
2503 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504
Arun Menon906de572013-06-18 17:01:40 -07002505 while (m_input_pending_q.m_size) {
2506 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2507 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2508 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002509
Arun Menon906de572013-06-18 17:01:40 -07002510 if (psource_frame) {
2511 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2512 psource_frame = NULL;
2513 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002514
Arun Menon906de572013-06-18 17:01:40 -07002515 if (pdest_frame) {
2516 pdest_frame->nFilledLen = 0;
2517 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2518 (unsigned int)NULL);
2519 pdest_frame = NULL;
2520 }
2521 m_frame_parser.flush();
2522 } else if (codec_config_flag) {
2523 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2524 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002525 }
Arun Menon906de572013-06-18 17:01:40 -07002526 pthread_mutex_unlock(&m_lock);
2527 input_flush_progress = false;
2528 if (!arbitrary_bytes) {
2529 prev_ts = LLONG_MAX;
2530 rst_prev_ts = true;
2531 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002532#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002533 if (m_debug_timestamp) {
2534 m_timestamp_list.reset_ts_list();
2535 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002536#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002537 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002538 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002539}
2540
2541
2542/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002543 FUNCTION
2544 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002545
Arun Menon906de572013-06-18 17:01:40 -07002546 DESCRIPTION
2547 Send the event to decoder pipe. This is needed to generate the callbacks
2548 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002549
Arun Menon906de572013-06-18 17:01:40 -07002550 PARAMETERS
2551 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002552
Arun Menon906de572013-06-18 17:01:40 -07002553 RETURN VALUE
2554 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002555
Arun Menon906de572013-06-18 17:01:40 -07002556 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002557bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002558 unsigned int p2,
2559 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002560{
Arun Menon906de572013-06-18 17:01:40 -07002561 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002562
2563
Arun Menon906de572013-06-18 17:01:40 -07002564 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002565
Arun Menon906de572013-06-18 17:01:40 -07002566 if (id == m_fill_output_msg ||
2567 id == OMX_COMPONENT_GENERATE_FBD) {
2568 m_ftb_q.insert_entry(p1,p2,id);
2569 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2570 id == OMX_COMPONENT_GENERATE_EBD ||
2571 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2572 m_etb_q.insert_entry(p1,p2,id);
2573 } else {
2574 m_cmd_q.insert_entry(p1,p2,id);
2575 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002576
Arun Menon906de572013-06-18 17:01:40 -07002577 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002578 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002579 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002580
Arun Menon906de572013-06-18 17:01:40 -07002581 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002582
Arun Menon906de572013-06-18 17:01:40 -07002583 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002584}
2585
2586OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2587{
Arun Menon906de572013-06-18 17:01:40 -07002588 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2589 if (!profileLevelType)
2590 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002591
Arun Menon906de572013-06-18 17:01:40 -07002592 if (profileLevelType->nPortIndex == 0) {
2593 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2594 if (profileLevelType->nProfileIndex == 0) {
2595 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2596 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002597
Arun Menon906de572013-06-18 17:01:40 -07002598 } else if (profileLevelType->nProfileIndex == 1) {
2599 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2600 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2601 } else if (profileLevelType->nProfileIndex == 2) {
2602 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2603 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2604 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002605 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002606 profileLevelType->nProfileIndex);
2607 eRet = OMX_ErrorNoMore;
2608 }
2609 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2610 if (profileLevelType->nProfileIndex == 0) {
2611 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2612 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2613 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002614 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002615 eRet = OMX_ErrorNoMore;
2616 }
2617 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2618 if (profileLevelType->nProfileIndex == 0) {
2619 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2620 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2621 } else if (profileLevelType->nProfileIndex == 1) {
2622 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2623 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2624 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002625 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002626 eRet = OMX_ErrorNoMore;
2627 }
2628 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2629 eRet = OMX_ErrorNoMore;
2630 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2631 if (profileLevelType->nProfileIndex == 0) {
2632 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2633 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2634 } else if (profileLevelType->nProfileIndex == 1) {
2635 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2636 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2637 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002638 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002639 eRet = OMX_ErrorNoMore;
2640 }
2641 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002642 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002643 eRet = OMX_ErrorNoMore;
2644 }
2645 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002646 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002647 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002648 }
Arun Menon906de572013-06-18 17:01:40 -07002649 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002650}
2651
2652/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002653 FUNCTION
2654 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002655
Arun Menon906de572013-06-18 17:01:40 -07002656 DESCRIPTION
2657 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002658
Arun Menon906de572013-06-18 17:01:40 -07002659 PARAMETERS
2660 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002661
Arun Menon906de572013-06-18 17:01:40 -07002662 RETURN VALUE
2663 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002664
Arun Menon906de572013-06-18 17:01:40 -07002665 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002666OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002667 OMX_IN OMX_INDEXTYPE paramIndex,
2668 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002669{
2670 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2671
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002672 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002673 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002674 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675 return OMX_ErrorInvalidState;
2676 }
Arun Menon906de572013-06-18 17:01:40 -07002677 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002678 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002679 return OMX_ErrorBadParameter;
2680 }
Arun Menon906de572013-06-18 17:01:40 -07002681 switch ((unsigned long)paramIndex) {
2682 case OMX_IndexParamPortDefinition: {
2683 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2684 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002685 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002686 eRet = update_portdef(portDefn);
2687 if (eRet == OMX_ErrorNone)
2688 m_port_def = *portDefn;
2689 break;
2690 }
2691 case OMX_IndexParamVideoInit: {
2692 OMX_PORT_PARAM_TYPE *portParamType =
2693 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002694 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002695
Arun Menon906de572013-06-18 17:01:40 -07002696 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2697 portParamType->nSize = sizeof(portParamType);
2698 portParamType->nPorts = 2;
2699 portParamType->nStartPortNumber = 0;
2700 break;
2701 }
2702 case OMX_IndexParamVideoPortFormat: {
2703 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2704 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002705 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002706
Arun Menon906de572013-06-18 17:01:40 -07002707 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2708 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002709
Arun Menon906de572013-06-18 17:01:40 -07002710 if (0 == portFmt->nPortIndex) {
2711 if (0 == portFmt->nIndex) {
2712 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2713 portFmt->eCompressionFormat = eCompressionFormat;
2714 } else {
2715 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002716 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002717 eRet = OMX_ErrorNoMore;
2718 }
2719 } else if (1 == portFmt->nPortIndex) {
2720 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002721
Arun Menon906de572013-06-18 17:01:40 -07002722 if (0 == portFmt->nIndex)
2723 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2724 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2725 else if (1 == portFmt->nIndex)
2726 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2727 else {
2728 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002729 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002730 eRet = OMX_ErrorNoMore;
2731 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002732 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002733 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002734 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002735 (int)portFmt->nPortIndex);
2736 eRet = OMX_ErrorBadPortIndex;
2737 }
2738 break;
2739 }
2740 /*Component should support this port definition*/
2741 case OMX_IndexParamAudioInit: {
2742 OMX_PORT_PARAM_TYPE *audioPortParamType =
2743 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002744 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002745 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2746 audioPortParamType->nSize = sizeof(audioPortParamType);
2747 audioPortParamType->nPorts = 0;
2748 audioPortParamType->nStartPortNumber = 0;
2749 break;
2750 }
2751 /*Component should support this port definition*/
2752 case OMX_IndexParamImageInit: {
2753 OMX_PORT_PARAM_TYPE *imagePortParamType =
2754 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002755 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002756 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2757 imagePortParamType->nSize = sizeof(imagePortParamType);
2758 imagePortParamType->nPorts = 0;
2759 imagePortParamType->nStartPortNumber = 0;
2760 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002761
Arun Menon906de572013-06-18 17:01:40 -07002762 }
2763 /*Component should support this port definition*/
2764 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002765 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002766 paramIndex);
2767 eRet =OMX_ErrorUnsupportedIndex;
2768 break;
2769 }
2770 case OMX_IndexParamStandardComponentRole: {
2771 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2772 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2773 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2774 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002775
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002776 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002777 paramIndex);
2778 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2779 OMX_MAX_STRINGNAME_SIZE);
2780 break;
2781 }
2782 /* Added for parameter test */
2783 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784
Arun Menon906de572013-06-18 17:01:40 -07002785 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2786 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002787 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002788 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2789 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002790
Arun Menon906de572013-06-18 17:01:40 -07002791 break;
2792 }
2793 /* Added for parameter test */
2794 case OMX_IndexParamCompBufferSupplier: {
2795 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2796 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002797 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798
Arun Menon906de572013-06-18 17:01:40 -07002799 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2800 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2801 if (0 == bufferSupplierType->nPortIndex)
2802 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2803 else if (1 == bufferSupplierType->nPortIndex)
2804 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2805 else
2806 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002807
2808
Arun Menon906de572013-06-18 17:01:40 -07002809 break;
2810 }
2811 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002812 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002813 paramIndex);
2814 break;
2815 }
2816 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002817 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002818 paramIndex);
2819 break;
2820 }
2821 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002822 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002823 paramIndex);
2824 break;
2825 }
2826 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002827 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002828 paramIndex);
2829 break;
2830 }
2831 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002832 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002833 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2834 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2835 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2836 break;
2837 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002838#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002839 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002840 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002841 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2842 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002843
Arun Menon906de572013-06-18 17:01:40 -07002844 if (secure_mode) {
2845 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2846 GRALLOC_USAGE_PRIVATE_UNCACHED);
2847 } else {
2848 nativeBuffersUsage->nUsage =
2849 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2850 GRALLOC_USAGE_PRIVATE_UNCACHED);
2851 }
2852 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002853 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002854 eRet = OMX_ErrorBadParameter;
2855 }
2856 }
2857 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002858#endif
2859
Arun Menon906de572013-06-18 17:01:40 -07002860 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002861 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002862 eRet =OMX_ErrorUnsupportedIndex;
2863 }
2864
Shalaj Jain273b3e02012-06-22 19:08:03 -07002865 }
2866
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002867 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002868 drv_ctx.video_resolution.frame_width,
2869 drv_ctx.video_resolution.frame_height,
2870 drv_ctx.video_resolution.stride,
2871 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002872
Arun Menon906de572013-06-18 17:01:40 -07002873 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002874}
2875
2876#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2877OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2878{
2879 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2880 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2881 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2882
Arun Menon906de572013-06-18 17:01:40 -07002883 if ((params == NULL) ||
2884 (params->nativeBuffer == NULL) ||
2885 (params->nativeBuffer->handle == NULL) ||
2886 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002887 return OMX_ErrorBadParameter;
2888 m_use_android_native_buffers = OMX_TRUE;
2889 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2890 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002891 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 -07002892 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002893 if (!secure_mode) {
2894 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002895 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002896 if (buffer == MAP_FAILED) {
2897 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2898 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002899 }
2900 }
2901 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2902 } else {
2903 eRet = OMX_ErrorBadParameter;
2904 }
2905 return eRet;
2906}
2907#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002908
2909OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2910 struct v4l2_control control;
2911 struct v4l2_format fmt;
2912 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2913 control.value = 1;
2914 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2915 if (rc < 0) {
2916 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2917 return OMX_ErrorHardware;
2918 }
2919 m_smoothstreaming_mode = true;
2920 return OMX_ErrorNone;
2921}
2922
Shalaj Jain273b3e02012-06-22 19:08:03 -07002923/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002924 FUNCTION
2925 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002926
Arun Menon906de572013-06-18 17:01:40 -07002927 DESCRIPTION
2928 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002929
Arun Menon906de572013-06-18 17:01:40 -07002930 PARAMETERS
2931 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002932
Arun Menon906de572013-06-18 17:01:40 -07002933 RETURN VALUE
2934 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002935
Arun Menon906de572013-06-18 17:01:40 -07002936 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002937OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002938 OMX_IN OMX_INDEXTYPE paramIndex,
2939 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002940{
2941 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002942 int ret=0;
2943 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002944 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002945 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002946 return OMX_ErrorInvalidState;
2947 }
Arun Menon906de572013-06-18 17:01:40 -07002948 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002949 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002950 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002951 }
Arun Menon906de572013-06-18 17:01:40 -07002952 if ((m_state != OMX_StateLoaded) &&
2953 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2954 (m_out_bEnabled == OMX_TRUE) &&
2955 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2956 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002957 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002958 return OMX_ErrorIncorrectStateOperation;
2959 }
Arun Menon906de572013-06-18 17:01:40 -07002960 switch ((unsigned long)paramIndex) {
2961 case OMX_IndexParamPortDefinition: {
2962 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2963 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2964 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2965 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002966 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002967 (int)portDefn->format.video.nFrameHeight,
2968 (int)portDefn->format.video.nFrameWidth);
2969 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002970 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002971 m_display_id = portDefn->format.video.pNativeWindow;
2972 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002973 /* update output port resolution with client supplied dimensions
2974 in case scaling is enabled, else it follows input resolution set
2975 */
2976 if (is_down_scalar_enabled) {
2977 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002978 portDefn->format.video.nFrameWidth,
2979 portDefn->format.video.nFrameHeight);
2980 if (portDefn->format.video.nFrameHeight != 0x0 &&
2981 portDefn->format.video.nFrameWidth != 0x0) {
2982 update_resolution(portDefn->format.video.nFrameWidth,
2983 portDefn->format.video.nFrameHeight,
2984 portDefn->format.video.nFrameWidth,
2985 portDefn->format.video.nFrameHeight);
2986 eRet = is_video_session_supported();
2987 if (eRet)
2988 break;
2989 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2990 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2991 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2992 fmt.fmt.pix_mp.pixelformat = capture_capability;
2993 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);
2994 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2995 if (ret) {
2996 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2997 eRet = OMX_ErrorUnsupportedSetting;
2998 } else
2999 eRet = get_buffer_req(&drv_ctx.op_buf);
3000 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003001 }
Arun Menon906de572013-06-18 17:01:40 -07003002 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003003 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003004 eRet = OMX_ErrorBadParameter;
3005 } else {
3006 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3007 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3008 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3009 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3010 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3011 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3012 drv_ctx.extradata_info.buffer_size;
3013 eRet = set_buffer_req(&drv_ctx.op_buf);
3014 if (eRet == OMX_ErrorNone)
3015 m_port_def = *portDefn;
3016 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003017 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003018 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3019 portDefn->nBufferCountActual, portDefn->nBufferSize);
3020 eRet = OMX_ErrorBadParameter;
3021 }
3022 }
3023 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003024 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003025 bool port_format_changed = false;
3026 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3027 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3028 // Frame rate only should be set if this is a "known value" or to
3029 // activate ts prediction logic (arbitrary mode only) sending input
3030 // timestamps with max value (LLONG_MAX).
3031 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3032 portDefn->format.video.xFramerate >> 16);
3033 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3034 drv_ctx.frame_rate.fps_denominator);
3035 if (!drv_ctx.frame_rate.fps_numerator) {
3036 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3037 drv_ctx.frame_rate.fps_numerator = 30;
3038 }
3039 if (drv_ctx.frame_rate.fps_denominator)
3040 drv_ctx.frame_rate.fps_numerator = (int)
3041 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3042 drv_ctx.frame_rate.fps_denominator = 1;
3043 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3044 drv_ctx.frame_rate.fps_numerator;
3045 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3046 frm_int, drv_ctx.frame_rate.fps_numerator /
3047 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003048
3049 struct v4l2_outputparm oparm;
3050 /*XXX: we're providing timing info as seconds per frame rather than frames
3051 * per second.*/
3052 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3053 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3054
3055 struct v4l2_streamparm sparm;
3056 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3057 sparm.parm.output = oparm;
3058 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3059 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3060 eRet = OMX_ErrorHardware;
3061 break;
3062 }
Arun Menon906de572013-06-18 17:01:40 -07003063 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003064
Arun Menon906de572013-06-18 17:01:40 -07003065 if (drv_ctx.video_resolution.frame_height !=
3066 portDefn->format.video.nFrameHeight ||
3067 drv_ctx.video_resolution.frame_width !=
3068 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003069 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003070 portDefn->format.video.nFrameWidth,
3071 portDefn->format.video.nFrameHeight);
3072 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003073 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3074 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3075 if (frameHeight != 0x0 && frameWidth != 0x0) {
3076 if (m_smoothstreaming_mode &&
3077 ((frameWidth * frameHeight) <
3078 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3079 frameWidth = m_smoothstreaming_width;
3080 frameHeight = m_smoothstreaming_height;
3081 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3082 frameWidth, frameHeight);
3083 }
3084 update_resolution(frameWidth, frameHeight,
3085 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003086 eRet = is_video_session_supported();
3087 if (eRet)
3088 break;
3089 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3090 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3091 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3092 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003093 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 -07003094 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3095 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003096 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003097 eRet = OMX_ErrorUnsupportedSetting;
3098 } else
3099 eRet = get_buffer_req(&drv_ctx.op_buf);
3100 }
3101 }
3102 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3103 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3104 port_format_changed = true;
3105 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3106 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3107 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3108 (~(buffer_prop->alignment - 1));
3109 eRet = set_buffer_req(buffer_prop);
3110 }
3111 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003112 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003113 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3114 portDefn->nBufferCountActual, portDefn->nBufferSize);
3115 eRet = OMX_ErrorBadParameter;
3116 }
3117 } else if (portDefn->eDir == OMX_DirMax) {
3118 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3119 (int)portDefn->nPortIndex);
3120 eRet = OMX_ErrorBadPortIndex;
3121 }
3122 }
3123 break;
3124 case OMX_IndexParamVideoPortFormat: {
3125 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3126 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3127 int ret=0;
3128 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003129 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003130 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003131
Arun Menon906de572013-06-18 17:01:40 -07003132 if (1 == portFmt->nPortIndex) {
3133 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3134 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3135 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3136 fmt.fmt.pix_mp.pixelformat = capture_capability;
3137 enum vdec_output_fromat op_format;
3138 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3139 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3140 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3141 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3142 else if (portFmt->eColorFormat ==
3143 (OMX_COLOR_FORMATTYPE)
3144 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3145 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3146 else
3147 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003148
Arun Menon906de572013-06-18 17:01:40 -07003149 if (eRet == OMX_ErrorNone) {
3150 drv_ctx.output_format = op_format;
3151 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3152 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003153 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003154 eRet = OMX_ErrorUnsupportedSetting;
3155 /*TODO: How to handle this case */
3156 } else {
3157 eRet = get_buffer_req(&drv_ctx.op_buf);
3158 }
3159 }
3160 if (eRet == OMX_ErrorNone) {
3161 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003162 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003163 eRet = OMX_ErrorBadParameter;
3164 }
3165 }
3166 }
3167 }
3168 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003169
Arun Menon906de572013-06-18 17:01:40 -07003170 case OMX_QcomIndexPortDefn: {
3171 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3172 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003173 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003174 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003175
Arun Menon906de572013-06-18 17:01:40 -07003176 /* Input port */
3177 if (portFmt->nPortIndex == 0) {
3178 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3179 if (secure_mode) {
3180 arbitrary_bytes = false;
3181 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3182 eRet = OMX_ErrorUnsupportedSetting;
3183 } else {
3184 arbitrary_bytes = true;
3185 }
3186 } else if (portFmt->nFramePackingFormat ==
3187 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3188 arbitrary_bytes = false;
3189 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003190 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003191 portFmt->nFramePackingFormat);
3192 eRet = OMX_ErrorUnsupportedSetting;
3193 }
3194 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003195 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003196 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3197 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3198 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3199 m_out_mem_region_smi = OMX_TRUE;
3200 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003201 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003202 m_use_output_pmem = OMX_TRUE;
3203 }
3204 }
3205 }
3206 }
3207 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003208
Arun Menon906de572013-06-18 17:01:40 -07003209 case OMX_IndexParamStandardComponentRole: {
3210 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3211 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003212 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003213 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003214
Arun Menon906de572013-06-18 17:01:40 -07003215 if ((m_state == OMX_StateLoaded)&&
3216 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3217 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3218 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003219 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003220 return OMX_ErrorIncorrectStateOperation;
3221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003222
Arun Menon906de572013-06-18 17:01:40 -07003223 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3224 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3225 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3226 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003227 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003228 eRet =OMX_ErrorUnsupportedSetting;
3229 }
3230 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3231 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3232 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3233 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003234 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003235 eRet = OMX_ErrorUnsupportedSetting;
3236 }
3237 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3238 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3239 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3240 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003241 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003242 eRet =OMX_ErrorUnsupportedSetting;
3243 }
3244 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3245 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3246 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3247 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003248 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003249 eRet = OMX_ErrorUnsupportedSetting;
3250 }
3251 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3252 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3253 ) {
3254 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3255 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3256 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003257 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003258 eRet =OMX_ErrorUnsupportedSetting;
3259 }
3260 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3261 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3262 ) {
3263 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3264 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3265 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003266 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003267 eRet =OMX_ErrorUnsupportedSetting;
3268 }
3269 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3270 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3271 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3272 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3273 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003274 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003275 eRet = OMX_ErrorUnsupportedSetting;
3276 }
3277 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003278 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003279 eRet = OMX_ErrorInvalidComponentName;
3280 }
3281 break;
3282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003283
Arun Menon906de572013-06-18 17:01:40 -07003284 case OMX_IndexParamPriorityMgmt: {
3285 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003286 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003287 return OMX_ErrorIncorrectStateOperation;
3288 }
3289 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003290 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003291 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003292
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003293 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003294 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003295
Arun Menon906de572013-06-18 17:01:40 -07003296 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3297 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003298
Arun Menon906de572013-06-18 17:01:40 -07003299 break;
3300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003301
Arun Menon906de572013-06-18 17:01:40 -07003302 case OMX_IndexParamCompBufferSupplier: {
3303 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003304 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003305 bufferSupplierType->eBufferSupplier);
3306 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3307 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003308
Arun Menon906de572013-06-18 17:01:40 -07003309 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003310
Arun Menon906de572013-06-18 17:01:40 -07003311 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003312
Arun Menon906de572013-06-18 17:01:40 -07003313 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003314
Arun Menon906de572013-06-18 17:01:40 -07003315 }
3316 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003317 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003318 paramIndex);
3319 break;
3320 }
3321 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003322 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003323 paramIndex);
3324 break;
3325 }
3326 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003327 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003328 paramIndex);
3329 break;
3330 }
3331 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003332 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003333 paramIndex);
3334 break;
3335 }
3336 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3337 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3338 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3339 struct v4l2_control control;
3340 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003341 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003342 pictureOrder->eOutputPictureOrder);
3343 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3344 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3345 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3346 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3347 time_stamp_dts.set_timestamp_reorder_mode(false);
3348 } else
3349 eRet = OMX_ErrorBadParameter;
3350 if (eRet == OMX_ErrorNone) {
3351 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3352 control.value = pic_order;
3353 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3354 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003355 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003356 eRet = OMX_ErrorUnsupportedSetting;
3357 }
3358 }
3359 break;
3360 }
3361 case OMX_QcomIndexParamConcealMBMapExtraData:
3362 if (!secure_mode)
3363 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3364 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3365 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003366 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003367 eRet = OMX_ErrorUnsupportedSetting;
3368 }
3369 break;
3370 case OMX_QcomIndexParamFrameInfoExtraData: {
3371 if (!secure_mode)
3372 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3373 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3374 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003375 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003376 eRet = OMX_ErrorUnsupportedSetting;
3377 }
3378 break;
3379 }
3380 case OMX_QcomIndexParamInterlaceExtraData:
3381 if (!secure_mode)
3382 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3383 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3384 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003385 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003386 eRet = OMX_ErrorUnsupportedSetting;
3387 }
3388 break;
3389 case OMX_QcomIndexParamH264TimeInfo:
3390 if (!secure_mode)
3391 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3392 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3393 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003394 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003395 eRet = OMX_ErrorUnsupportedSetting;
3396 }
3397 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303398 case OMX_QcomIndexParamVideoFramePackingExtradata:
3399 if (!secure_mode)
3400 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3401 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3402 else {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003403 DEBUG_PRINT_ERROR("secure mode setting not supported");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303404 eRet = OMX_ErrorUnsupportedSetting;
3405 }
3406 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003407 case OMX_QcomIndexParamVideoQPExtraData: {
3408 if (!secure_mode)
3409 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3410 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3411 else {
3412 DEBUG_PRINT_ERROR("secure mode setting not supported");
3413 eRet = OMX_ErrorUnsupportedSetting;
3414 }
3415 break;
3416 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08003417 case OMX_QcomIndexParamVideoInputBitsInfoExtraData: {
3418 if (!secure_mode)
3419 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3420 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3421 else {
3422 DEBUG_PRINT_ERROR("secure mode setting not supported");
3423 eRet = OMX_ErrorUnsupportedSetting;
3424 }
3425 break;
3426 }
Arun Menon906de572013-06-18 17:01:40 -07003427 case OMX_QcomIndexParamVideoDivx: {
3428 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3429 }
3430 break;
3431 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003432 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003433 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3434 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3435 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3436 eRet = OMX_ErrorUnsupportedSetting;
3437 } else {
3438 m_out_pvt_entry_pmem = OMX_TRUE;
3439 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003440 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003441 m_use_output_pmem = OMX_TRUE;
3442 }
3443 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003444
Arun Menon906de572013-06-18 17:01:40 -07003445 }
3446 break;
3447 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3448 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3449 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3450 struct v4l2_control control;
3451 int rc;
3452 drv_ctx.idr_only_decoding = 1;
3453 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3454 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3455 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3456 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003457 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003458 eRet = OMX_ErrorUnsupportedSetting;
3459 } else {
3460 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3461 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3462 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3463 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003464 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003465 eRet = OMX_ErrorUnsupportedSetting;
3466 }
3467 /*Setting sync frame decoding on driver might change buffer
3468 * requirements so update them here*/
3469 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003470 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003471 eRet = OMX_ErrorUnsupportedSetting;
3472 }
3473 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003474 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003475 eRet = OMX_ErrorUnsupportedSetting;
3476 }
3477 }
3478 }
3479 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003480
Arun Menon906de572013-06-18 17:01:40 -07003481 case OMX_QcomIndexParamIndexExtraDataType: {
3482 if (!secure_mode) {
3483 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3484 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3485 (extradataIndexType->bEnabled == OMX_TRUE) &&
3486 (extradataIndexType->nPortIndex == 1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003487 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
Arun Menon906de572013-06-18 17:01:40 -07003488 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003489
Arun Menon906de572013-06-18 17:01:40 -07003490 }
3491 }
3492 }
3493 break;
3494 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003495#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003496 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003497#else
Arun Menon906de572013-06-18 17:01:40 -07003498 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003499#endif
Arun Menon906de572013-06-18 17:01:40 -07003500 }
3501 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003502#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003503 /* Need to allow following two set_parameters even in Idle
3504 * state. This is ANDROID architecture which is not in sync
3505 * with openmax standard. */
3506 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3507 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3508 if (enableNativeBuffers) {
3509 m_enable_android_native_buffers = enableNativeBuffers->enable;
3510 }
3511 }
3512 break;
3513 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3514 eRet = use_android_native_buffer(hComp, paramData);
3515 }
3516 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003517#endif
Arun Menon906de572013-06-18 17:01:40 -07003518 case OMX_QcomIndexParamEnableTimeStampReorder: {
3519 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3520 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3521 if (reorder->bEnable == OMX_TRUE) {
3522 frm_int =0;
3523 time_stamp_dts.set_timestamp_reorder_mode(true);
3524 } else
3525 time_stamp_dts.set_timestamp_reorder_mode(false);
3526 } else {
3527 time_stamp_dts.set_timestamp_reorder_mode(false);
3528 if (reorder->bEnable == OMX_TRUE) {
3529 eRet = OMX_ErrorUnsupportedSetting;
3530 }
3531 }
3532 }
3533 break;
3534 case OMX_IndexParamVideoProfileLevelCurrent: {
3535 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3536 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3537 if (pParam) {
3538 m_profile_lvl.eProfile = pParam->eProfile;
3539 m_profile_lvl.eLevel = pParam->eLevel;
3540 }
3541 break;
Arun Menon888aa852013-05-30 11:24:42 -07003542
Arun Menon906de572013-06-18 17:01:40 -07003543 }
Arun Menone5652482013-08-04 13:33:05 -07003544 case OMX_QcomIndexParamVideoMetaBufferMode:
3545 {
3546 StoreMetaDataInBuffersParams *metabuffer =
3547 (StoreMetaDataInBuffersParams *)paramData;
3548 if (!metabuffer) {
3549 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3550 eRet = OMX_ErrorBadParameter;
3551 break;
3552 }
3553 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3554 //set property dynamic buffer mode to driver.
3555 struct v4l2_control control;
3556 struct v4l2_format fmt;
3557 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3558 if (metabuffer->bStoreMetaData == true) {
3559 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3560 } else {
3561 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3562 }
3563 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3564 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003565 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003566 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003567 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003568 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003569 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003570 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3571 eRet = OMX_ErrorUnsupportedSetting;
3572 }
3573 } else {
3574 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003575 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003576 metabuffer->nPortIndex);
3577 eRet = OMX_ErrorUnsupportedSetting;
3578 }
3579 break;
3580 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003581 case OMX_QcomIndexParamVideoDownScalar: {
3582 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3583 struct v4l2_control control;
3584 int rc;
3585 if (pParam) {
3586 is_down_scalar_enabled = pParam->bEnable;
3587 if (is_down_scalar_enabled) {
3588 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3589 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3590 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3591 pParam->bEnable);
3592 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3593 if (rc < 0) {
3594 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3595 eRet = OMX_ErrorUnsupportedSetting;
3596 }
3597 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3598 control.value = 1;
3599 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3600 if (rc < 0) {
3601 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3602 eRet = OMX_ErrorUnsupportedSetting;
3603 }
3604 }
3605 }
3606 break;
3607 }
Praveen Chavancf924182013-12-06 23:16:23 -08003608#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3609 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3610 {
3611 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3612 PrepareForAdaptivePlaybackParams* pParams =
3613 (PrepareForAdaptivePlaybackParams *) paramData;
3614 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3615 if (!pParams->bEnable) {
3616 return OMX_ErrorNone;
3617 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303618 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3619 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003620 DEBUG_PRINT_ERROR(
3621 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3622 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303623 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003624 eRet = OMX_ErrorBadParameter;
3625 } else {
3626 eRet = enable_smoothstreaming();
3627 if (eRet != OMX_ErrorNone) {
3628 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3629 eRet = OMX_ErrorHardware;
3630 } else {
3631 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3632 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3633 m_smoothstreaming_mode = true;
3634 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3635 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3636 }
Deepak Vermaf8771292014-02-03 12:22:50 +05303637 struct v4l2_format fmt;
3638 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
3639 m_smoothstreaming_width, m_smoothstreaming_height);
3640 eRet = is_video_session_supported();
3641 if (eRet)
3642 break;
3643 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3644 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3645 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3646 fmt.fmt.pix_mp.pixelformat = output_capability;
3647 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
3648 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
3649 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3650 if (ret) {
3651 DEBUG_PRINT_ERROR("Set Resolution failed");
3652 eRet = OMX_ErrorUnsupportedSetting;
3653 } else
3654 eRet = get_buffer_req(&drv_ctx.op_buf);
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303655 }
Praveen Chavancf924182013-12-06 23:16:23 -08003656 } else {
3657 DEBUG_PRINT_ERROR(
3658 "Prepare for adaptive playback supported only on output port");
3659 eRet = OMX_ErrorBadParameter;
3660 }
3661 break;
3662 }
3663
3664#endif
Arun Menon906de572013-06-18 17:01:40 -07003665 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003666 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003667 eRet = OMX_ErrorUnsupportedIndex;
3668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003669 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003670 if (eRet != OMX_ErrorNone)
3671 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003672 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003673}
3674
3675/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003676 FUNCTION
3677 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003678
Arun Menon906de572013-06-18 17:01:40 -07003679 DESCRIPTION
3680 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003681
Arun Menon906de572013-06-18 17:01:40 -07003682 PARAMETERS
3683 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003684
Arun Menon906de572013-06-18 17:01:40 -07003685 RETURN VALUE
3686 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003687
Arun Menon906de572013-06-18 17:01:40 -07003688 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003689OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003690 OMX_IN OMX_INDEXTYPE configIndex,
3691 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003692{
Arun Menon906de572013-06-18 17:01:40 -07003693 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003694
Arun Menon906de572013-06-18 17:01:40 -07003695 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003696 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003697 return OMX_ErrorInvalidState;
3698 }
Arun Menon906de572013-06-18 17:01:40 -07003699
3700 switch ((unsigned long)configIndex) {
3701 case OMX_QcomIndexConfigInterlaced: {
3702 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3703 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3704 if (configFmt->nPortIndex == 1) {
3705 if (configFmt->nIndex == 0) {
3706 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3707 } else if (configFmt->nIndex == 1) {
3708 configFmt->eInterlaceType =
3709 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3710 } else if (configFmt->nIndex == 2) {
3711 configFmt->eInterlaceType =
3712 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3713 } else {
3714 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003715 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003716 eRet = OMX_ErrorNoMore;
3717 }
3718
3719 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003720 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003721 (int)configFmt->nPortIndex);
3722 eRet = OMX_ErrorBadPortIndex;
3723 }
3724 break;
3725 }
3726 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3727 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3728 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3729 decoderinstances->nNumOfInstances = 16;
3730 /*TODO: How to handle this case */
3731 break;
3732 }
3733 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3734 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3735 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3736 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303737 memcpy(configFmt, &m_frame_pack_arrangement,
3738 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003739 } else {
3740 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3741 }
3742 break;
3743 }
3744 case OMX_IndexConfigCommonOutputCrop: {
3745 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3746 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3747 break;
3748 }
3749 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003750 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003751 eRet = OMX_ErrorBadParameter;
3752 }
3753
Shalaj Jain273b3e02012-06-22 19:08:03 -07003754 }
Arun Menon906de572013-06-18 17:01:40 -07003755
3756 return eRet;
3757}
3758
3759/* ======================================================================
3760 FUNCTION
3761 omx_vdec::SetConfig
3762
3763 DESCRIPTION
3764 OMX Set Config method implementation
3765
3766 PARAMETERS
3767 <TBD>.
3768
3769 RETURN VALUE
3770 OMX Error None if successful.
3771 ========================================================================== */
3772OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3773 OMX_IN OMX_INDEXTYPE configIndex,
3774 OMX_IN OMX_PTR configData)
3775{
3776 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003777 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003778 return OMX_ErrorInvalidState;
3779 }
3780
3781 OMX_ERRORTYPE ret = OMX_ErrorNone;
3782 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3783
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003784 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003785
3786 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3787 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003788 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003789 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003790 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003791 OMX_U32 extra_size;
3792 // Parsing done here for the AVC atom is definitely not generic
3793 // Currently this piece of code is working, but certainly
3794 // not tested with all .mp4 files.
3795 // Incase of failure, we might need to revisit this
3796 // for a generic piece of code.
3797
3798 // Retrieve size of NAL length field
3799 // byte #4 contains the size of NAL lenght field
3800 nal_length = (config->pData[4] & 0x03) + 1;
3801
3802 extra_size = 0;
3803 if (nal_length > 2) {
3804 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3805 extra_size = (nal_length - 2) * 2;
3806 }
3807
3808 // SPS starts from byte #6
3809 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3810 OMX_U8 *pDestBuf;
3811 m_vendor_config.nPortIndex = config->nPortIndex;
3812
3813 // minus 6 --> SPS starts from byte #6
3814 // minus 1 --> picture param set byte to be ignored from avcatom
3815 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3816 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3817 OMX_U32 len;
3818 OMX_U8 index = 0;
3819 // case where SPS+PPS is sent as part of set_config
3820 pDestBuf = m_vendor_config.pData;
3821
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003822 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003823 m_vendor_config.nPortIndex,
3824 m_vendor_config.nDataSize,
3825 m_vendor_config.pData);
3826 while (index < 2) {
3827 uint8 *psize;
3828 len = *pSrcBuf;
3829 len = len << 8;
3830 len |= *(pSrcBuf + 1);
3831 psize = (uint8 *) & len;
3832 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3833 for (unsigned int i = 0; i < nal_length; i++) {
3834 pDestBuf[i] = psize[nal_length - 1 - i];
3835 }
3836 //memcpy(pDestBuf,pSrcBuf,(len+2));
3837 pDestBuf += len + nal_length;
3838 pSrcBuf += len + 2;
3839 index++;
3840 pSrcBuf++; // skip picture param set
3841 len = 0;
3842 }
3843 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3844 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3845 m_vendor_config.nPortIndex = config->nPortIndex;
3846 m_vendor_config.nDataSize = config->nDataSize;
3847 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3848 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3849 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3850 if (m_vendor_config.pData) {
3851 free(m_vendor_config.pData);
3852 m_vendor_config.pData = NULL;
3853 m_vendor_config.nDataSize = 0;
3854 }
3855
3856 if (((*((OMX_U32 *) config->pData)) &
3857 VC1_SP_MP_START_CODE_MASK) ==
3858 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003859 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003860 m_vendor_config.nPortIndex = config->nPortIndex;
3861 m_vendor_config.nDataSize = config->nDataSize;
3862 m_vendor_config.pData =
3863 (OMX_U8 *) malloc(config->nDataSize);
3864 memcpy(m_vendor_config.pData, config->pData,
3865 config->nDataSize);
3866 m_vc1_profile = VC1_SP_MP_RCV;
3867 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003868 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003869 m_vendor_config.nPortIndex = config->nPortIndex;
3870 m_vendor_config.nDataSize = config->nDataSize;
3871 m_vendor_config.pData =
3872 (OMX_U8 *) malloc((config->nDataSize));
3873 memcpy(m_vendor_config.pData, config->pData,
3874 config->nDataSize);
3875 m_vc1_profile = VC1_AP;
3876 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003877 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003878 m_vendor_config.nPortIndex = config->nPortIndex;
3879 m_vendor_config.nDataSize = config->nDataSize;
3880 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3881 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3882 m_vc1_profile = VC1_SP_MP_RCV;
3883 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003884 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003885 }
3886 }
3887 return ret;
3888 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3889 struct v4l2_control temp;
3890 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3891
3892 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3893 switch (pNal->nNaluBytes) {
3894 case 0:
3895 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3896 break;
3897 case 2:
3898 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3899 break;
3900 case 4:
3901 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3902 break;
3903 default:
3904 return OMX_ErrorUnsupportedSetting;
3905 }
3906
3907 if (!arbitrary_bytes) {
3908 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3909 * with start code, so only need to notify driver in frame by frame mode */
3910 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3911 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3912 return OMX_ErrorHardware;
3913 }
3914 }
3915
3916 nal_length = pNal->nNaluBytes;
3917 m_frame_parser.init_nal_length(nal_length);
3918
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003919 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003920 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303921 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003922 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303923 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003924
3925 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3926 if (config->bEnabled) {
3927 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303928 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003929 config->nFps >> 16);
3930 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3931 drv_ctx.frame_rate.fps_denominator);
3932
3933 if (!drv_ctx.frame_rate.fps_numerator) {
3934 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3935 drv_ctx.frame_rate.fps_numerator = 30;
3936 }
3937
3938 if (drv_ctx.frame_rate.fps_denominator) {
3939 drv_ctx.frame_rate.fps_numerator = (int)
3940 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3941 }
3942
3943 drv_ctx.frame_rate.fps_denominator = 1;
3944 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3945 drv_ctx.frame_rate.fps_numerator;
3946
3947 struct v4l2_outputparm oparm;
3948 /*XXX: we're providing timing info as seconds per frame rather than frames
3949 * per second.*/
3950 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3951 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3952
3953 struct v4l2_streamparm sparm;
3954 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3955 sparm.parm.output = oparm;
3956 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3957 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3958 performance might be affected");
3959 ret = OMX_ErrorHardware;
3960 }
3961 client_set_fps = true;
3962 } else {
3963 DEBUG_PRINT_ERROR("Frame rate not supported.");
3964 ret = OMX_ErrorUnsupportedSetting;
3965 }
3966 } else {
3967 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3968 client_set_fps = false;
3969 }
3970 } else {
3971 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3972 (int)config->nPortIndex);
3973 ret = OMX_ErrorBadPortIndex;
3974 }
3975
3976 return ret;
3977 }
3978
3979 return OMX_ErrorNotImplemented;
3980}
3981
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303982#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3983
Arun Menon906de572013-06-18 17:01:40 -07003984/* ======================================================================
3985 FUNCTION
3986 omx_vdec::GetExtensionIndex
3987
3988 DESCRIPTION
3989 OMX GetExtensionIndex method implementaion. <TBD>
3990
3991 PARAMETERS
3992 <TBD>.
3993
3994 RETURN VALUE
3995 OMX Error None if everything successful.
3996
3997 ========================================================================== */
3998OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3999 OMX_IN OMX_STRING paramName,
4000 OMX_OUT OMX_INDEXTYPE* indexType)
4001{
4002 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004003 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004004 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304005 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004006 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304007 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004008 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304009 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4010 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4011 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4012 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004013 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4014 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004015 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4016 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004017 }
4018#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304019 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004020 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304021 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004022 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304023 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004024 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004025 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304026 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004027 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4028 }
4029#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304030 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004031 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4032 }
Praveen Chavancf924182013-12-06 23:16:23 -08004033#if ADAPTIVE_PLAYBACK_SUPPORTED
4034 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4035 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4036 }
4037#endif
Arun Menon906de572013-06-18 17:01:40 -07004038 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004039 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004040 return OMX_ErrorNotImplemented;
4041 }
4042 return OMX_ErrorNone;
4043}
4044
4045/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004046 FUNCTION
4047 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004048
Arun Menon906de572013-06-18 17:01:40 -07004049 DESCRIPTION
4050 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004051
Arun Menon906de572013-06-18 17:01:40 -07004052 PARAMETERS
4053 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004054
Arun Menon906de572013-06-18 17:01:40 -07004055 RETURN VALUE
4056 Error None if everything is successful.
4057 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004058OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004059 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004060{
Arun Menon906de572013-06-18 17:01:40 -07004061 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004062 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004063 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004064}
4065
4066/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004067 FUNCTION
4068 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004069
Arun Menon906de572013-06-18 17:01:40 -07004070 DESCRIPTION
4071 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004072
Arun Menon906de572013-06-18 17:01:40 -07004073 PARAMETERS
4074 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004075
Arun Menon906de572013-06-18 17:01:40 -07004076 RETURN VALUE
4077 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004078
Arun Menon906de572013-06-18 17:01:40 -07004079 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004080OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004081 OMX_IN OMX_U32 port,
4082 OMX_IN OMX_HANDLETYPE peerComponent,
4083 OMX_IN OMX_U32 peerPort,
4084 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004085{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004086 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004087 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004088}
4089
4090/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004091 FUNCTION
4092 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004093
Arun Menon906de572013-06-18 17:01:40 -07004094 DESCRIPTION
4095 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004096
Arun Menon906de572013-06-18 17:01:40 -07004097 PARAMETERS
4098 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004099
Arun Menon906de572013-06-18 17:01:40 -07004100 RETURN VALUE
4101 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004102
Arun Menon906de572013-06-18 17:01:40 -07004103 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004104OMX_ERRORTYPE omx_vdec::allocate_extradata()
4105{
4106#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004107 if (drv_ctx.extradata_info.buffer_size) {
4108 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4109 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4110 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4111 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004112 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004113 }
4114 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4115 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4116 drv_ctx.extradata_info.size, 4096,
4117 &drv_ctx.extradata_info.ion.ion_alloc_data,
4118 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4119 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004120 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004121 return OMX_ErrorInsufficientResources;
4122 }
4123 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4124 drv_ctx.extradata_info.size,
4125 PROT_READ|PROT_WRITE, MAP_SHARED,
4126 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4127 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004128 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004129 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4130 free_ion_memory(&drv_ctx.extradata_info.ion);
4131 return OMX_ErrorInsufficientResources;
4132 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004133 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004134#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304135 if (!m_other_extradata) {
4136 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4137 if (!m_other_extradata) {
4138 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4139 return OMX_ErrorInsufficientResources;
4140 }
4141 }
Arun Menon906de572013-06-18 17:01:40 -07004142 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004143}
4144
Arun Menon906de572013-06-18 17:01:40 -07004145void omx_vdec::free_extradata()
4146{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004147#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004148 if (drv_ctx.extradata_info.uaddr) {
4149 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4150 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4151 free_ion_memory(&drv_ctx.extradata_info.ion);
4152 }
4153 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004154#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304155 if (m_other_extradata) {
4156 free(m_other_extradata);
4157 m_other_extradata = NULL;
4158 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004159}
4160
Shalaj Jain273b3e02012-06-22 19:08:03 -07004161OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004162 OMX_IN OMX_HANDLETYPE hComp,
4163 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4164 OMX_IN OMX_U32 port,
4165 OMX_IN OMX_PTR appData,
4166 OMX_IN OMX_U32 bytes,
4167 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004168{
Arun Menon906de572013-06-18 17:01:40 -07004169 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4170 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4171 unsigned i= 0; // Temporary counter
4172 struct vdec_setbuffer_cmd setbuffers;
4173 OMX_PTR privateAppData = NULL;
4174 private_handle_t *handle = NULL;
4175 OMX_U8 *buff = buffer;
4176 struct v4l2_buffer buf;
4177 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4178 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004179
Arun Menon906de572013-06-18 17:01:40 -07004180 if (!m_out_mem_ptr) {
4181 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4182 eRet = allocate_output_headers();
4183 if (eRet == OMX_ErrorNone)
4184 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004185 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004186
Arun Menon906de572013-06-18 17:01:40 -07004187 if (eRet == OMX_ErrorNone) {
4188 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4189 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4190 break;
4191 }
4192 }
4193 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004194
Arun Menon906de572013-06-18 17:01:40 -07004195 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004196 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004197 eRet = OMX_ErrorInsufficientResources;
4198 }
4199
Arun Menonbdb80b02013-08-12 17:45:54 -07004200 if (dynamic_buf_mode) {
4201 *bufferHdr = (m_out_mem_ptr + i );
4202 (*bufferHdr)->pBuffer = NULL;
4203 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4204 enum v4l2_buf_type buf_type;
4205 int rr = 0;
4206 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4207 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4208 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4209 return OMX_ErrorInsufficientResources;
4210 } else {
4211 streaming[CAPTURE_PORT] = true;
4212 DEBUG_PRINT_LOW("STREAMON Successful");
4213 }
4214 }
4215 BITMASK_SET(&m_out_bm_count,i);
4216 (*bufferHdr)->pAppPrivate = appData;
4217 (*bufferHdr)->pBuffer = buffer;
4218 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4219 return eRet;
4220 }
Arun Menon906de572013-06-18 17:01:40 -07004221 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004222#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004223 if (m_enable_android_native_buffers) {
4224 if (m_use_android_native_buffers) {
4225 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4226 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4227 handle = (private_handle_t *)nBuf->handle;
4228 privateAppData = params->pAppPrivate;
4229 } else {
4230 handle = (private_handle_t *)buff;
4231 privateAppData = appData;
4232 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004233
Arun Menon906de572013-06-18 17:01:40 -07004234 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4235 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4236 " expected %u, got %lu",
4237 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4238 return OMX_ErrorBadParameter;
4239 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004240
Arun Menon906de572013-06-18 17:01:40 -07004241 if (!m_use_android_native_buffers) {
4242 if (!secure_mode) {
4243 buff = (OMX_U8*)mmap(0, handle->size,
4244 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4245 if (buff == MAP_FAILED) {
4246 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4247 return OMX_ErrorInsufficientResources;
4248 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004249 }
4250 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004251#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004252 native_buffer[i].nativehandle = handle;
4253 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004254#endif
Arun Menon906de572013-06-18 17:01:40 -07004255 if (!handle) {
4256 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4257 return OMX_ErrorBadParameter;
4258 }
4259 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4260 drv_ctx.ptr_outputbuffer[i].offset = 0;
4261 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4262 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4263 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4264 } else
4265#endif
4266
4267 if (!ouput_egl_buffers && !m_use_output_pmem) {
4268#ifdef USE_ION
4269 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4270 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4271 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4272 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4273 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004274 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 -07004275 return OMX_ErrorInsufficientResources;
4276 }
4277 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4278 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4279#else
4280 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4281 open (MEM_DEVICE,O_RDWR);
4282
4283 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004284 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004285 return OMX_ErrorInsufficientResources;
4286 }
4287
4288 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4289 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4290 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4291 open (MEM_DEVICE,O_RDWR);
4292 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004293 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004294 return OMX_ErrorInsufficientResources;
4295 }
4296 }
4297
4298 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4299 drv_ctx.op_buf.buffer_size,
4300 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004301 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004302 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4303 return OMX_ErrorInsufficientResources;
4304 }
4305#endif
4306 if (!secure_mode) {
4307 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4308 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4309 PROT_READ|PROT_WRITE, MAP_SHARED,
4310 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4311 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4312 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4313#ifdef USE_ION
4314 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4315#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004316 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004317 return OMX_ErrorInsufficientResources;
4318 }
4319 }
4320 drv_ctx.ptr_outputbuffer[i].offset = 0;
4321 privateAppData = appData;
4322 } else {
4323
4324 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4325 if (!appData || !bytes ) {
4326 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004327 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004328 return OMX_ErrorBadParameter;
4329 }
4330 }
4331
4332 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4333 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4334 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4335 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4336 !pmem_list->nEntries ||
4337 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004338 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004339 return OMX_ErrorBadParameter;
4340 }
4341 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4342 pmem_list->entryList->entry;
4343 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4344 pmem_info->pmem_fd);
4345 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4346 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4347 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4348 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4349 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4350 privateAppData = appData;
4351 }
4352 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4353 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304354 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4355 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4356 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004357
4358 *bufferHdr = (m_out_mem_ptr + i );
4359 if (secure_mode)
4360 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4361 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4362 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4363 sizeof (vdec_bufferpayload));
4364
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004365 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004366 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4367 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4368
4369 buf.index = i;
4370 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4371 buf.memory = V4L2_MEMORY_USERPTR;
4372 plane[0].length = drv_ctx.op_buf.buffer_size;
4373 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4374 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4375 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4376 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4377 plane[0].data_offset = 0;
4378 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4379 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4380 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4381 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4382#ifdef USE_ION
4383 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4384#endif
4385 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4386 plane[extra_idx].data_offset = 0;
4387 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004388 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004389 return OMX_ErrorBadParameter;
4390 }
Arun Menon906de572013-06-18 17:01:40 -07004391 buf.m.planes = plane;
4392 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004393
Arun Menon906de572013-06-18 17:01:40 -07004394 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004395 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004396 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004397 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004398 }
4399
Arun Menon906de572013-06-18 17:01:40 -07004400 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4401 enum v4l2_buf_type buf_type;
4402 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4403 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4404 return OMX_ErrorInsufficientResources;
4405 } else {
4406 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004407 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408 }
4409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004410
Arun Menon906de572013-06-18 17:01:40 -07004411 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4412 if (m_enable_android_native_buffers) {
4413 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4414 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4415 } else {
4416 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004417 }
Arun Menon906de572013-06-18 17:01:40 -07004418 (*bufferHdr)->pAppPrivate = privateAppData;
4419 BITMASK_SET(&m_out_bm_count,i);
4420 }
4421 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004422}
4423
4424/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004425 FUNCTION
4426 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004427
Arun Menon906de572013-06-18 17:01:40 -07004428 DESCRIPTION
4429 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004430
Arun Menon906de572013-06-18 17:01:40 -07004431 PARAMETERS
4432 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004433
Arun Menon906de572013-06-18 17:01:40 -07004434 RETURN VALUE
4435 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004436
Arun Menon906de572013-06-18 17:01:40 -07004437 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004439 OMX_IN OMX_HANDLETYPE hComp,
4440 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4441 OMX_IN OMX_U32 port,
4442 OMX_IN OMX_PTR appData,
4443 OMX_IN OMX_U32 bytes,
4444 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004445{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004446 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004447 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4448 if (!m_inp_heap_ptr)
4449 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4450 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4451 drv_ctx.ip_buf.actualcount);
4452 if (!m_phdr_pmem_ptr)
4453 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4454 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4455 drv_ctx.ip_buf.actualcount);
4456 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4457 DEBUG_PRINT_ERROR("Insufficent memory");
4458 eRet = OMX_ErrorInsufficientResources;
4459 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4460 input_use_buffer = true;
4461 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4462 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4463 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4464 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4465 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4466 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4467 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4468 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004469 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 -07004470 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4471 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004472 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004473 return OMX_ErrorInsufficientResources;
4474 }
4475 m_in_alloc_cnt++;
4476 } else {
4477 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4478 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004479 }
Arun Menon906de572013-06-18 17:01:40 -07004480 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004481}
4482
4483/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004484 FUNCTION
4485 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004486
Arun Menon906de572013-06-18 17:01:40 -07004487 DESCRIPTION
4488 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004489
Arun Menon906de572013-06-18 17:01:40 -07004490 PARAMETERS
4491 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004492
Arun Menon906de572013-06-18 17:01:40 -07004493 RETURN VALUE
4494 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004495
Arun Menon906de572013-06-18 17:01:40 -07004496 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004497OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004498 OMX_IN OMX_HANDLETYPE hComp,
4499 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4500 OMX_IN OMX_U32 port,
4501 OMX_IN OMX_PTR appData,
4502 OMX_IN OMX_U32 bytes,
4503 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004504{
Arun Menon906de572013-06-18 17:01:40 -07004505 OMX_ERRORTYPE error = OMX_ErrorNone;
4506 struct vdec_setbuffer_cmd setbuffers;
4507
4508 if (bufferHdr == NULL || bytes == 0) {
4509 if (!secure_mode && buffer == NULL) {
4510 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4511 return OMX_ErrorBadParameter;
4512 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004513 }
Arun Menon906de572013-06-18 17:01:40 -07004514 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004515 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004516 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004517 }
Arun Menon906de572013-06-18 17:01:40 -07004518 if (port == OMX_CORE_INPUT_PORT_INDEX)
4519 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4520 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4521 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4522 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004523 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004524 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004525 }
Arun Menon906de572013-06-18 17:01:40 -07004526 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4527 if (error == OMX_ErrorNone) {
4528 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4529 // Send the callback now
4530 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4531 post_event(OMX_CommandStateSet,OMX_StateIdle,
4532 OMX_COMPONENT_GENERATE_EVENT);
4533 }
4534 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4535 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4536 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4537 post_event(OMX_CommandPortEnable,
4538 OMX_CORE_INPUT_PORT_INDEX,
4539 OMX_COMPONENT_GENERATE_EVENT);
4540 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4541 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4542 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4543 post_event(OMX_CommandPortEnable,
4544 OMX_CORE_OUTPUT_PORT_INDEX,
4545 OMX_COMPONENT_GENERATE_EVENT);
4546 }
4547 }
4548 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549}
4550
4551OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004552 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004553{
Arun Menon906de572013-06-18 17:01:40 -07004554 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4555 if (m_inp_heap_ptr[bufferindex].pBuffer)
4556 free(m_inp_heap_ptr[bufferindex].pBuffer);
4557 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4558 }
4559 if (pmem_bufferHdr)
4560 free_input_buffer(pmem_bufferHdr);
4561 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004562}
4563
4564OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4565{
Arun Menon906de572013-06-18 17:01:40 -07004566 unsigned int index = 0;
4567 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4568 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570
Arun Menon906de572013-06-18 17:01:40 -07004571 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004572 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004573
4574 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004575 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004576 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4577 struct vdec_setbuffer_cmd setbuffers;
4578 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4579 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4580 sizeof (vdec_bufferpayload));
4581 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004582 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004583 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004584 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004585 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4586 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4587 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4588 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4589 }
4590 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4591 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4592 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4593 free(m_desc_buffer_ptr[index].buf_addr);
4594 m_desc_buffer_ptr[index].buf_addr = NULL;
4595 m_desc_buffer_ptr[index].desc_data_size = 0;
4596 }
4597#ifdef USE_ION
4598 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4599#endif
4600 }
4601 }
4602
4603 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604}
4605
4606OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4607{
Arun Menon906de572013-06-18 17:01:40 -07004608 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004609
Arun Menon906de572013-06-18 17:01:40 -07004610 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4611 return OMX_ErrorBadParameter;
4612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004613
Arun Menon906de572013-06-18 17:01:40 -07004614 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004615 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004616
Arun Menon906de572013-06-18 17:01:40 -07004617 if (index < drv_ctx.op_buf.actualcount
4618 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004619 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004620 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004621
Arun Menon906de572013-06-18 17:01:40 -07004622 struct vdec_setbuffer_cmd setbuffers;
4623 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4624 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4625 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004626
4627 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004628#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004629 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004630 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004631 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4632 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4633 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4634 }
Arun Menon906de572013-06-18 17:01:40 -07004635 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004636 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4637 } else {
4638#endif
4639 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4640 if (!secure_mode) {
4641 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4642 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4643 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4644 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4645 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4646 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4647 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4648 }
4649 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4650 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004651#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004652 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004653#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004654 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004656 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004657#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004658 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004659 if (release_output_done()) {
4660 free_extradata();
4661 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663
Arun Menon906de572013-06-18 17:01:40 -07004664 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004665
4666}
4667
4668OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004669 OMX_BUFFERHEADERTYPE **bufferHdr,
4670 OMX_U32 port,
4671 OMX_PTR appData,
4672 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004673{
Arun Menon906de572013-06-18 17:01:40 -07004674 OMX_BUFFERHEADERTYPE *input = NULL;
4675 unsigned char *buf_addr = NULL;
4676 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4677 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004678
Arun Menon906de572013-06-18 17:01:40 -07004679 /* Sanity Check*/
4680 if (bufferHdr == NULL) {
4681 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682 }
4683
Arun Menon906de572013-06-18 17:01:40 -07004684 if (m_inp_heap_ptr == NULL) {
4685 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4686 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4687 drv_ctx.ip_buf.actualcount);
4688 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4689 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4690 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004691
Arun Menon906de572013-06-18 17:01:40 -07004692 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004693 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004694 return OMX_ErrorInsufficientResources;
4695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004697
Arun Menon906de572013-06-18 17:01:40 -07004698 /*Find a Free index*/
4699 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4700 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004701 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004702 break;
4703 }
4704 }
4705
4706 if (i < drv_ctx.ip_buf.actualcount) {
4707 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4708
4709 if (buf_addr == NULL) {
4710 return OMX_ErrorInsufficientResources;
4711 }
4712
4713 *bufferHdr = (m_inp_heap_ptr + i);
4714 input = *bufferHdr;
4715 BITMASK_SET(&m_heap_inp_bm_count,i);
4716
4717 input->pBuffer = (OMX_U8 *)buf_addr;
4718 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4719 input->nVersion.nVersion = OMX_SPEC_VERSION;
4720 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4721 input->pAppPrivate = appData;
4722 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004723 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004724 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004725 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004726 /*Add the Buffers to freeq*/
4727 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4728 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004729 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004730 return OMX_ErrorInsufficientResources;
4731 }
4732 } else {
4733 return OMX_ErrorBadParameter;
4734 }
4735
4736 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004737
4738}
4739
4740
4741/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004742 FUNCTION
4743 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004744
Arun Menon906de572013-06-18 17:01:40 -07004745 DESCRIPTION
4746 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004747
Arun Menon906de572013-06-18 17:01:40 -07004748 PARAMETERS
4749 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004750
Arun Menon906de572013-06-18 17:01:40 -07004751 RETURN VALUE
4752 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004753
Arun Menon906de572013-06-18 17:01:40 -07004754 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004755OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004756 OMX_IN OMX_HANDLETYPE hComp,
4757 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4758 OMX_IN OMX_U32 port,
4759 OMX_IN OMX_PTR appData,
4760 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004761{
4762
Arun Menon906de572013-06-18 17:01:40 -07004763 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4764 struct vdec_setbuffer_cmd setbuffers;
4765 OMX_BUFFERHEADERTYPE *input = NULL;
4766 unsigned i = 0;
4767 unsigned char *buf_addr = NULL;
4768 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769
Arun Menon906de572013-06-18 17:01:40 -07004770 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004771 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004772 bytes, drv_ctx.ip_buf.buffer_size);
4773 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004774 }
4775
Arun Menon906de572013-06-18 17:01:40 -07004776 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004777 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004778 drv_ctx.ip_buf.actualcount,
4779 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004780
Arun Menon906de572013-06-18 17:01:40 -07004781 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4782 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4783
4784 if (m_inp_mem_ptr == NULL) {
4785 return OMX_ErrorInsufficientResources;
4786 }
4787
4788 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4789 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4790
4791 if (drv_ctx.ptr_inputbuffer == NULL) {
4792 return OMX_ErrorInsufficientResources;
4793 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004794#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004795 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4796 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004797
Arun Menon906de572013-06-18 17:01:40 -07004798 if (drv_ctx.ip_buf_ion_info == NULL) {
4799 return OMX_ErrorInsufficientResources;
4800 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004801#endif
4802
Arun Menon906de572013-06-18 17:01:40 -07004803 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4804 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004805#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004806 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004807#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004808 }
4809 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004810
Arun Menon906de572013-06-18 17:01:40 -07004811 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4812 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004813 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004814 break;
4815 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004816 }
Arun Menon906de572013-06-18 17:01:40 -07004817
4818 if (i < drv_ctx.ip_buf.actualcount) {
4819 struct v4l2_buffer buf;
4820 struct v4l2_plane plane;
4821 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004822 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004823#ifdef USE_ION
4824 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4825 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4826 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4827 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4828 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4829 return OMX_ErrorInsufficientResources;
4830 }
4831 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4832#else
4833 pmem_fd = open (MEM_DEVICE,O_RDWR);
4834
4835 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004836 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004837 return OMX_ErrorInsufficientResources;
4838 }
4839
4840 if (pmem_fd == 0) {
4841 pmem_fd = open (MEM_DEVICE,O_RDWR);
4842
4843 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004844 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004845 return OMX_ErrorInsufficientResources;
4846 }
4847 }
4848
4849 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4850 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004851 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004852 close(pmem_fd);
4853 return OMX_ErrorInsufficientResources;
4854 }
4855#endif
4856 if (!secure_mode) {
4857 buf_addr = (unsigned char *)mmap(NULL,
4858 drv_ctx.ip_buf.buffer_size,
4859 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4860
4861 if (buf_addr == MAP_FAILED) {
4862 close(pmem_fd);
4863#ifdef USE_ION
4864 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4865#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004866 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004867 return OMX_ErrorInsufficientResources;
4868 }
4869 }
4870 *bufferHdr = (m_inp_mem_ptr + i);
4871 if (secure_mode)
4872 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4873 else
4874 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4875 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4876 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4877 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4878 drv_ctx.ptr_inputbuffer [i].offset = 0;
4879
4880
4881 buf.index = i;
4882 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4883 buf.memory = V4L2_MEMORY_USERPTR;
4884 plane.bytesused = 0;
4885 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4886 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4887 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4888 plane.reserved[1] = 0;
4889 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4890 buf.m.planes = &plane;
4891 buf.length = 1;
4892
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004893 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004894 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4895
4896 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4897
4898 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004899 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004900 /*TODO: How to handle this case */
4901 return OMX_ErrorInsufficientResources;
4902 }
4903
4904 input = *bufferHdr;
4905 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004906 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004907 if (secure_mode)
4908 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4909 else
4910 input->pBuffer = (OMX_U8 *)buf_addr;
4911 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4912 input->nVersion.nVersion = OMX_SPEC_VERSION;
4913 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4914 input->pAppPrivate = appData;
4915 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4916 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4917
4918 if (drv_ctx.disable_dmx) {
4919 eRet = allocate_desc_buffer(i);
4920 }
4921 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004922 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004923 eRet = OMX_ErrorInsufficientResources;
4924 }
4925 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004926}
4927
4928
4929/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004930 FUNCTION
4931 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004932
Arun Menon906de572013-06-18 17:01:40 -07004933 DESCRIPTION
4934 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004935
Arun Menon906de572013-06-18 17:01:40 -07004936 PARAMETERS
4937 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004938
Arun Menon906de572013-06-18 17:01:40 -07004939 RETURN VALUE
4940 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004941
Arun Menon906de572013-06-18 17:01:40 -07004942 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004943OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004944 OMX_IN OMX_HANDLETYPE hComp,
4945 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4946 OMX_IN OMX_U32 port,
4947 OMX_IN OMX_PTR appData,
4948 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004949{
Arun Menon906de572013-06-18 17:01:40 -07004950 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4951 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4952 unsigned i= 0; // Temporary counter
4953 struct vdec_setbuffer_cmd setbuffers;
4954 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004955#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004956 int ion_device_fd =-1;
4957 struct ion_allocation_data ion_alloc_data;
4958 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959#endif
Arun Menon906de572013-06-18 17:01:40 -07004960 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004961 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004962 drv_ctx.op_buf.actualcount,
4963 drv_ctx.op_buf.buffer_size);
4964 int nBufHdrSize = 0;
4965 int nPlatformEntrySize = 0;
4966 int nPlatformListSize = 0;
4967 int nPMEMInfoSize = 0;
4968 int pmem_fd = -1;
4969 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004970
Arun Menon906de572013-06-18 17:01:40 -07004971 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4972 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4973 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004974
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004975 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004976 drv_ctx.op_buf.actualcount);
4977 nBufHdrSize = drv_ctx.op_buf.actualcount *
4978 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004979
Arun Menon906de572013-06-18 17:01:40 -07004980 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4981 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4982 nPlatformListSize = drv_ctx.op_buf.actualcount *
4983 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4984 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4985 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004986
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004987 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004988 sizeof(OMX_BUFFERHEADERTYPE),
4989 nPMEMInfoSize,
4990 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004991 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004992 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004993#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004994 ion_device_fd = alloc_map_ion_memory(
4995 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4996 drv_ctx.op_buf.alignment,
4997 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4998 if (ion_device_fd < 0) {
4999 return OMX_ErrorInsufficientResources;
5000 }
5001 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005002#else
Arun Menon906de572013-06-18 17:01:40 -07005003 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005004
Arun Menon906de572013-06-18 17:01:40 -07005005 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005006 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005007 drv_ctx.op_buf.buffer_size);
5008 return OMX_ErrorInsufficientResources;
5009 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005010
Arun Menon906de572013-06-18 17:01:40 -07005011 if (pmem_fd == 0) {
5012 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013
Arun Menon906de572013-06-18 17:01:40 -07005014 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005015 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005016 drv_ctx.op_buf.buffer_size);
5017 return OMX_ErrorInsufficientResources;
5018 }
5019 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005020
Arun Menon906de572013-06-18 17:01:40 -07005021 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5022 drv_ctx.op_buf.actualcount,
5023 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005024 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005025 close(pmem_fd);
5026 return OMX_ErrorInsufficientResources;
5027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005028#endif
Arun Menon906de572013-06-18 17:01:40 -07005029 if (!secure_mode) {
5030 pmem_baseaddress = (unsigned char *)mmap(NULL,
5031 (drv_ctx.op_buf.buffer_size *
5032 drv_ctx.op_buf.actualcount),
5033 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5034 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005035 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005036 drv_ctx.op_buf.buffer_size);
5037 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005038#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005039 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005040#endif
Arun Menon906de572013-06-18 17:01:40 -07005041 return OMX_ErrorInsufficientResources;
5042 }
5043 }
5044 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5045 // Alloc mem for platform specific info
5046 char *pPtr=NULL;
5047 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5048 nPMEMInfoSize,1);
5049 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5050 calloc (sizeof(struct vdec_bufferpayload),
5051 drv_ctx.op_buf.actualcount);
5052 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5053 calloc (sizeof (struct vdec_output_frameinfo),
5054 drv_ctx.op_buf.actualcount);
5055#ifdef USE_ION
5056 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5057 calloc (sizeof(struct vdec_ion),
5058 drv_ctx.op_buf.actualcount);
5059#endif
5060
5061 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5062 && drv_ctx.ptr_respbuffer) {
5063 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5064 (drv_ctx.op_buf.buffer_size *
5065 drv_ctx.op_buf.actualcount);
5066 bufHdr = m_out_mem_ptr;
5067 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5068 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5069 (((char *) m_platform_list) + nPlatformListSize);
5070 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5071 (((char *) m_platform_entry) + nPlatformEntrySize);
5072 pPlatformList = m_platform_list;
5073 pPlatformEntry = m_platform_entry;
5074 pPMEMInfo = m_pmem_info;
5075
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005076 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005077
5078 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005079 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5080 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005081 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5082 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5083 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5084 // Set the values when we determine the right HxW param
5085 bufHdr->nAllocLen = bytes;
5086 bufHdr->nFilledLen = 0;
5087 bufHdr->pAppPrivate = appData;
5088 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5089 // Platform specific PMEM Information
5090 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005091 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005092 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5093 pPlatformEntry->entry = pPMEMInfo;
5094 // Initialize the Platform List
5095 pPlatformList->nEntries = 1;
5096 pPlatformList->entryList = pPlatformEntry;
5097 // Keep pBuffer NULL till vdec is opened
5098 bufHdr->pBuffer = NULL;
5099 bufHdr->nOffset = 0;
5100
5101 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5102 pPMEMInfo->pmem_fd = 0;
5103 bufHdr->pPlatformPrivate = pPlatformList;
5104
5105 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5106 m_pmem_info[i].pmem_fd = pmem_fd;
5107#ifdef USE_ION
5108 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5109 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5110 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5111#endif
5112
5113 /*Create a mapping between buffers*/
5114 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5115 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5116 &drv_ctx.ptr_outputbuffer[i];
5117 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5118 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5119 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305120 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5121 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5122 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005123
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005124 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005125 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5126 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5127 // Move the buffer and buffer header pointers
5128 bufHdr++;
5129 pPMEMInfo++;
5130 pPlatformEntry++;
5131 pPlatformList++;
5132 }
5133 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005134 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005135 m_out_mem_ptr, pPtr);
5136 if (m_out_mem_ptr) {
5137 free(m_out_mem_ptr);
5138 m_out_mem_ptr = NULL;
5139 }
5140 if (pPtr) {
5141 free(pPtr);
5142 pPtr = NULL;
5143 }
5144 if (drv_ctx.ptr_outputbuffer) {
5145 free(drv_ctx.ptr_outputbuffer);
5146 drv_ctx.ptr_outputbuffer = NULL;
5147 }
5148 if (drv_ctx.ptr_respbuffer) {
5149 free(drv_ctx.ptr_respbuffer);
5150 drv_ctx.ptr_respbuffer = NULL;
5151 }
5152#ifdef USE_ION
5153 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005154 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005155 free(drv_ctx.op_buf_ion_info);
5156 drv_ctx.op_buf_ion_info = NULL;
5157 }
5158#endif
5159 eRet = OMX_ErrorInsufficientResources;
5160 }
5161 if (eRet == OMX_ErrorNone)
5162 eRet = allocate_extradata();
5163 }
5164
5165 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5166 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005167 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005168 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005169 }
5170 }
Arun Menon906de572013-06-18 17:01:40 -07005171
5172 if (eRet == OMX_ErrorNone) {
5173 if (i < drv_ctx.op_buf.actualcount) {
5174 struct v4l2_buffer buf;
5175 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5176 int rc;
5177 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5178
5179 drv_ctx.ptr_outputbuffer[i].buffer_len =
5180 drv_ctx.op_buf.buffer_size;
5181
5182 *bufferHdr = (m_out_mem_ptr + i );
5183 if (secure_mode) {
5184 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5185 }
5186 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5187
5188 buf.index = i;
5189 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5190 buf.memory = V4L2_MEMORY_USERPTR;
5191 plane[0].length = drv_ctx.op_buf.buffer_size;
5192 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5193 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005194#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005195 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005196#endif
Arun Menon906de572013-06-18 17:01:40 -07005197 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5198 plane[0].data_offset = 0;
5199 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5200 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5201 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5202 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 -07005203#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005204 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005205#endif
Arun Menon906de572013-06-18 17:01:40 -07005206 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5207 plane[extra_idx].data_offset = 0;
5208 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005209 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005210 return OMX_ErrorBadParameter;
5211 }
5212 buf.m.planes = plane;
5213 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005214 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 -07005215 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5216 if (rc) {
5217 /*TODO: How to handle this case */
5218 return OMX_ErrorInsufficientResources;
5219 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005220
Arun Menon906de572013-06-18 17:01:40 -07005221 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5222 enum v4l2_buf_type buf_type;
5223 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5224 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5225 if (rc) {
5226 return OMX_ErrorInsufficientResources;
5227 } else {
5228 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005229 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005230 }
5231 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005232
Arun Menon906de572013-06-18 17:01:40 -07005233 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5234 (*bufferHdr)->pAppPrivate = appData;
5235 BITMASK_SET(&m_out_bm_count,i);
5236 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005237 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005238 eRet = OMX_ErrorInsufficientResources;
5239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005240 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005241
Arun Menon906de572013-06-18 17:01:40 -07005242 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005243}
5244
5245
5246// AllocateBuffer -- API Call
5247/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005248 FUNCTION
5249 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005250
Arun Menon906de572013-06-18 17:01:40 -07005251 DESCRIPTION
5252 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005253
Arun Menon906de572013-06-18 17:01:40 -07005254 PARAMETERS
5255 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005256
Arun Menon906de572013-06-18 17:01:40 -07005257 RETURN VALUE
5258 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005259
Arun Menon906de572013-06-18 17:01:40 -07005260 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005261OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005262 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5263 OMX_IN OMX_U32 port,
5264 OMX_IN OMX_PTR appData,
5265 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005266{
5267 unsigned i = 0;
5268 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5269
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005270 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005271 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005272 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273 return OMX_ErrorInvalidState;
5274 }
5275
Arun Menon906de572013-06-18 17:01:40 -07005276 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5277 if (arbitrary_bytes) {
5278 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5279 } else {
5280 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5281 }
5282 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005283 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5284 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005285 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005286 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005287 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005288 }
5289 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005290 if (eRet == OMX_ErrorNone) {
5291 if (allocate_done()) {
5292 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005293 // Send the callback now
5294 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5295 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005296 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005297 }
5298 }
Arun Menon906de572013-06-18 17:01:40 -07005299 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5300 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5301 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5302 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005303 OMX_CORE_INPUT_PORT_INDEX,
5304 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005305 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005306 }
Arun Menon906de572013-06-18 17:01:40 -07005307 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5308 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5309 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005310 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005311 OMX_CORE_OUTPUT_PORT_INDEX,
5312 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005313 }
5314 }
5315 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005316 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005317 return eRet;
5318}
5319
5320// Free Buffer - API call
5321/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005322 FUNCTION
5323 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324
Arun Menon906de572013-06-18 17:01:40 -07005325 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005326
Arun Menon906de572013-06-18 17:01:40 -07005327 PARAMETERS
5328 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005329
Arun Menon906de572013-06-18 17:01:40 -07005330 RETURN VALUE
5331 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005332
Arun Menon906de572013-06-18 17:01:40 -07005333 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005334OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005335 OMX_IN OMX_U32 port,
5336 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005337{
5338 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5339 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005340 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005341
Arun Menon906de572013-06-18 17:01:40 -07005342 if (m_state == OMX_StateIdle &&
5343 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005344 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005345 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5346 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005347 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005348 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5349 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5350 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5351 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005352 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005353 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005354 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005355 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005356 OMX_ErrorPortUnpopulated,
5357 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005358
5359 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005360 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005361 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005363 OMX_ErrorPortUnpopulated,
5364 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365 }
5366
Arun Menon906de572013-06-18 17:01:40 -07005367 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5368 /*Check if arbitrary bytes*/
5369 if (!arbitrary_bytes && !input_use_buffer)
5370 nPortIndex = buffer - m_inp_mem_ptr;
5371 else
5372 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005373
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005374 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005375 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5376 // Clear the bit associated with it.
5377 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5378 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5379 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005380
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005381 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005382 if (m_phdr_pmem_ptr)
5383 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5384 } else {
5385 if (arbitrary_bytes) {
5386 if (m_phdr_pmem_ptr)
5387 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5388 else
5389 free_input_buffer(nPortIndex,NULL);
5390 } else
5391 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005392 }
Arun Menon906de572013-06-18 17:01:40 -07005393 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305394 if(release_input_done())
5395 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005396 /*Free the Buffer Header*/
5397 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005398 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005399 free_input_buffer_header();
5400 }
5401 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005402 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005403 eRet = OMX_ErrorBadPortIndex;
5404 }
5405
Arun Menon906de572013-06-18 17:01:40 -07005406 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5407 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005408 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5410 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005411 OMX_CORE_INPUT_PORT_INDEX,
5412 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005413 }
Arun Menon906de572013-06-18 17:01:40 -07005414 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005415 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005416 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005417 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005418 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005419 // Clear the bit associated with it.
5420 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5421 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005422 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005423
Surajit Podder12aefac2013-08-06 18:43:32 +05305424 if(release_output_done()) {
5425 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5426 }
Arun Menon906de572013-06-18 17:01:40 -07005427 if (release_output_done()) {
5428 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005429 }
Arun Menon906de572013-06-18 17:01:40 -07005430 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005431 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005432 eRet = OMX_ErrorBadPortIndex;
5433 }
Arun Menon906de572013-06-18 17:01:40 -07005434 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5435 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005436 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005437
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005438 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005439 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005440#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005441 if (m_enable_android_native_buffers) {
5442 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5443 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5444 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005445#endif
5446
Arun Menon906de572013-06-18 17:01:40 -07005447 post_event(OMX_CommandPortDisable,
5448 OMX_CORE_OUTPUT_PORT_INDEX,
5449 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005450 }
Arun Menon906de572013-06-18 17:01:40 -07005451 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452 eRet = OMX_ErrorBadPortIndex;
5453 }
Arun Menon906de572013-06-18 17:01:40 -07005454 if ((eRet == OMX_ErrorNone) &&
5455 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5456 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005457 // Send the callback now
5458 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5459 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005460 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005461 }
5462 }
5463 return eRet;
5464}
5465
5466
5467/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005468 FUNCTION
5469 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470
Arun Menon906de572013-06-18 17:01:40 -07005471 DESCRIPTION
5472 This routine is used to push the encoded video frames to
5473 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474
Arun Menon906de572013-06-18 17:01:40 -07005475 PARAMETERS
5476 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005477
Arun Menon906de572013-06-18 17:01:40 -07005478 RETURN VALUE
5479 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005480
Arun Menon906de572013-06-18 17:01:40 -07005481 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005482OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005483 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005484{
Arun Menon906de572013-06-18 17:01:40 -07005485 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5486 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487
Arun Menon906de572013-06-18 17:01:40 -07005488 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005489 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005490 return OMX_ErrorInvalidState;
5491 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492
Arun Menon906de572013-06-18 17:01:40 -07005493 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005494 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005495 return OMX_ErrorBadParameter;
5496 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497
Arun Menon906de572013-06-18 17:01:40 -07005498 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005499 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005500 return OMX_ErrorIncorrectStateOperation;
5501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005502
Arun Menon906de572013-06-18 17:01:40 -07005503 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005504 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005505 return OMX_ErrorBadPortIndex;
5506 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005507
5508#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005509 if (iDivXDrmDecrypt) {
5510 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5511 if (drmErr != OMX_ErrorNone) {
5512 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005513 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005515 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005517 if (perf_flag) {
5518 if (!latency) {
5519 dec_time.stop();
5520 latency = dec_time.processing_time_us();
5521 dec_time.start();
5522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005524
Arun Menon906de572013-06-18 17:01:40 -07005525 if (arbitrary_bytes) {
5526 nBufferIndex = buffer - m_inp_heap_ptr;
5527 } else {
5528 if (input_use_buffer == true) {
5529 nBufferIndex = buffer - m_inp_heap_ptr;
5530 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5531 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5532 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5533 buffer = &m_inp_mem_ptr[nBufferIndex];
5534 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5535 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5536 } else {
5537 nBufferIndex = buffer - m_inp_mem_ptr;
5538 }
5539 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540
Arun Menon906de572013-06-18 17:01:40 -07005541 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005542 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005543 return OMX_ErrorBadParameter;
5544 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005545
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005546 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5547 codec_config_flag = true;
5548 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5549 }
5550
Arun Menon906de572013-06-18 17:01:40 -07005551 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5552 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5553 if (arbitrary_bytes) {
5554 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005555 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005556 } else {
Arun Menon906de572013-06-18 17:01:40 -07005557 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5558 }
5559 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005560}
5561
5562/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005563 FUNCTION
5564 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005565
Arun Menon906de572013-06-18 17:01:40 -07005566 DESCRIPTION
5567 This routine is used to push the encoded video frames to
5568 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005569
Arun Menon906de572013-06-18 17:01:40 -07005570 PARAMETERS
5571 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005572
Arun Menon906de572013-06-18 17:01:40 -07005573 RETURN VALUE
5574 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005575
Arun Menon906de572013-06-18 17:01:40 -07005576 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005578 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579{
Arun Menon906de572013-06-18 17:01:40 -07005580 int push_cnt = 0,i=0;
5581 unsigned nPortIndex = 0;
5582 OMX_ERRORTYPE ret = OMX_ErrorNone;
5583 struct vdec_input_frameinfo frameinfo;
5584 struct vdec_bufferpayload *temp_buffer;
5585 struct vdec_seqheader seq_header;
5586 bool port_setting_changed = true;
5587 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005588
Arun Menon906de572013-06-18 17:01:40 -07005589 /*Should we generate a Aync error event*/
5590 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005591 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005592 return OMX_ErrorBadParameter;
5593 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005594
Arun Menon906de572013-06-18 17:01:40 -07005595 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005596
Arun Menon906de572013-06-18 17:01:40 -07005597 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005598 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005599 nPortIndex);
5600 return OMX_ErrorBadParameter;
5601 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602
Arun Menon906de572013-06-18 17:01:40 -07005603 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604
Arun Menon906de572013-06-18 17:01:40 -07005605 /* return zero length and not an EOS buffer */
5606 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5607 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005608 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005609 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5610 OMX_COMPONENT_GENERATE_EBD);
5611 return OMX_ErrorNone;
5612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005613
5614
Arun Menon906de572013-06-18 17:01:40 -07005615 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5616 mp4StreamType psBits;
5617 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5618 psBits.numBytes = buffer->nFilledLen;
5619 mp4_headerparser.parseHeader(&psBits);
5620 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5621 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5622 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005623 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005624 buffer->nFilledLen,frame_count);
5625 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005626 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005627 not_coded_vop = false;
5628 buffer->nFilledLen = 0;
5629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630 }
5631 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632
Arun Menon906de572013-06-18 17:01:40 -07005633 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005634
Arun Menon906de572013-06-18 17:01:40 -07005635 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636
Arun Menon906de572013-06-18 17:01:40 -07005637 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005638 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005639 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5640 OMX_COMPONENT_GENERATE_EBD);
5641 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005642 }
5643
Arun Menon906de572013-06-18 17:01:40 -07005644 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005645
Surajit Podderd2644d52013-08-28 17:59:06 +05305646 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005647 return OMX_ErrorBadParameter;
5648 }
5649 /* If its first frame, H264 codec and reject is true, then parse the nal
5650 and get the profile. Based on this, reject the clip playback */
5651 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5652 m_reject_avc_1080p_mp) {
5653 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005654 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005655 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5656 NALU_TYPE_SPS);
5657 m_profile = h264_parser->get_profile();
5658 ret = is_video_session_supported();
5659 if (ret) {
5660 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5661 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5662 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5663 m_state = OMX_StateInvalid;
5664 return OMX_ErrorNone;
5665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005666 }
5667
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005668 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005669 /*for use buffer we need to memcpy the data*/
5670 temp_buffer->buffer_len = buffer->nFilledLen;
5671
5672 if (input_use_buffer) {
5673 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5674 if (arbitrary_bytes) {
5675 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5676 } else {
5677 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5678 buffer->nFilledLen);
5679 }
5680 } else {
5681 return OMX_ErrorBadParameter;
5682 }
5683
5684 }
5685
5686 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5687 frameinfo.client_data = (void *) buffer;
5688 frameinfo.datalen = temp_buffer->buffer_len;
5689 frameinfo.flags = 0;
5690 frameinfo.offset = buffer->nOffset;
5691 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5692 frameinfo.pmem_offset = temp_buffer->offset;
5693 frameinfo.timestamp = buffer->nTimeStamp;
5694 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5695 DEBUG_PRINT_LOW("ETB: dmx enabled");
5696 if (m_demux_entries == 0) {
5697 extract_demux_addr_offsets(buffer);
5698 }
5699
5700 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5701 handle_demux_data(buffer);
5702 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5703 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5704 } else {
5705 frameinfo.desc_addr = NULL;
5706 frameinfo.desc_size = 0;
5707 }
5708 if (!arbitrary_bytes) {
5709 frameinfo.flags |= buffer->nFlags;
5710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711
5712#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005713 if (m_debug_timestamp) {
5714 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005715 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005716 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5717 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005718 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005719 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5720 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005721 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005722#endif
5723
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005724log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005725
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005726if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005727 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5728 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730
Arun Menon906de572013-06-18 17:01:40 -07005731 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005732 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005733 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5734 h264_scratch.nFilledLen = 0;
5735 nal_count = 0;
5736 look_ahead_nal = false;
5737 frame_count = 0;
5738 if (m_frame_parser.mutils)
5739 m_frame_parser.mutils->initialize_frame_checking_environment();
5740 m_frame_parser.flush();
5741 h264_last_au_ts = LLONG_MAX;
5742 h264_last_au_flags = 0;
5743 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5744 m_demux_entries = 0;
5745 }
5746 struct v4l2_buffer buf;
5747 struct v4l2_plane plane;
5748 memset( (void *)&buf, 0, sizeof(buf));
5749 memset( (void *)&plane, 0, sizeof(plane));
5750 int rc;
5751 unsigned long print_count;
5752 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005753 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005754 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005755 }
5756 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5757 buf.index = nPortIndex;
5758 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5759 buf.memory = V4L2_MEMORY_USERPTR;
5760 plane.bytesused = temp_buffer->buffer_len;
5761 plane.length = drv_ctx.ip_buf.buffer_size;
5762 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5763 (unsigned long)temp_buffer->offset;
5764 plane.reserved[0] = temp_buffer->pmem_fd;
5765 plane.reserved[1] = temp_buffer->offset;
5766 plane.data_offset = 0;
5767 buf.m.planes = &plane;
5768 buf.length = 1;
5769 if (frameinfo.timestamp >= LLONG_MAX) {
5770 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5771 }
5772 //assumption is that timestamp is in milliseconds
5773 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5774 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5775 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5776 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005777
Arun Menon906de572013-06-18 17:01:40 -07005778 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5779 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005780 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005781 return OMX_ErrorHardware;
5782 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005783 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5784 codec_config_flag = false;
5785 }
Arun Menon906de572013-06-18 17:01:40 -07005786 if (!streaming[OUTPUT_PORT]) {
5787 enum v4l2_buf_type buf_type;
5788 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005789
Arun Menon906de572013-06-18 17:01:40 -07005790 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005791 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005792 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5793 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005794 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005795 streaming[OUTPUT_PORT] = true;
5796 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005797 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005798 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5799 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5800 OMX_COMPONENT_GENERATE_EBD);
5801 return OMX_ErrorBadParameter;
5802 }
5803 }
5804 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5805 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5806 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807
Arun Menon906de572013-06-18 17:01:40 -07005808 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809}
5810
5811/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005812 FUNCTION
5813 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005814
Arun Menon906de572013-06-18 17:01:40 -07005815 DESCRIPTION
5816 IL client uses this method to release the frame buffer
5817 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818
Arun Menon906de572013-06-18 17:01:40 -07005819 PARAMETERS
5820 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821
Arun Menon906de572013-06-18 17:01:40 -07005822 RETURN VALUE
5823 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005824
Arun Menon906de572013-06-18 17:01:40 -07005825 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005826OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005827 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828{
Arun Menonbdb80b02013-08-12 17:45:54 -07005829 if (dynamic_buf_mode) {
5830 private_handle_t *handle = NULL;
5831 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005832 unsigned int nPortIndex = 0;
5833
5834 if (!buffer || !buffer->pBuffer) {
5835 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5836 return OMX_ErrorBadParameter;
5837 }
5838
5839 //get the buffer type and fd info
5840 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5841 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005842 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5843
5844 if (!handle) {
5845 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5846 return OMX_ErrorBadParameter;
5847 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005848 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5849 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5850 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005851 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005852
5853 //Store private handle from GraphicBuffer
5854 native_buffer[nPortIndex].privatehandle = handle;
5855 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005856 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005857
Arun Menon906de572013-06-18 17:01:40 -07005858 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005859 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005860 return OMX_ErrorInvalidState;
5861 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005862
Arun Menon906de572013-06-18 17:01:40 -07005863 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005864 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005865 return OMX_ErrorIncorrectStateOperation;
5866 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005867
Arun Menon906de572013-06-18 17:01:40 -07005868 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305869 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005870 return OMX_ErrorBadParameter;
5871 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005872
Arun Menon906de572013-06-18 17:01:40 -07005873 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005874 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005875 return OMX_ErrorBadPortIndex;
5876 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005877
Arun Menon906de572013-06-18 17:01:40 -07005878 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5879 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5880 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005881}
5882/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005883 FUNCTION
5884 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005885
Arun Menon906de572013-06-18 17:01:40 -07005886 DESCRIPTION
5887 IL client uses this method to release the frame buffer
5888 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005889
Arun Menon906de572013-06-18 17:01:40 -07005890 PARAMETERS
5891 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005892
Arun Menon906de572013-06-18 17:01:40 -07005893 RETURN VALUE
5894 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005895
Arun Menon906de572013-06-18 17:01:40 -07005896 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005897OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005898 OMX_IN OMX_HANDLETYPE hComp,
5899 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005900{
Arun Menon906de572013-06-18 17:01:40 -07005901 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5902 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5903 unsigned nPortIndex = 0;
5904 struct vdec_fillbuffer_cmd fillbuffer;
5905 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5906 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005907
Arun Menon906de572013-06-18 17:01:40 -07005908 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005909
Arun Menon906de572013-06-18 17:01:40 -07005910 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5911 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005913 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005914 bufferAdd, bufferAdd->pBuffer);
5915 /*Return back the output buffer to client*/
5916 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005917 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005918 buffer->nFilledLen = 0;
5919 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5920 return OMX_ErrorNone;
5921 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005922
5923 if (dynamic_buf_mode) {
5924 //map the buffer handle based on the size set on output port definition.
5925 if (!secure_mode) {
5926 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5927 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5928 PROT_READ|PROT_WRITE, MAP_SHARED,
5929 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5930 }
5931 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5932 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5933 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5934 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5935 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5936 }
5937
Arun Menon906de572013-06-18 17:01:40 -07005938 pending_output_buffers++;
5939 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5940 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5941 if (ptr_respbuffer) {
5942 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5943 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005944
Arun Menon906de572013-06-18 17:01:40 -07005945 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5946 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5947 buffer->nFilledLen = 0;
5948 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5949 pending_output_buffers--;
5950 return OMX_ErrorBadParameter;
5951 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952
Arun Menon906de572013-06-18 17:01:40 -07005953 int rc = 0;
5954 struct v4l2_buffer buf;
5955 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5956 memset( (void *)&buf, 0, sizeof(buf));
5957 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5958 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005959
Arun Menon906de572013-06-18 17:01:40 -07005960 buf.index = nPortIndex;
5961 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5962 buf.memory = V4L2_MEMORY_USERPTR;
5963 plane[0].bytesused = buffer->nFilledLen;
5964 plane[0].length = drv_ctx.op_buf.buffer_size;
5965 plane[0].m.userptr =
5966 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5967 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5968 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5969 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5970 plane[0].data_offset = 0;
5971 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5972 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5973 plane[extra_idx].bytesused = 0;
5974 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5975 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 -07005976#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005977 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005978#endif
Arun Menon906de572013-06-18 17:01:40 -07005979 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5980 plane[extra_idx].data_offset = 0;
5981 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005982 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005983 return OMX_ErrorBadParameter;
5984 }
5985 buf.m.planes = plane;
5986 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005987 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005988 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5989
Arun Menon906de572013-06-18 17:01:40 -07005990 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5991 if (rc) {
5992 /*TODO: How to handle this case */
5993 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5994 }
Arun Menon906de572013-06-18 17:01:40 -07005995return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005996}
5997
5998/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005999 FUNCTION
6000 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006001
Arun Menon906de572013-06-18 17:01:40 -07006002 DESCRIPTION
6003 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006004
Arun Menon906de572013-06-18 17:01:40 -07006005 PARAMETERS
6006 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007
Arun Menon906de572013-06-18 17:01:40 -07006008 RETURN VALUE
6009 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010
Arun Menon906de572013-06-18 17:01:40 -07006011 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006012OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006013 OMX_IN OMX_CALLBACKTYPE* callbacks,
6014 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015{
6016
Arun Menon906de572013-06-18 17:01:40 -07006017 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006018 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006019 m_cb.EventHandler,m_cb.FillBufferDone);
6020 m_app_data = appData;
6021 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006022}
6023
6024/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006025 FUNCTION
6026 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027
Arun Menon906de572013-06-18 17:01:40 -07006028 DESCRIPTION
6029 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030
Arun Menon906de572013-06-18 17:01:40 -07006031 PARAMETERS
6032 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033
Arun Menon906de572013-06-18 17:01:40 -07006034 RETURN VALUE
6035 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036
Arun Menon906de572013-06-18 17:01:40 -07006037 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006038OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6039{
6040#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006041 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006042 delete iDivXDrmDecrypt;
6043 iDivXDrmDecrypt=NULL;
6044 }
6045#endif //_ANDROID_
6046
Shalaj Jain286b0062013-02-21 20:35:48 -08006047 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006048 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006049 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006050 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006051 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006052 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006053 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054 }
6055
6056 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006057 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006058 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006059 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6060 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061 }
6062#ifdef _ANDROID_ICS_
6063 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6064#endif
6065 }
6066
6067 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006068 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006069 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006070 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6071 if (m_inp_mem_ptr)
6072 free_input_buffer (i,&m_inp_mem_ptr[i]);
6073 else
6074 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006075 }
6076 }
6077 free_input_buffer_header();
6078 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006079 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006080 free(h264_scratch.pBuffer);
6081 h264_scratch.pBuffer = NULL;
6082 }
6083
Arun Menon906de572013-06-18 17:01:40 -07006084 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006086 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006087 }
6088
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006089 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006090 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006091 delete (m_frame_parser.mutils);
6092 m_frame_parser.mutils = NULL;
6093 }
6094
Arun Menon906de572013-06-18 17:01:40 -07006095 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096 free(m_platform_list);
6097 m_platform_list = NULL;
6098 }
Arun Menon906de572013-06-18 17:01:40 -07006099 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006100 free(m_vendor_config.pData);
6101 m_vendor_config.pData = NULL;
6102 }
6103
6104 // Reset counters in mesg queues
6105 m_ftb_q.m_size=0;
6106 m_cmd_q.m_size=0;
6107 m_etb_q.m_size=0;
6108 m_ftb_q.m_read = m_ftb_q.m_write =0;
6109 m_cmd_q.m_read = m_cmd_q.m_write =0;
6110 m_etb_q.m_read = m_etb_q.m_write =0;
6111#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006112 if (m_debug_timestamp) {
6113 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006114 }
6115#endif
6116
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006117 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006119 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006120 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006121
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006122 if (m_debug.infile) {
6123 fclose(m_debug.infile);
6124 m_debug.infile = NULL;
6125 }
6126 if (m_debug.outfile) {
6127 fclose(m_debug.outfile);
6128 m_debug.outfile = NULL;
6129 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006130#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006131 if (outputExtradataFile)
6132 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006133#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006134 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006135 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006136}
6137
6138/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006139 FUNCTION
6140 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006141
Arun Menon906de572013-06-18 17:01:40 -07006142 DESCRIPTION
6143 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Arun Menon906de572013-06-18 17:01:40 -07006145 PARAMETERS
6146 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147
Arun Menon906de572013-06-18 17:01:40 -07006148 RETURN VALUE
6149 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006150
Arun Menon906de572013-06-18 17:01:40 -07006151 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006152OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006153 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6154 OMX_IN OMX_U32 port,
6155 OMX_IN OMX_PTR appData,
6156 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006157{
Arun Menon906de572013-06-18 17:01:40 -07006158 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6159 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6160 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006161
6162#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006163 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6164 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165#else
Arun Menon906de572013-06-18 17:01:40 -07006166 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006167#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006168 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006169 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006170 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006171 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006172#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006173 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006174 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006175 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006176 }
6177 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6178 eglGetProcAddress("eglQueryImageKHR");
6179 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6180 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6181 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006182#else //with OMX test app
6183 struct temp_egl {
6184 int pmem_fd;
6185 int offset;
6186 };
6187 struct temp_egl *temp_egl_id = NULL;
6188 void * pmemPtr = (void *) eglImage;
6189 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006190 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006191 fd = temp_egl_id->pmem_fd;
6192 offset = temp_egl_id->offset;
6193 }
6194#endif
6195 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006196 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006197 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006198 }
6199 pmem_info.pmem_fd = (OMX_U32) fd;
6200 pmem_info.offset = (OMX_U32) offset;
6201 pmem_entry.entry = (void *) &pmem_info;
6202 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6203 pmem_list.entryList = &pmem_entry;
6204 pmem_list.nEntries = 1;
6205 ouput_egl_buffers = true;
6206 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6207 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6208 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006209 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006210 return OMX_ErrorInsufficientResources;
6211 }
6212 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213}
6214
6215/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006216 FUNCTION
6217 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006218
Arun Menon906de572013-06-18 17:01:40 -07006219 DESCRIPTION
6220 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006221
Arun Menon906de572013-06-18 17:01:40 -07006222 PARAMETERS
6223 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006224
Arun Menon906de572013-06-18 17:01:40 -07006225 RETURN VALUE
6226 OMX Error None if everything is successful.
6227 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006228OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006229 OMX_OUT OMX_U8* role,
6230 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006231{
Arun Menon906de572013-06-18 17:01:40 -07006232 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006233
Arun Menon906de572013-06-18 17:01:40 -07006234 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6235 if ((0 == index) && role) {
6236 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006237 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006238 } else {
6239 eRet = OMX_ErrorNoMore;
6240 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241 }
Arun Menon906de572013-06-18 17:01:40 -07006242 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6243 if ((0 == index) && role) {
6244 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006245 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006246 } else {
6247 eRet = OMX_ErrorNoMore;
6248 }
6249 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6250 if ((0 == index) && role) {
6251 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006252 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006253 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006254 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006255 eRet = OMX_ErrorNoMore;
6256 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006257 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006258
Arun Menon906de572013-06-18 17:01:40 -07006259 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6260 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6261 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006262
Shalaj Jain273b3e02012-06-22 19:08:03 -07006263 {
Arun Menon906de572013-06-18 17:01:40 -07006264 if ((0 == index) && role) {
6265 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006266 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006267 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006268 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006269 eRet = OMX_ErrorNoMore;
6270 }
6271 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6272 if ((0 == index) && role) {
6273 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006274 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006275 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006276 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006277 eRet = OMX_ErrorNoMore;
6278 }
6279 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6280 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6281 ) {
6282 if ((0 == index) && role) {
6283 strlcpy((char *)role, "video_decoder.vc1",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 {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006286 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006287 eRet = OMX_ErrorNoMore;
6288 }
6289 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6290 if ((0 == index) && role) {
6291 strlcpy((char *)role, "video_decoder.vp8",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 {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006294 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006295 eRet = OMX_ErrorNoMore;
6296 }
6297 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006298 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006299 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006300 }
Arun Menon906de572013-06-18 17:01:40 -07006301 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302}
6303
6304
6305
6306
6307/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006308 FUNCTION
6309 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310
Arun Menon906de572013-06-18 17:01:40 -07006311 DESCRIPTION
6312 Checks if entire buffer pool is allocated by IL Client or not.
6313 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006314
Arun Menon906de572013-06-18 17:01:40 -07006315 PARAMETERS
6316 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006317
Arun Menon906de572013-06-18 17:01:40 -07006318 RETURN VALUE
6319 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006320
Arun Menon906de572013-06-18 17:01:40 -07006321 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006322bool omx_vdec::allocate_done(void)
6323{
Arun Menon906de572013-06-18 17:01:40 -07006324 bool bRet = false;
6325 bool bRet_In = false;
6326 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006327
Arun Menon906de572013-06-18 17:01:40 -07006328 bRet_In = allocate_input_done();
6329 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006330
Arun Menon906de572013-06-18 17:01:40 -07006331 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006332 bRet = true;
6333 }
Arun Menon906de572013-06-18 17:01:40 -07006334
6335 return bRet;
6336}
6337/* ======================================================================
6338 FUNCTION
6339 omx_vdec::AllocateInputDone
6340
6341 DESCRIPTION
6342 Checks if I/P buffer pool is allocated by IL Client or not.
6343
6344 PARAMETERS
6345 None.
6346
6347 RETURN VALUE
6348 true/false.
6349
6350 ========================================================================== */
6351bool omx_vdec::allocate_input_done(void)
6352{
6353 bool bRet = false;
6354 unsigned i=0;
6355
6356 if (m_inp_mem_ptr == NULL) {
6357 return bRet;
6358 }
6359 if (m_inp_mem_ptr ) {
6360 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6361 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6362 break;
6363 }
6364 }
6365 }
6366 if (i == drv_ctx.ip_buf.actualcount) {
6367 bRet = true;
6368 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6369 }
6370 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6371 m_inp_bPopulated = OMX_TRUE;
6372 }
6373 return bRet;
6374}
6375/* ======================================================================
6376 FUNCTION
6377 omx_vdec::AllocateOutputDone
6378
6379 DESCRIPTION
6380 Checks if entire O/P buffer pool is allocated by IL Client or not.
6381
6382 PARAMETERS
6383 None.
6384
6385 RETURN VALUE
6386 true/false.
6387
6388 ========================================================================== */
6389bool omx_vdec::allocate_output_done(void)
6390{
6391 bool bRet = false;
6392 unsigned j=0;
6393
6394 if (m_out_mem_ptr == NULL) {
6395 return bRet;
6396 }
6397
6398 if (m_out_mem_ptr) {
6399 for (; j < drv_ctx.op_buf.actualcount; j++) {
6400 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6401 break;
6402 }
6403 }
6404 }
6405
6406 if (j == drv_ctx.op_buf.actualcount) {
6407 bRet = true;
6408 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6409 if (m_out_bEnabled)
6410 m_out_bPopulated = OMX_TRUE;
6411 }
6412
6413 return bRet;
6414}
6415
6416/* ======================================================================
6417 FUNCTION
6418 omx_vdec::ReleaseDone
6419
6420 DESCRIPTION
6421 Checks if IL client has released all the buffers.
6422
6423 PARAMETERS
6424 None.
6425
6426 RETURN VALUE
6427 true/false
6428
6429 ========================================================================== */
6430bool omx_vdec::release_done(void)
6431{
6432 bool bRet = false;
6433
6434 if (release_input_done()) {
6435 if (release_output_done()) {
6436 bRet = true;
6437 }
6438 }
6439 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006440}
6441
6442
6443/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006444 FUNCTION
6445 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006446
Arun Menon906de572013-06-18 17:01:40 -07006447 DESCRIPTION
6448 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006449
Arun Menon906de572013-06-18 17:01:40 -07006450 PARAMETERS
6451 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006452
Arun Menon906de572013-06-18 17:01:40 -07006453 RETURN VALUE
6454 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006455
Arun Menon906de572013-06-18 17:01:40 -07006456 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457bool omx_vdec::release_output_done(void)
6458{
Arun Menon906de572013-06-18 17:01:40 -07006459 bool bRet = false;
6460 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006462 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006463 if (m_out_mem_ptr) {
6464 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6465 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6466 break;
6467 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006468 }
Arun Menon906de572013-06-18 17:01:40 -07006469 if (j == drv_ctx.op_buf.actualcount) {
6470 m_out_bm_count = 0;
6471 bRet = true;
6472 }
6473 } else {
6474 m_out_bm_count = 0;
6475 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006476 }
Arun Menon906de572013-06-18 17:01:40 -07006477 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006478}
6479/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006480 FUNCTION
6481 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006482
Arun Menon906de572013-06-18 17:01:40 -07006483 DESCRIPTION
6484 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006485
Arun Menon906de572013-06-18 17:01:40 -07006486 PARAMETERS
6487 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006488
Arun Menon906de572013-06-18 17:01:40 -07006489 RETURN VALUE
6490 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006491
Arun Menon906de572013-06-18 17:01:40 -07006492 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006493bool omx_vdec::release_input_done(void)
6494{
Arun Menon906de572013-06-18 17:01:40 -07006495 bool bRet = false;
6496 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006497
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006498 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006499 if (m_inp_mem_ptr) {
6500 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6501 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6502 break;
6503 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006504 }
Arun Menon906de572013-06-18 17:01:40 -07006505 if (j==drv_ctx.ip_buf.actualcount) {
6506 bRet = true;
6507 }
6508 } else {
6509 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006510 }
Arun Menon906de572013-06-18 17:01:40 -07006511 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006512}
6513
6514OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006515 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006516{
Arun Menon906de572013-06-18 17:01:40 -07006517 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306518 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006519 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006520 return OMX_ErrorBadParameter;
6521 } else if (output_flush_progress) {
6522 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6523 buffer->nFilledLen = 0;
6524 buffer->nTimeStamp = 0;
6525 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6526 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6527 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006528 }
6529
Arun Menon906de572013-06-18 17:01:40 -07006530 if (m_debug_extradata) {
6531 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006532 DEBUG_PRINT_HIGH("");
6533 DEBUG_PRINT_HIGH("***************************************************");
6534 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6535 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006536 }
6537
6538 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006539 DEBUG_PRINT_HIGH("");
6540 DEBUG_PRINT_HIGH("***************************************************");
6541 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6542 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006543 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006544 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006545
6546
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006547 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006548 buffer, buffer->pBuffer);
6549 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006550
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006551 if (dynamic_buf_mode) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006552 unsigned int nPortIndex = 0;
6553 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006554
6555 if (!secure_mode) {
6556 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6557 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6558 }
6559
6560 //Clear graphic buffer handles in dynamic mode
6561 native_buffer[nPortIndex].privatehandle = NULL;
6562 native_buffer[nPortIndex].nativehandle = NULL;
Arun Menonbdb80b02013-08-12 17:45:54 -07006563 }
Arun Menon906de572013-06-18 17:01:40 -07006564 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006565 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006566 if (!output_flush_progress)
6567 post_event((unsigned)NULL, (unsigned)NULL,
6568 OMX_COMPONENT_GENERATE_EOS_DONE);
6569
6570 if (psource_frame) {
6571 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6572 psource_frame = NULL;
6573 }
6574 if (pdest_frame) {
6575 pdest_frame->nFilledLen = 0;
6576 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6577 (unsigned)NULL);
6578 pdest_frame = NULL;
6579 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006580 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006581
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006582 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006583 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006584
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006585 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6586 DEBUG_PRINT_LOW("Processing extradata");
6587 handle_extradata(buffer);
6588 }
6589
Arun Menon906de572013-06-18 17:01:40 -07006590 /* For use buffer we need to copy the data */
6591 if (!output_flush_progress) {
6592 /* This is the error check for non-recoverable errros */
6593 bool is_duplicate_ts_valid = true;
6594 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006595
Arun Menon906de572013-06-18 17:01:40 -07006596 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6597 output_capability == V4L2_PIX_FMT_MPEG2 ||
6598 output_capability == V4L2_PIX_FMT_DIVX ||
6599 output_capability == V4L2_PIX_FMT_DIVX_311)
6600 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006601
Arun Menon906de572013-06-18 17:01:40 -07006602 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6603 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6604 if (mbaff) {
6605 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306606 }
Arun Menon906de572013-06-18 17:01:40 -07006607 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306608
Arun Menon906de572013-06-18 17:01:40 -07006609 if (buffer->nFilledLen > 0) {
6610 time_stamp_dts.get_next_timestamp(buffer,
6611 is_interlaced && is_duplicate_ts_valid);
6612 if (m_debug_timestamp) {
6613 {
6614 OMX_TICKS expected_ts = 0;
6615 m_timestamp_list.pop_min_ts(expected_ts);
6616 if (is_interlaced && is_duplicate_ts_valid) {
6617 m_timestamp_list.pop_min_ts(expected_ts);
6618 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006619 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006620 buffer->nTimeStamp, expected_ts);
6621
6622 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006623 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006624 }
6625 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306626 }
Arun Menon906de572013-06-18 17:01:40 -07006627 } else {
Arun Menon906de572013-06-18 17:01:40 -07006628 time_stamp_dts.remove_time_stamp(
6629 buffer->nTimeStamp,
6630 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306631 }
Arun Menon906de572013-06-18 17:01:40 -07006632
6633
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006634 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006635
Arun Menon906de572013-06-18 17:01:40 -07006636 if (m_cb.FillBufferDone) {
6637 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006638 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006639 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006640 else
6641 set_frame_rate(buffer->nTimeStamp);
6642
Arun Menon906de572013-06-18 17:01:40 -07006643 if (perf_flag) {
6644 if (!proc_frms) {
6645 dec_time.stop();
6646 latency = dec_time.processing_time_us() - latency;
6647 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6648 dec_time.start();
6649 fps_metrics.start();
6650 }
6651 proc_frms++;
6652 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6653 OMX_U64 proc_time = 0;
6654 fps_metrics.stop();
6655 proc_time = fps_metrics.processing_time_us();
6656 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006657 proc_frms, (float)proc_time / 1e6,
6658 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006659 proc_frms = 0;
6660 }
6661 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006662
6663#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006664 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006665
Arun Menon906de572013-06-18 17:01:40 -07006666 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6667 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6668 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6669 buffer->nFilledLen + 3)&(~3));
6670 while (p_extra &&
6671 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006672 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006673 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6674 if (p_extra->eType == OMX_ExtraDataNone) {
6675 break;
6676 }
6677 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6678 }
6679 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006680#endif
Arun Menon906de572013-06-18 17:01:40 -07006681 }
6682 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6683 prev_ts = LLONG_MAX;
6684 rst_prev_ts = true;
6685 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006686
Arun Menon906de572013-06-18 17:01:40 -07006687 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6688 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6689 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006690 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006691 OMX_BUFFERHEADERTYPE *il_buffer;
6692 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006693
vivek mehta79cff222014-01-22 12:17:07 -08006694 if (il_buffer && m_last_rendered_TS >= 0) {
6695 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306696 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006697
6698 // Current frame can be send for rendering if
6699 // (a) current FPS is <= 60
6700 // (b) is the next frame after the frame with TS 0
6701 // (c) is the first frame after seek
6702 // (d) the delta TS b\w two consecutive frames is > 16 ms
6703 // (e) its TS is equal to previous frame TS
6704 // (f) if marked EOS
6705
6706 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6707 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6708 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006709 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006710 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006711 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006712 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006713 }
6714
6715 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6716 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6717 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006718 }
6719
vivek mehta79cff222014-01-22 12:17:07 -08006720 if (il_buffer) {
Arun Menon906de572013-06-18 17:01:40 -07006721 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006722 } else {
Arun Menon906de572013-06-18 17:01:40 -07006723 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6724 return OMX_ErrorBadParameter;
6725 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006726 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006727 } else {
6728 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006730
Praveen Chavancf924182013-12-06 23:16:23 -08006731#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6732 if (m_smoothstreaming_mode) {
6733 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6734 BufferDim_t dim;
6735 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6736 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6737 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6738 if (private_handle) {
6739 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6740 dim.sliceWidth, dim.sliceHeight);
6741 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6742 }
6743 }
6744#endif
6745
Arun Menon906de572013-06-18 17:01:40 -07006746 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006747}
6748
6749OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006750 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006751{
6752
Surajit Podderd2644d52013-08-28 17:59:06 +05306753 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006754 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006755 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006756 }
6757
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006758 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006759 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006760 pending_input_buffers--;
6761
Arun Menon906de572013-06-18 17:01:40 -07006762 if (arbitrary_bytes) {
6763 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006764 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006765 pdest_frame = buffer;
6766 buffer->nFilledLen = 0;
6767 buffer->nTimeStamp = LLONG_MAX;
6768 push_input_buffer (hComp);
6769 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006770 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006771 buffer->nFilledLen = 0;
6772 if (!m_input_free_q.insert_entry((unsigned)buffer,
6773 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006774 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006775 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006776 }
Arun Menon906de572013-06-18 17:01:40 -07006777 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006778 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006779 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006780 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6781 }
6782 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6783 }
6784 return OMX_ErrorNone;
6785}
6786
Shalaj Jain273b3e02012-06-22 19:08:03 -07006787int omx_vdec::async_message_process (void *context, void* message)
6788{
Arun Menon906de572013-06-18 17:01:40 -07006789 omx_vdec* omx = NULL;
6790 struct vdec_msginfo *vdec_msg = NULL;
6791 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6792 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6793 struct vdec_output_frameinfo *output_respbuf = NULL;
6794 int rc=1;
6795 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006796 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006797 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006798 }
Arun Menon906de572013-06-18 17:01:40 -07006799 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006800
Arun Menon906de572013-06-18 17:01:40 -07006801 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006802
Arun Menon906de572013-06-18 17:01:40 -07006803 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006804
Arun Menon906de572013-06-18 17:01:40 -07006805 case VDEC_MSG_EVT_HW_ERROR:
6806 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6807 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6808 break;
6809
6810 case VDEC_MSG_RESP_START_DONE:
6811 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6812 OMX_COMPONENT_GENERATE_START_DONE);
6813 break;
6814
6815 case VDEC_MSG_RESP_STOP_DONE:
6816 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6817 OMX_COMPONENT_GENERATE_STOP_DONE);
6818 break;
6819
6820 case VDEC_MSG_RESP_RESUME_DONE:
6821 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6822 OMX_COMPONENT_GENERATE_RESUME_DONE);
6823 break;
6824
6825 case VDEC_MSG_RESP_PAUSE_DONE:
6826 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6827 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6828 break;
6829
6830 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6831 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6832 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6833 break;
6834 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6835 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6836 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6837 break;
6838 case VDEC_MSG_RESP_INPUT_FLUSHED:
6839 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6840
6841 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6842 vdec_msg->msgdata.input_frame_clientdata; */
6843
6844 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6845 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6846 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306847 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006848 omxhdr = NULL;
6849 vdec_msg->status_code = VDEC_S_EFATAL;
6850 }
6851 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6852 DEBUG_PRINT_HIGH("Unsupported input");
6853 omx->omx_report_error ();
6854 }
6855 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6856 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6857 }
6858 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6859 OMX_COMPONENT_GENERATE_EBD);
6860 break;
6861 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6862 int64_t *timestamp;
6863 timestamp = (int64_t *) malloc(sizeof(int64_t));
6864 if (timestamp) {
6865 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6866 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6867 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006868 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006869 vdec_msg->msgdata.output_frame.time_stamp);
6870 }
6871 break;
6872 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6873 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6874
6875 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6876 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6877 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6878 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6879 vdec_msg->msgdata.output_frame.pic_type);
6880
6881 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306882 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006883 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306884 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006885 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6886 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6887 }
Arun Menon906de572013-06-18 17:01:40 -07006888 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6889 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6890 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6891 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6892 omxhdr->nFlags = 0;
6893
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006894 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006895 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6896 //rc = -1;
6897 }
6898 if (omxhdr->nFilledLen) {
6899 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6900 }
6901 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6902 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6903 } else {
6904 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6905 }
6906 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6907 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6908 }
6909 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6910 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6911 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006912 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006913 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006914 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6915 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6916 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006917 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6918 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6919 omxhdr->nOffset);
6920 }
Arun Menon906de572013-06-18 17:01:40 -07006921 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6922 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006923 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006924 omx->time_stamp_dts.remove_time_stamp(
6925 omxhdr->nTimeStamp,
6926 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6927 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006928 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6929 OMX_COMPONENT_GENERATE_FTB);
6930 break;
6931 }
6932 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6933 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6934 }
6935 vdec_msg->msgdata.output_frame.bufferaddr =
6936 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6937 int format_notably_changed = 0;
6938 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306939 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006940 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6941 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006942 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006943 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6944 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6945 format_notably_changed = 1;
6946 }
6947 }
6948 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6949 vdec_msg->msgdata.output_frame.framesize.left)
6950 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6951 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6952 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6953 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6954 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6955 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6956 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006957 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006958 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6959 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6960 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006961 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006962 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6963 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006964 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6965 omx->drv_ctx.video_resolution.frame_width) {
6966 vdec_msg->msgdata.output_frame.framesize.left = 0;
6967 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6968 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6969 }
6970 }
6971 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6972 omx->drv_ctx.video_resolution.frame_height) {
6973 vdec_msg->msgdata.output_frame.framesize.top = 0;
6974 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6975 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6976 }
6977 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006978 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 -07006979 vdec_msg->msgdata.output_frame.framesize.left,
6980 vdec_msg->msgdata.output_frame.framesize.top,
6981 vdec_msg->msgdata.output_frame.framesize.right,
6982 vdec_msg->msgdata.output_frame.framesize.bottom,
6983 omx->drv_ctx.video_resolution.frame_width,
6984 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006985 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6986 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6987 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6988 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6989 format_notably_changed = 1;
6990 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006991 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006992 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6993 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006994 if (format_notably_changed) {
6995 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306996 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006997 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6998 } else {
6999 if (!omx->client_buffers.update_buffer_req()) {
7000 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7001 }
7002 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7003 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7004 }
7005 }
7006 if (omxhdr->nFilledLen)
7007 omx->prev_n_filled_len = omxhdr->nFilledLen;
7008
7009 output_respbuf = (struct vdec_output_frameinfo *)\
7010 omxhdr->pOutputPortPrivate;
7011 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7012 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
7013 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7014 output_respbuf->pic_type = PICTURE_TYPE_I;
7015 }
7016 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7017 output_respbuf->pic_type = PICTURE_TYPE_P;
7018 }
7019 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7020 output_respbuf->pic_type = PICTURE_TYPE_B;
7021 }
7022
7023 if (omx->output_use_buffer)
7024 memcpy ( omxhdr->pBuffer, (void *)
7025 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7026 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7027 vdec_msg->msgdata.output_frame.len);
7028 } else
7029 omxhdr->nFilledLen = 0;
7030 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7031 OMX_COMPONENT_GENERATE_FBD);
7032 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
7033 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7034 OMX_COMPONENT_GENERATE_EOS_DONE);
7035 else
7036 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7037 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7038 break;
7039 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007040 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007041 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7042 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7043 break;
7044 default:
7045 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007046 }
Arun Menon906de572013-06-18 17:01:40 -07007047 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007048}
7049
7050OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007051 OMX_HANDLETYPE hComp,
7052 OMX_BUFFERHEADERTYPE *buffer
7053 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007054{
Arun Menon906de572013-06-18 17:01:40 -07007055 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007056 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007057
Arun Menon906de572013-06-18 17:01:40 -07007058 if (buffer == NULL) {
7059 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007060 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007061 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7062 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007063 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7064
7065 /* return zero length and not an EOS buffer */
7066 /* return buffer if input flush in progress */
7067 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7068 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007069 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007070 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7071 return OMX_ErrorNone;
7072 }
7073
7074 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007075 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007076 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007077 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007078 push_input_buffer (hComp);
7079 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007080 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007081 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7082 (unsigned)NULL)) {
7083 return OMX_ErrorBadParameter;
7084 }
7085 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007086
7087
Arun Menon906de572013-06-18 17:01:40 -07007088 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007089}
7090
7091OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7092{
Arun Menon906de572013-06-18 17:01:40 -07007093 unsigned address,p2,id;
7094 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007095
Arun Menon906de572013-06-18 17:01:40 -07007096 if (pdest_frame == NULL || psource_frame == NULL) {
7097 /*Check if we have a destination buffer*/
7098 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007099 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007100 if (m_input_free_q.m_size) {
7101 m_input_free_q.pop_entry(&address,&p2,&id);
7102 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7103 pdest_frame->nFilledLen = 0;
7104 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007105 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007106 }
7107 }
7108
7109 /*Check if we have a destination buffer*/
7110 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007111 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007112 if (m_input_pending_q.m_size) {
7113 m_input_pending_q.pop_entry(&address,&p2,&id);
7114 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007115 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007116 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007117 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007118 psource_frame->nFlags,psource_frame->nFilledLen);
7119
7120 }
7121 }
7122
Shalaj Jain273b3e02012-06-22 19:08:03 -07007123 }
7124
Arun Menon906de572013-06-18 17:01:40 -07007125 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7126 switch (codec_type_parse) {
7127 case CODEC_TYPE_MPEG4:
7128 case CODEC_TYPE_H263:
7129 case CODEC_TYPE_MPEG2:
7130 ret = push_input_sc_codec(hComp);
7131 break;
7132 case CODEC_TYPE_H264:
7133 ret = push_input_h264(hComp);
7134 break;
7135 case CODEC_TYPE_VC1:
7136 ret = push_input_vc1(hComp);
7137 break;
7138 default:
7139 break;
7140 }
7141 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007142 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007143 omx_report_error ();
7144 break;
7145 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007146 }
7147
Arun Menon906de572013-06-18 17:01:40 -07007148 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007149}
7150
7151OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7152{
Arun Menon906de572013-06-18 17:01:40 -07007153 OMX_U32 partial_frame = 1;
7154 OMX_BOOL generate_ebd = OMX_TRUE;
7155 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007156
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007157 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007158 psource_frame,psource_frame->nTimeStamp);
7159 if (m_frame_parser.parse_sc_frame(psource_frame,
7160 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007161 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007162 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007163 }
Arun Menon906de572013-06-18 17:01:40 -07007164
7165 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007166 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007167 pdest_frame->nFilledLen,psource_frame,frame_count);
7168
7169
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007170 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007171 /*First Parsed buffer will have only header Hence skip*/
7172 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007173 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007174
7175 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7176 codec_type_parse == CODEC_TYPE_DIVX) {
7177 mp4StreamType psBits;
7178 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7179 psBits.numBytes = pdest_frame->nFilledLen;
7180 mp4_headerparser.parseHeader(&psBits);
7181 }
7182
7183 frame_count++;
7184 } else {
7185 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7186 if (pdest_frame->nFilledLen) {
7187 /*Push the frame to the Decoder*/
7188 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7189 return OMX_ErrorBadParameter;
7190 }
7191 frame_count++;
7192 pdest_frame = NULL;
7193
7194 if (m_input_free_q.m_size) {
7195 m_input_free_q.pop_entry(&address,&p2,&id);
7196 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7197 pdest_frame->nFilledLen = 0;
7198 }
7199 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007200 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007201 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7202 (unsigned)NULL);
7203 pdest_frame = NULL;
7204 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007205 }
Arun Menon906de572013-06-18 17:01:40 -07007206 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007207 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007208 /*Check if Destination Buffer is full*/
7209 if (pdest_frame->nAllocLen ==
7210 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007211 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007212 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007213 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007214 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007215
Arun Menon906de572013-06-18 17:01:40 -07007216 if (psource_frame->nFilledLen == 0) {
7217 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7218 if (pdest_frame) {
7219 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007220 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007221 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007222 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007223 pdest_frame->nFilledLen,frame_count++);
7224 /*Push the frame to the Decoder*/
7225 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7226 return OMX_ErrorBadParameter;
7227 }
7228 frame_count++;
7229 pdest_frame = NULL;
7230 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007231 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007232 generate_ebd = OMX_FALSE;
7233 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007234 }
Arun Menon906de572013-06-18 17:01:40 -07007235 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007236 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007237 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7238 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007239
Arun Menon906de572013-06-18 17:01:40 -07007240 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007241 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007242 m_input_pending_q.pop_entry(&address,&p2,&id);
7243 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007244 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007245 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007246 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007247 psource_frame->nFlags,psource_frame->nFilledLen);
7248 }
7249 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007250 }
Arun Menon906de572013-06-18 17:01:40 -07007251 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007252}
7253
7254OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7255{
Arun Menon906de572013-06-18 17:01:40 -07007256 OMX_U32 partial_frame = 1;
7257 unsigned address = 0, p2 = 0, id = 0;
7258 OMX_BOOL isNewFrame = OMX_FALSE;
7259 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007260
Arun Menon906de572013-06-18 17:01:40 -07007261 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007262 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007263 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007264 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007265 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007266 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007267 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007268 if (h264_scratch.nFilledLen && look_ahead_nal) {
7269 look_ahead_nal = false;
7270 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7271 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007272 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7273 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7274 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007275 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007276 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007277 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007278 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007279 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007280 }
Arun Menon906de572013-06-18 17:01:40 -07007281 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007282
7283 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7284 in EOS flag getting associated with the destination
7285 */
7286 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7287 pdest_frame->nFilledLen) {
7288 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7289 generate_ebd = OMX_FALSE;
7290 }
7291
Arun Menon906de572013-06-18 17:01:40 -07007292 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007293 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007294 if (m_frame_parser.parse_sc_frame(psource_frame,
7295 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007296 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007297 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007298 }
Arun Menon906de572013-06-18 17:01:40 -07007299 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007300 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007301 if (m_frame_parser.parse_h264_nallength(psource_frame,
7302 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007303 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007304 return OMX_ErrorBadParameter;
7305 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007306 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007307
Arun Menon906de572013-06-18 17:01:40 -07007308 if (partial_frame == 0) {
7309 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007310 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007311 nal_count++;
7312 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7313 h264_scratch.nFlags = psource_frame->nFlags;
7314 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007315 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007316 if (h264_scratch.nFilledLen) {
7317 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7318 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007319#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007320 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7321 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7322 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7323 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7324 // If timeinfo is present frame info from SEI is already processed
7325 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7326 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007327#endif
Arun Menon906de572013-06-18 17:01:40 -07007328 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7329 nal_count++;
7330 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7331 pdest_frame->nTimeStamp = h264_last_au_ts;
7332 pdest_frame->nFlags = h264_last_au_flags;
7333#ifdef PANSCAN_HDLR
7334 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7335 h264_parser->update_panscan_data(h264_last_au_ts);
7336#endif
7337 }
7338 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7339 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7340 h264_last_au_ts = h264_scratch.nTimeStamp;
7341 h264_last_au_flags = h264_scratch.nFlags;
7342#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7343 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7344 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7345 if (!VALID_TS(h264_last_au_ts))
7346 h264_last_au_ts = ts_in_sei;
7347 }
7348#endif
7349 } else
7350 h264_last_au_ts = LLONG_MAX;
7351 }
7352
7353 if (!isNewFrame) {
7354 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7355 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007356 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007357 h264_scratch.nFilledLen);
7358 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7359 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7360 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7361 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7362 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7363 h264_scratch.nFilledLen = 0;
7364 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007365 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007366 return OMX_ErrorBadParameter;
7367 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007368 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007369 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007370 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007371 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007372 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007373 pdest_frame->nFilledLen,frame_count++);
7374
7375 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007376 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007377 look_ahead_nal = false;
7378 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7379 h264_scratch.nFilledLen) {
7380 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7381 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7382 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7383 h264_scratch.nFilledLen = 0;
7384 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007385 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007386 return OMX_ErrorBadParameter;
7387 }
7388 } else {
7389 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007390 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007391 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7392 }
7393 /*Push the frame to the Decoder*/
7394 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7395 return OMX_ErrorBadParameter;
7396 }
7397 //frame_count++;
7398 pdest_frame = NULL;
7399 if (m_input_free_q.m_size) {
7400 m_input_free_q.pop_entry(&address,&p2,&id);
7401 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007402 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007403 pdest_frame->nFilledLen = 0;
7404 pdest_frame->nFlags = 0;
7405 pdest_frame->nTimeStamp = LLONG_MAX;
7406 }
7407 }
7408 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007409 }
Arun Menon906de572013-06-18 17:01:40 -07007410 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007411 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007412 /*Check if Destination Buffer is full*/
7413 if (h264_scratch.nAllocLen ==
7414 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007415 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007416 return OMX_ErrorStreamCorrupt;
7417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007418 }
Arun Menon906de572013-06-18 17:01:40 -07007419
7420 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007421 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007422
7423 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7424 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007425 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007426 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7427 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007428 if(pdest_frame->nFilledLen == 0) {
7429 /* No residual frame from before, send whatever
7430 * we have left */
7431 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7432 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7433 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7434 h264_scratch.nFilledLen = 0;
7435 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7436 } else {
7437 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7438 if(!isNewFrame) {
7439 /* Have a residual frame, but we know that the
7440 * AU in this frame is belonging to whatever
7441 * frame we had left over. So append it */
7442 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7443 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7444 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7445 h264_scratch.nFilledLen = 0;
7446 pdest_frame->nTimeStamp = h264_last_au_ts;
7447 } else {
7448 /* Completely new frame, let's just push what
7449 * we have now. The resulting EBD would trigger
7450 * another push */
7451 generate_ebd = OMX_FALSE;
7452 pdest_frame->nTimeStamp = h264_last_au_ts;
7453 h264_last_au_ts = h264_scratch.nTimeStamp;
7454 }
7455 }
Arun Menon906de572013-06-18 17:01:40 -07007456 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007457 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007458 return OMX_ErrorBadParameter;
7459 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007460
7461 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7462 if(generate_ebd == OMX_TRUE) {
7463 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7464 }
Arun Menon906de572013-06-18 17:01:40 -07007465
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007466 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007467 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007468 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007469#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7470 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7471 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7472 if (!VALID_TS(pdest_frame->nTimeStamp))
7473 pdest_frame->nTimeStamp = ts_in_sei;
7474 }
7475#endif
7476 /*Push the frame to the Decoder*/
7477 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7478 return OMX_ErrorBadParameter;
7479 }
7480 frame_count++;
7481 pdest_frame = NULL;
7482 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007483 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007484 pdest_frame,h264_scratch.nFilledLen);
7485 generate_ebd = OMX_FALSE;
7486 }
7487 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 }
Arun Menon906de572013-06-18 17:01:40 -07007489 if (generate_ebd && !psource_frame->nFilledLen) {
7490 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7491 psource_frame = NULL;
7492 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007493 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007494 m_input_pending_q.pop_entry(&address,&p2,&id);
7495 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007496 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007497 psource_frame->nFlags,psource_frame->nFilledLen);
7498 }
7499 }
7500 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007501}
7502
7503OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7504{
7505 OMX_U8 *buf, *pdest;
7506 OMX_U32 partial_frame = 1;
7507 OMX_U32 buf_len, dest_len;
7508
Arun Menon906de572013-06-18 17:01:40 -07007509 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007510 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007511 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007512 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007513 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007514 buf = psource_frame->pBuffer;
7515 buf_len = psource_frame->nFilledLen;
7516
7517 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007518 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007519 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007520 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007521 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007522 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007523 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007524 return OMX_ErrorStreamCorrupt;
7525 }
Arun Menon906de572013-06-18 17:01:40 -07007526 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007527 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7528 pdest_frame->nOffset;
7529 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007530 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007531
Arun Menon906de572013-06-18 17:01:40 -07007532 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007533 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007534 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007535 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007536 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7537 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7538 }
7539 }
7540 }
7541
Arun Menon906de572013-06-18 17:01:40 -07007542 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007543 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007544 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007545 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007546 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007547 return OMX_ErrorBadParameter;
7548 }
Arun Menon906de572013-06-18 17:01:40 -07007549 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007550
7551 case VC1_SP_MP_RCV:
7552 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007553 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007554 return OMX_ErrorBadParameter;
7555 }
7556 return OMX_ErrorNone;
7557}
7558
David Ng38e2d232013-03-15 20:05:58 -07007559#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007560bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007561 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007562{
Arun Menon906de572013-06-18 17:01:40 -07007563 struct pmem_allocation allocation;
7564 allocation.size = buffer_size;
7565 allocation.align = clip2(alignment);
7566 if (allocation.align < 4096) {
7567 allocation.align = 4096;
7568 }
7569 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007570 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007571 allocation.align, allocation.size);
7572 return false;
7573 }
7574 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007575}
David Ng38e2d232013-03-15 20:05:58 -07007576#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007577#ifdef USE_ION
7578int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007579 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7580 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007581{
Arun Menon906de572013-06-18 17:01:40 -07007582 int fd = -EINVAL;
7583 int rc = -EINVAL;
7584 int ion_dev_flag;
7585 struct vdec_ion ion_buf_info;
7586 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007587 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007588 return -EINVAL;
7589 }
7590 ion_dev_flag = O_RDONLY;
7591 fd = open (MEM_DEVICE, ion_dev_flag);
7592 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007593 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007594 return fd;
7595 }
7596 alloc_data->flags = 0;
7597 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7598 alloc_data->flags |= ION_FLAG_CACHED;
7599 }
7600 alloc_data->len = buffer_size;
7601 alloc_data->align = clip2(alignment);
7602 if (alloc_data->align < 4096) {
7603 alloc_data->align = 4096;
7604 }
7605 if ((secure_mode) && (flag & ION_SECURE))
7606 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007607
Arun Menon906de572013-06-18 17:01:40 -07007608 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307609 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007610 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7611 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7612 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007613 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007614 alloc_data->handle = NULL;
7615 close(fd);
7616 fd = -ENOMEM;
7617 return fd;
7618 }
7619 fd_data->handle = alloc_data->handle;
7620 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7621 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007622 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007623 ion_buf_info.ion_alloc_data = *alloc_data;
7624 ion_buf_info.ion_device_fd = fd;
7625 ion_buf_info.fd_ion_data = *fd_data;
7626 free_ion_memory(&ion_buf_info);
7627 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007628 fd = -ENOMEM;
7629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007630
Arun Menon906de572013-06-18 17:01:40 -07007631 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007632}
7633
Arun Menon906de572013-06-18 17:01:40 -07007634void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7635{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007636
Arun Menon906de572013-06-18 17:01:40 -07007637 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007638 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007639 return;
7640 }
7641 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7642 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007643 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007644 }
7645 close(buf_ion_info->ion_device_fd);
7646 buf_ion_info->ion_device_fd = -1;
7647 buf_ion_info->ion_alloc_data.handle = NULL;
7648 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649}
7650#endif
7651void omx_vdec::free_output_buffer_header()
7652{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007653 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007654 output_use_buffer = false;
7655 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007656
Arun Menon906de572013-06-18 17:01:40 -07007657 if (m_out_mem_ptr) {
7658 free (m_out_mem_ptr);
7659 m_out_mem_ptr = NULL;
7660 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007661
Arun Menon906de572013-06-18 17:01:40 -07007662 if (m_platform_list) {
7663 free(m_platform_list);
7664 m_platform_list = NULL;
7665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007666
Arun Menon906de572013-06-18 17:01:40 -07007667 if (drv_ctx.ptr_respbuffer) {
7668 free (drv_ctx.ptr_respbuffer);
7669 drv_ctx.ptr_respbuffer = NULL;
7670 }
7671 if (drv_ctx.ptr_outputbuffer) {
7672 free (drv_ctx.ptr_outputbuffer);
7673 drv_ctx.ptr_outputbuffer = NULL;
7674 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007675#ifdef USE_ION
7676 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007677 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007678 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007679 drv_ctx.op_buf_ion_info = NULL;
7680 }
7681#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007682 if (out_dynamic_list) {
7683 free(out_dynamic_list);
7684 out_dynamic_list = NULL;
7685 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007686}
7687
7688void omx_vdec::free_input_buffer_header()
7689{
7690 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007691 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007692 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007694 free (m_inp_heap_ptr);
7695 m_inp_heap_ptr = NULL;
7696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007697
Arun Menon906de572013-06-18 17:01:40 -07007698 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007699 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007700 free (m_phdr_pmem_ptr);
7701 m_phdr_pmem_ptr = NULL;
7702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007703 }
Arun Menon906de572013-06-18 17:01:40 -07007704 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007706 free (m_inp_mem_ptr);
7707 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007708 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007709 /* We just freed all the buffer headers, every thing in m_input_free_q,
7710 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007711 while (m_input_free_q.m_size) {
7712 unsigned address, p2, id;
7713 m_input_free_q.pop_entry(&address, &p2, &id);
7714 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007715 while (m_input_pending_q.m_size) {
7716 unsigned address, p2, id;
7717 m_input_pending_q.pop_entry(&address, &p2, &id);
7718 }
7719 pdest_frame = NULL;
7720 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007721 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007722 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007723 free (drv_ctx.ptr_inputbuffer);
7724 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007725 }
7726#ifdef USE_ION
7727 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007728 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007729 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007730 drv_ctx.ip_buf_ion_info = NULL;
7731 }
7732#endif
7733}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007734
7735int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007736{
Arun Menon906de572013-06-18 17:01:40 -07007737 enum v4l2_buf_type btype;
7738 int rc = 0;
7739 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007740
Arun Menon906de572013-06-18 17:01:40 -07007741 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7742 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7743 v4l2_port = OUTPUT_PORT;
7744 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7745 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7746 v4l2_port = CAPTURE_PORT;
7747 } else if (port == OMX_ALL) {
7748 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7749 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007750
Arun Menon906de572013-06-18 17:01:40 -07007751 if (!rc_input)
7752 return rc_input;
7753 else
7754 return rc_output;
7755 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007756
Arun Menon906de572013-06-18 17:01:40 -07007757 if (!streaming[v4l2_port]) {
7758 // already streamed off, warn and move on
7759 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7760 " which is already streamed off", v4l2_port);
7761 return 0;
7762 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007763
Arun Menon906de572013-06-18 17:01:40 -07007764 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007765
Arun Menon906de572013-06-18 17:01:40 -07007766 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7767 if (rc) {
7768 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007769 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007770 } else {
7771 streaming[v4l2_port] = false;
7772 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007773
Arun Menon906de572013-06-18 17:01:40 -07007774 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775}
7776
7777OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7778{
Arun Menon906de572013-06-18 17:01:40 -07007779 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7780 struct v4l2_requestbuffers bufreq;
7781 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7782 struct v4l2_format fmt;
7783 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007784 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007785 buffer_prop->actualcount, buffer_prop->buffer_size);
7786 bufreq.memory = V4L2_MEMORY_USERPTR;
7787 bufreq.count = 1;
7788 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7789 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7790 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7791 fmt.fmt.pix_mp.pixelformat = output_capability;
7792 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7793 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7794 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7795 fmt.fmt.pix_mp.pixelformat = capture_capability;
7796 } else {
7797 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007798 }
Arun Menon906de572013-06-18 17:01:40 -07007799 if (eRet==OMX_ErrorNone) {
7800 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007801 }
Arun Menon906de572013-06-18 17:01:40 -07007802 if (ret) {
7803 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7804 /*TODO: How to handle this case */
7805 eRet = OMX_ErrorInsufficientResources;
7806 return eRet;
7807 } else {
7808 buffer_prop->actualcount = bufreq.count;
7809 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007810 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007811 }
Arun Menon906de572013-06-18 17:01:40 -07007812 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7813 buffer_prop->actualcount, buffer_prop->buffer_size);
7814
7815 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7816 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7817
7818 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7819
7820 update_resolution(fmt.fmt.pix_mp.width,
7821 fmt.fmt.pix_mp.height,
7822 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7823 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7824 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7825 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007826 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007827
7828 if (ret) {
7829 /*TODO: How to handle this case */
7830 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7831 eRet = OMX_ErrorInsufficientResources;
7832 } else {
7833 int extra_idx = 0;
7834
7835 eRet = is_video_session_supported();
7836 if (eRet)
7837 return eRet;
7838
7839 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7840 buf_size = buffer_prop->buffer_size;
7841 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7842 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7843 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7844 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007845 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007846 return OMX_ErrorBadParameter;
7847 }
7848 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7849 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7850 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7851 }
7852 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7853 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7854 }
7855 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7856 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007857 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007858 client_extra_data_size);
7859 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307860 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7861 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7862 DEBUG_PRINT_HIGH("framepack extradata enabled");
7863 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007864 if (client_extradata & OMX_QP_EXTRADATA) {
7865 client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
7866 DEBUG_PRINT_HIGH("QP extradata enabled");
7867 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08007868 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
7869 client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
7870 DEBUG_PRINT_HIGH("Input bits info extradata enabled");
7871 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007872
Arun Menon906de572013-06-18 17:01:40 -07007873 if (client_extra_data_size) {
7874 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7875 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7876 }
7877 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7878 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7879 drv_ctx.extradata_info.buffer_size = extra_data_size;
7880 buf_size += client_extra_data_size;
7881 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7882 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7883 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7884 if (in_reconfig) // BufReq will be set to driver when port is disabled
7885 buffer_prop->buffer_size = buf_size;
7886 else if (buf_size != buffer_prop->buffer_size) {
7887 buffer_prop->buffer_size = buf_size;
7888 eRet = set_buffer_req(buffer_prop);
7889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007890 }
Arun Menon906de572013-06-18 17:01:40 -07007891 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7892 buffer_prop->actualcount, buffer_prop->buffer_size);
7893 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007894}
7895
7896OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7897{
Arun Menon906de572013-06-18 17:01:40 -07007898 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7899 unsigned buf_size = 0;
7900 struct v4l2_format fmt;
7901 struct v4l2_requestbuffers bufreq;
7902 int ret;
7903 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7904 buffer_prop->actualcount, buffer_prop->buffer_size);
7905 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7906 if (buf_size != buffer_prop->buffer_size) {
7907 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7908 buffer_prop->buffer_size, buf_size);
7909 eRet = OMX_ErrorBadParameter;
7910 } else {
7911 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7912 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007913
Arun Menon906de572013-06-18 17:01:40 -07007914 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7915 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7916 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007917 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007918 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7919 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7920 fmt.fmt.pix_mp.pixelformat = capture_capability;
7921 } else {
7922 eRet = OMX_ErrorBadParameter;
7923 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007924
Arun Menon906de572013-06-18 17:01:40 -07007925 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7926 if (ret) {
7927 /*TODO: How to handle this case */
7928 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7929 eRet = OMX_ErrorInsufficientResources;
7930 }
7931
7932 bufreq.memory = V4L2_MEMORY_USERPTR;
7933 bufreq.count = buffer_prop->actualcount;
7934 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7935 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7936 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7937 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7938 } else {
7939 eRet = OMX_ErrorBadParameter;
7940 }
7941
7942 if (eRet==OMX_ErrorNone) {
7943 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7944 }
7945
7946 if (ret) {
7947 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7948 /*TODO: How to handle this case */
7949 eRet = OMX_ErrorInsufficientResources;
7950 } else if (bufreq.count < buffer_prop->actualcount) {
7951 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7952 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7953 buffer_prop->actualcount, bufreq.count);
7954 eRet = OMX_ErrorInsufficientResources;
7955 } else {
7956 if (!client_buffers.update_buffer_req()) {
7957 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7958 eRet = OMX_ErrorInsufficientResources;
7959 }
7960 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007961 }
Arun Menon906de572013-06-18 17:01:40 -07007962 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007963}
7964
Shalaj Jain273b3e02012-06-22 19:08:03 -07007965OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7966{
Arun Menon906de572013-06-18 17:01:40 -07007967 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7968 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007969}
7970
7971OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7972{
Arun Menon906de572013-06-18 17:01:40 -07007973 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7974 if (!portDefn) {
7975 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007976 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007977 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007978 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7979 portDefn->nSize = sizeof(portDefn);
7980 portDefn->eDomain = OMX_PortDomainVideo;
7981 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08007982 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
7983 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07007984 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007985 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007986 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007987 }
Arun Menon906de572013-06-18 17:01:40 -07007988 if (0 == portDefn->nPortIndex) {
7989 portDefn->eDir = OMX_DirInput;
7990 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7991 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7992 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7993 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7994 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7995 portDefn->bEnabled = m_inp_bEnabled;
7996 portDefn->bPopulated = m_inp_bPopulated;
7997 } else if (1 == portDefn->nPortIndex) {
7998 unsigned int buf_size = 0;
7999 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008000 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008001 return OMX_ErrorHardware;
8002 }
8003 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008004 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008005 return OMX_ErrorHardware;
8006 }
8007 portDefn->nBufferSize = buf_size;
8008 portDefn->eDir = OMX_DirOutput;
8009 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8010 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8011 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8012 portDefn->bEnabled = m_out_bEnabled;
8013 portDefn->bPopulated = m_out_bPopulated;
8014 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008015 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008016 return OMX_ErrorHardware;
8017 }
8018 } else {
8019 portDefn->eDir = OMX_DirMax;
8020 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8021 (int)portDefn->nPortIndex);
8022 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008023 }
Arun Menon906de572013-06-18 17:01:40 -07008024 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8025 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8026 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8027 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308028 if (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) {
8029 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8030 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8031 }
8032 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8033 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8034 portDefn->nPortIndex,
8035 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008036 portDefn->format.video.nFrameHeight,
8037 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308038 portDefn->format.video.nSliceHeight,
8039 portDefn->format.video.eColorFormat,
8040 portDefn->nBufferSize,
8041 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008042
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308043 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008044}
8045
8046OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8047{
Arun Menon906de572013-06-18 17:01:40 -07008048 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8049 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8050 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008051
Arun Menon906de572013-06-18 17:01:40 -07008052 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008053 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008054 int nBufHdrSize = 0;
8055 int nPlatformEntrySize = 0;
8056 int nPlatformListSize = 0;
8057 int nPMEMInfoSize = 0;
8058 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8059 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8060 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008061
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008062 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008063 drv_ctx.op_buf.actualcount);
8064 nBufHdrSize = drv_ctx.op_buf.actualcount *
8065 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008066
Arun Menon906de572013-06-18 17:01:40 -07008067 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8068 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8069 nPlatformListSize = drv_ctx.op_buf.actualcount *
8070 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8071 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8072 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008073
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008074 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008075 sizeof(OMX_BUFFERHEADERTYPE),
8076 nPMEMInfoSize,
8077 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008078 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008079 m_out_bm_count);
8080 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8081 // Alloc mem for platform specific info
8082 char *pPtr=NULL;
8083 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8084 nPMEMInfoSize,1);
8085 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8086 calloc (sizeof(struct vdec_bufferpayload),
8087 drv_ctx.op_buf.actualcount);
8088 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8089 calloc (sizeof (struct vdec_output_frameinfo),
8090 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008091#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008092 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8093 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008094#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008095 if (dynamic_buf_mode) {
8096 out_dynamic_list = (struct dynamic_buf_list *) \
8097 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8098 }
Arun Menon906de572013-06-18 17:01:40 -07008099 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8100 && drv_ctx.ptr_respbuffer) {
8101 bufHdr = m_out_mem_ptr;
8102 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8103 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8104 (((char *) m_platform_list) + nPlatformListSize);
8105 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8106 (((char *) m_platform_entry) + nPlatformEntrySize);
8107 pPlatformList = m_platform_list;
8108 pPlatformEntry = m_platform_entry;
8109 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008110
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008111 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008112
Arun Menon906de572013-06-18 17:01:40 -07008113 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008114 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008115 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008116 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008117 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8118 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8119 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8120 // Set the values when we determine the right HxW param
8121 bufHdr->nAllocLen = 0;
8122 bufHdr->nFilledLen = 0;
8123 bufHdr->pAppPrivate = NULL;
8124 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8125 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8126 pPlatformEntry->entry = pPMEMInfo;
8127 // Initialize the Platform List
8128 pPlatformList->nEntries = 1;
8129 pPlatformList->entryList = pPlatformEntry;
8130 // Keep pBuffer NULL till vdec is opened
8131 bufHdr->pBuffer = NULL;
8132 pPMEMInfo->offset = 0;
8133 pPMEMInfo->pmem_fd = 0;
8134 bufHdr->pPlatformPrivate = pPlatformList;
8135 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008136#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008137 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008138#endif
Arun Menon906de572013-06-18 17:01:40 -07008139 /*Create a mapping between buffers*/
8140 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8141 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8142 &drv_ctx.ptr_outputbuffer[i];
8143 // Move the buffer and buffer header pointers
8144 bufHdr++;
8145 pPMEMInfo++;
8146 pPlatformEntry++;
8147 pPlatformList++;
8148 }
8149 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008150 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008151 m_out_mem_ptr, pPtr);
8152 if (m_out_mem_ptr) {
8153 free(m_out_mem_ptr);
8154 m_out_mem_ptr = NULL;
8155 }
8156 if (pPtr) {
8157 free(pPtr);
8158 pPtr = NULL;
8159 }
8160 if (drv_ctx.ptr_outputbuffer) {
8161 free(drv_ctx.ptr_outputbuffer);
8162 drv_ctx.ptr_outputbuffer = NULL;
8163 }
8164 if (drv_ctx.ptr_respbuffer) {
8165 free(drv_ctx.ptr_respbuffer);
8166 drv_ctx.ptr_respbuffer = NULL;
8167 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008168#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008169 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008170 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008171 free(drv_ctx.op_buf_ion_info);
8172 drv_ctx.op_buf_ion_info = NULL;
8173 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008174#endif
Arun Menon906de572013-06-18 17:01:40 -07008175 eRet = OMX_ErrorInsufficientResources;
8176 }
8177 } else {
8178 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008179 }
Arun Menon906de572013-06-18 17:01:40 -07008180 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008181}
8182
8183void omx_vdec::complete_pending_buffer_done_cbs()
8184{
Arun Menon906de572013-06-18 17:01:40 -07008185 unsigned p1;
8186 unsigned p2;
8187 unsigned ident;
8188 omx_cmd_queue tmp_q, pending_bd_q;
8189 pthread_mutex_lock(&m_lock);
8190 // pop all pending GENERATE FDB from ftb queue
8191 while (m_ftb_q.m_size) {
8192 m_ftb_q.pop_entry(&p1,&p2,&ident);
8193 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8194 pending_bd_q.insert_entry(p1,p2,ident);
8195 } else {
8196 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008197 }
Arun Menon906de572013-06-18 17:01:40 -07008198 }
8199 //return all non GENERATE FDB to ftb queue
8200 while (tmp_q.m_size) {
8201 tmp_q.pop_entry(&p1,&p2,&ident);
8202 m_ftb_q.insert_entry(p1,p2,ident);
8203 }
8204 // pop all pending GENERATE EDB from etb queue
8205 while (m_etb_q.m_size) {
8206 m_etb_q.pop_entry(&p1,&p2,&ident);
8207 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8208 pending_bd_q.insert_entry(p1,p2,ident);
8209 } else {
8210 tmp_q.insert_entry(p1,p2,ident);
8211 }
8212 }
8213 //return all non GENERATE FDB to etb queue
8214 while (tmp_q.m_size) {
8215 tmp_q.pop_entry(&p1,&p2,&ident);
8216 m_etb_q.insert_entry(p1,p2,ident);
8217 }
8218 pthread_mutex_unlock(&m_lock);
8219 // process all pending buffer dones
8220 while (pending_bd_q.m_size) {
8221 pending_bd_q.pop_entry(&p1,&p2,&ident);
8222 switch (ident) {
8223 case OMX_COMPONENT_GENERATE_EBD:
8224 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008225 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008226 omx_report_error ();
8227 }
8228 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008229
Arun Menon906de572013-06-18 17:01:40 -07008230 case OMX_COMPONENT_GENERATE_FBD:
8231 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008232 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008233 omx_report_error ();
8234 }
8235 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008236 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008238}
8239
8240void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8241{
Arun Menon906de572013-06-18 17:01:40 -07008242 OMX_U32 new_frame_interval = 0;
8243 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8244 && llabs(act_timestamp - prev_ts) > 2000) {
8245 new_frame_interval = client_set_fps ? frm_int :
8246 llabs(act_timestamp - prev_ts);
8247 if (new_frame_interval < frm_int || frm_int == 0) {
8248 frm_int = new_frame_interval;
8249 if (frm_int) {
8250 drv_ctx.frame_rate.fps_numerator = 1e6;
8251 drv_ctx.frame_rate.fps_denominator = frm_int;
8252 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8253 frm_int, drv_ctx.frame_rate.fps_numerator /
8254 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008255
Arun Menon906de572013-06-18 17:01:40 -07008256 /* We need to report the difference between this FBD and the previous FBD
8257 * back to the driver for clock scaling purposes. */
8258 struct v4l2_outputparm oparm;
8259 /*XXX: we're providing timing info as seconds per frame rather than frames
8260 * per second.*/
8261 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8262 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008263
Arun Menon906de572013-06-18 17:01:40 -07008264 struct v4l2_streamparm sparm;
8265 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8266 sparm.parm.output = oparm;
8267 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8268 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8269 performance might be affected");
8270 }
8271
8272 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008273 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008274 }
Arun Menon906de572013-06-18 17:01:40 -07008275 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008276}
8277
8278void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8279{
Arun Menon906de572013-06-18 17:01:40 -07008280 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8281 prev_ts = act_timestamp;
8282 rst_prev_ts = false;
8283 } else if (VALID_TS(prev_ts)) {
8284 bool codec_cond = (drv_ctx.timestamp_adjust)?
8285 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8286 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8287 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8288 if (frm_int > 0 && codec_cond) {
8289 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8290 act_timestamp = prev_ts + frm_int;
8291 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8292 prev_ts = act_timestamp;
8293 } else
8294 set_frame_rate(act_timestamp);
8295 } else if (frm_int > 0) // In this case the frame rate was set along
8296 { // with the port definition, start ts with 0
8297 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8298 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008299 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008300}
8301
8302void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8303{
Arun Menon906de572013-06-18 17:01:40 -07008304 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8305 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308306 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008307 OMX_U32 frame_rate = 0;
8308 int consumed_len = 0;
8309 OMX_U32 num_MB_in_frame;
8310 OMX_U32 recovery_sei_flags = 1;
8311 int enable = 0;
8312 OMX_U32 mbaff = 0;
8313 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008314 if (buf_index >= drv_ctx.extradata_info.count) {
8315 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8316 buf_index, drv_ctx.extradata_info.count);
8317 return;
8318 }
Arun Menon906de572013-06-18 17:01:40 -07008319 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8320 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8321 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308322
Arun Menon906de572013-06-18 17:01:40 -07008323 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308324 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008325 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008326 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308327 if (!secure_mode)
8328 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008329 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308330 else
8331 p_extra = m_other_extradata;
8332
Arun Menon906de572013-06-18 17:01:40 -07008333 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308334
8335 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008336 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308337 return;
8338 }
Arun Menon906de572013-06-18 17:01:40 -07008339 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8340 if (data) {
8341 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8342 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308343 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008344 DEBUG_PRINT_LOW("Invalid extra data size");
8345 break;
8346 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308347 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008348 switch ((unsigned long)data->eType) {
8349 case EXTRADATA_INTERLACE_VIDEO:
8350 struct msm_vidc_interlace_payload *payload;
8351 payload = (struct msm_vidc_interlace_payload *)data->data;
8352 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8353 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8354 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008355 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8356 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8357 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8358 enable = 1;
8359 } else {
Arun Menon906de572013-06-18 17:01:40 -07008360 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8361 enable = 1;
8362 }
8363 if (m_enable_android_native_buffers)
8364 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8365 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308366 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008367 append_interlace_extradata(p_extra, payload->format);
8368 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8369 }
8370 break;
8371 case EXTRADATA_FRAME_RATE:
8372 struct msm_vidc_framerate_payload *frame_rate_payload;
8373 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8374 frame_rate = frame_rate_payload->frame_rate;
8375 break;
8376 case EXTRADATA_TIMESTAMP:
8377 struct msm_vidc_ts_payload *time_stamp_payload;
8378 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308379 time_stamp = time_stamp_payload->timestamp_lo;
8380 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8381 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008382 break;
8383 case EXTRADATA_NUM_CONCEALED_MB:
8384 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8385 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8386 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8387 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8388 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8389 break;
8390 case EXTRADATA_INDEX:
8391 int *etype;
8392 etype = (int *)(data->data);
8393 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8394 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8395 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8396 if (aspect_ratio_payload) {
8397 ((struct vdec_output_frameinfo *)
8398 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8399 ((struct vdec_output_frameinfo *)
8400 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8401 }
8402 }
8403 break;
8404 case EXTRADATA_RECOVERY_POINT_SEI:
8405 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8406 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8407 recovery_sei_flags = recovery_sei_payload->flags;
8408 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8409 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008410 DEBUG_PRINT_HIGH("");
8411 DEBUG_PRINT_HIGH("***************************************************");
8412 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8413 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008414 }
8415 break;
8416 case EXTRADATA_PANSCAN_WINDOW:
8417 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8418 break;
8419 case EXTRADATA_MPEG2_SEQDISP:
8420 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8421 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8422 if (seqdisp_payload) {
8423 m_disp_hor_size = seqdisp_payload->disp_width;
8424 m_disp_vert_size = seqdisp_payload->disp_height;
8425 }
8426 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308427 case EXTRADATA_S3D_FRAME_PACKING:
8428 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8429 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
8430 if (!secure_mode && (client_extradata & OMX_FRAMEPACK_EXTRADATA)) {
8431 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8432 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8433 }
8434 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008435 case EXTRADATA_FRAME_QP:
8436 struct msm_vidc_frame_qp_payload *qp_payload;
8437 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
8438 if (!secure_mode && (client_extradata & OMX_QP_EXTRADATA)) {
8439 append_qp_extradata(p_extra, qp_payload);
8440 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8441 }
8442 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008443 case EXTRADATA_FRAME_BITS_INFO:
8444 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8445 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
8446 if (!secure_mode && (client_extradata & OMX_BITSINFO_EXTRADATA)) {
8447 append_bitsinfo_extradata(p_extra, bits_info_payload);
8448 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8449 }
8450 break;
Arun Menon906de572013-06-18 17:01:40 -07008451 default:
8452 goto unrecognized_extradata;
8453 }
8454 consumed_len += data->nSize;
8455 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8456 }
8457 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8458 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8459 append_frame_info_extradata(p_extra,
8460 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308461 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008462 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008463 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008464 }
8465 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008466unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008467 if (!secure_mode && client_extradata)
8468 append_terminator_extradata(p_extra);
8469 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470}
8471
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008472OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008473 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008474{
Arun Menon906de572013-06-18 17:01:40 -07008475 OMX_ERRORTYPE ret = OMX_ErrorNone;
8476 struct v4l2_control control;
8477 if (m_state != OMX_StateLoaded) {
8478 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8479 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008480 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008481 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008482 client_extradata, requested_extradata, enable, is_internal);
8483
8484 if (!is_internal) {
8485 if (enable)
8486 client_extradata |= requested_extradata;
8487 else
8488 client_extradata = client_extradata & ~requested_extradata;
8489 }
8490
8491 if (enable) {
8492 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8493 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8494 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8495 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8496 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008497 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008498 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308499 }
8500 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008501 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8502 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8503 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008504 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008505 }
8506 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8507 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8508 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008509 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008510 }
8511 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8512 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8513 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008514 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008515 }
8516 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8517 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8518 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008519 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008520 }
8521 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8522 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8523 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008524 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008525 }
8526 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8527 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8528 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8529 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008530 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008531 }
8532 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308533 }
8534 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008535 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8536 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8537 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008538 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008539 }
8540 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308541 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8542 if (output_capability == V4L2_PIX_FMT_H264) {
8543 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8544 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8545 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8546 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8547 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8548 }
8549 } else {
8550 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8551 }
8552 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008553 if (requested_extradata & OMX_QP_EXTRADATA) {
8554 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8555 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8556 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8557 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8558 }
8559 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008560 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8561 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8562 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8563 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8564 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8565 }
8566 }
Arun Menon906de572013-06-18 17:01:40 -07008567 }
8568 ret = get_buffer_req(&drv_ctx.op_buf);
8569 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008570}
8571
8572OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8573{
Arun Menon906de572013-06-18 17:01:40 -07008574 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8575 OMX_U8 *data_ptr = extra->data, data = 0;
8576 while (byte_count < extra->nDataSize) {
8577 data = *data_ptr;
8578 while (data) {
8579 num_MB += (data&0x01);
8580 data >>= 1;
8581 }
8582 data_ptr++;
8583 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008584 }
Arun Menon906de572013-06-18 17:01:40 -07008585 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8586 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8587 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008588}
8589
8590void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8591{
Arun Menon906de572013-06-18 17:01:40 -07008592 if (!m_debug_extradata)
8593 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008594
8595 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308596 "============== Extra Data ==============\n"
8597 " Size: %lu\n"
8598 " Version: %lu\n"
8599 " PortIndex: %lu\n"
8600 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008601 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008602 extra->nSize, extra->nVersion.nVersion,
8603 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008604
Arun Menon906de572013-06-18 17:01:40 -07008605 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8606 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8607 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308608 "------ Interlace Format ------\n"
8609 " Size: %lu\n"
8610 " Version: %lu\n"
8611 " PortIndex: %lu\n"
8612 " Is Interlace Format: %d\n"
8613 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008614 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008615 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8616 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8617 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8618 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8619
8620 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308621 "-------- Frame Format --------\n"
8622 " Picture Type: %d\n"
8623 " Interlace Type: %d\n"
8624 " Pan Scan Total Frame Num: %lu\n"
8625 " Concealed Macro Blocks: %lu\n"
8626 " frame rate: %lu\n"
8627 " Time Stamp: %llu\n"
8628 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008629 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008630 fminfo->ePicType,
8631 fminfo->interlaceType,
8632 fminfo->panScan.numWindows,
8633 fminfo->nConcealedMacroblocks,
8634 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308635 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008636 fminfo->aspectRatio.aspectRatioX,
8637 fminfo->aspectRatio.aspectRatioY);
8638
8639 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8640 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008641 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308642 " Pan Scan Frame Num: %lu\n"
8643 " Rectangle x: %ld\n"
8644 " Rectangle y: %ld\n"
8645 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008646 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008647 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8648 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8649 }
8650
8651 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308652 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8653 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8654 DEBUG_PRINT_HIGH(
8655 "------------------ Framepack Format ----------\n"
8656 " id: %lu \n"
8657 " cancel_flag: %lu \n"
8658 " type: %lu \n"
8659 " quincunx_sampling_flagFormat: %lu \n"
8660 " content_interpretation_type: %lu \n"
8661 " content_interpretation_type: %lu \n"
8662 " spatial_flipping_flag: %lu \n"
8663 " frame0_flipped_flag: %lu \n"
8664 " field_views_flag: %lu \n"
8665 " current_frame_is_frame0_flag: %lu \n"
8666 " frame0_self_contained_flag: %lu \n"
8667 " frame1_self_contained_flag: %lu \n"
8668 " frame0_grid_position_x: %lu \n"
8669 " frame0_grid_position_y: %lu \n"
8670 " frame1_grid_position_x: %lu \n"
8671 " frame1_grid_position_y: %lu \n"
8672 " reserved_byte: %lu \n"
8673 " repetition_period: %lu \n"
8674 " extension_flag: %lu \n"
8675 "================== End of Framepack ===========",
8676 framepack->id,
8677 framepack->cancel_flag,
8678 framepack->type,
8679 framepack->quincunx_sampling_flag,
8680 framepack->content_interpretation_type,
8681 framepack->spatial_flipping_flag,
8682 framepack->frame0_flipped_flag,
8683 framepack->field_views_flag,
8684 framepack->current_frame_is_frame0_flag,
8685 framepack->frame0_self_contained_flag,
8686 framepack->frame1_self_contained_flag,
8687 framepack->frame0_grid_position_x,
8688 framepack->frame0_grid_position_y,
8689 framepack->frame1_grid_position_x,
8690 framepack->frame1_grid_position_y,
8691 framepack->reserved_byte,
8692 framepack->repetition_period,
8693 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008694 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8695 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8696 DEBUG_PRINT_HIGH(
8697 "---- QP (Frame quantization parameter) ----\n"
8698 " Frame QP: %lu \n"
8699 "================ End of QP ================\n",
8700 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008701 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8702 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8703 DEBUG_PRINT_HIGH(
8704 "--------- Input bits information --------\n"
8705 " Header bits: %lu \n"
8706 " Frame bits: %lu \n"
8707 "===== End of Input bits information =====\n",
8708 bits->header_bits, bits->frame_bits);
Arun Menon906de572013-06-18 17:01:40 -07008709 } else if (extra->eType == OMX_ExtraDataNone) {
8710 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8711 } else {
8712 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008714}
8715
8716void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008717 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008718{
Arun Menon906de572013-06-18 17:01:40 -07008719 OMX_STREAMINTERLACEFORMAT *interlace_format;
8720 OMX_U32 mbaff = 0;
8721 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8722 return;
8723 }
8724 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8725 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8726 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8727 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8728 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8729 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8730 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8731 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8732 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8733 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8734 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8735 interlace_format->bInterlaceFormat = OMX_FALSE;
8736 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8737 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008738 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8739 interlace_format->bInterlaceFormat = OMX_TRUE;
8740 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8741 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8742 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8743 interlace_format->bInterlaceFormat = OMX_TRUE;
8744 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8745 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008746 } else {
8747 interlace_format->bInterlaceFormat = OMX_TRUE;
8748 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8749 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8750 }
8751 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008752}
8753
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008754void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008755 struct vdec_aspectratioinfo *aspect_ratio_info,
8756 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008757{
Arun Menon906de572013-06-18 17:01:40 -07008758 m_extradata = frame_info;
8759 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8760 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308761 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008762 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008763}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008764
8765void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008766 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308767 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008768 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008769{
Arun Menon906de572013-06-18 17:01:40 -07008770 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8771 struct msm_vidc_panscan_window *panscan_window;
8772 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008773 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008774 }
Arun Menon906de572013-06-18 17:01:40 -07008775 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8776 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8777 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8778 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8779 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8780 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8781 switch (picture_type) {
8782 case PICTURE_TYPE_I:
8783 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8784 break;
8785 case PICTURE_TYPE_P:
8786 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8787 break;
8788 case PICTURE_TYPE_B:
8789 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8790 break;
8791 default:
8792 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8793 }
8794 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8795 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8796 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8797 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8798 else
8799 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8800 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8801 frame_info->nConcealedMacroblocks = num_conceal_mb;
8802 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308803 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008804 frame_info->panScan.numWindows = 0;
8805 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8806 if (m_disp_hor_size && m_disp_vert_size) {
8807 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8808 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05308809 } else {
8810 frame_info->displayAspectRatio.displayHorizontalSize = 0;
8811 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07008812 }
8813 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008814
Arun Menon906de572013-06-18 17:01:40 -07008815 if (panscan_payload) {
8816 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8817 panscan_window = &panscan_payload->wnd[0];
8818 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8819 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8820 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8821 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8822 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8823 panscan_window++;
8824 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008825 }
Arun Menon906de572013-06-18 17:01:40 -07008826 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8827 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008828}
8829
8830void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8831{
Arun Menon906de572013-06-18 17:01:40 -07008832 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8833 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8834 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8835 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8836 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8837 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8838 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8839 *portDefn = m_port_def;
8840 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008841 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008842 portDefn->format.video.nFrameWidth,
8843 portDefn->format.video.nStride,
8844 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008845}
8846
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308847void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8848 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8849{
8850 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8851 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8852 DEBUG_PRINT_ERROR("frame packing size mismatch");
8853 return;
8854 }
8855 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8856 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8857 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8858 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8859 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8860 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8861 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8862 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8863 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8864 memcpy(&framepack->id, s3d_frame_packing_payload,
8865 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8866 memcpy(&m_frame_pack_arrangement, framepack,
8867 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8868 print_debug_extradata(extra);
8869}
8870
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008871void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8872 struct msm_vidc_frame_qp_payload *qp_payload)
8873{
8874 OMX_QCOM_EXTRADATA_QP * qp = NULL;
8875 if (!qp_payload) {
8876 DEBUG_PRINT_ERROR("QP payload is NULL");
8877 return;
8878 }
8879 extra->nSize = OMX_QP_EXTRADATA_SIZE;
8880 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8881 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8882 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
8883 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
8884 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8885 qp->nQP = qp_payload->frame_qp;
8886 print_debug_extradata(extra);
8887}
8888
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008889void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8890 struct msm_vidc_frame_bits_info_payload *bits_payload)
8891{
8892 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
8893 if (!bits_payload) {
8894 DEBUG_PRINT_ERROR("bits info payload is NULL");
8895 return;
8896 }
8897 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
8898 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8899 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8900 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
8901 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
8902 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
8903 bits->frame_bits = bits_payload->frame_bits;
8904 bits->header_bits = bits_payload->header_bits;
8905 print_debug_extradata(extra);
8906}
8907
Shalaj Jain273b3e02012-06-22 19:08:03 -07008908void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8909{
Arun Menon906de572013-06-18 17:01:40 -07008910 if (!client_extradata) {
8911 return;
8912 }
8913 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8914 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8915 extra->eType = OMX_ExtraDataNone;
8916 extra->nDataSize = 0;
8917 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008918
Arun Menon906de572013-06-18 17:01:40 -07008919 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008920}
8921
8922OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8923{
Arun Menon906de572013-06-18 17:01:40 -07008924 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8925 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008926 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008927 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008928 }
Arun Menon906de572013-06-18 17:01:40 -07008929 if (m_desc_buffer_ptr == NULL) {
8930 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8931 calloc( (sizeof(desc_buffer_hdr)),
8932 drv_ctx.ip_buf.actualcount);
8933 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008934 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008935 return OMX_ErrorInsufficientResources;
8936 }
8937 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008938
Arun Menon906de572013-06-18 17:01:40 -07008939 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8940 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008941 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008942 return OMX_ErrorInsufficientResources;
8943 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008944
Arun Menon906de572013-06-18 17:01:40 -07008945 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008946}
8947
8948void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8949{
Arun Menon906de572013-06-18 17:01:40 -07008950 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8951 if (m_demux_entries < 8192) {
8952 m_demux_offsets[m_demux_entries++] = address_offset;
8953 }
8954 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008955}
8956
8957void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8958{
Arun Menon906de572013-06-18 17:01:40 -07008959 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8960 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8961 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008962
Arun Menon906de572013-06-18 17:01:40 -07008963 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008964
Arun Menon906de572013-06-18 17:01:40 -07008965 while (index < bytes_to_parse) {
8966 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8967 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8968 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8969 (buf[index+2] == 0x01)) ) {
8970 //Found start code, insert address offset
8971 insert_demux_addr_offset(index);
8972 if (buf[index+2] == 0x01) // 3 byte start code
8973 index += 3;
8974 else //4 byte start code
8975 index += 4;
8976 } else
8977 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008978 }
Arun Menon906de572013-06-18 17:01:40 -07008979 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8980 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008981}
8982
8983OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8984{
Arun Menon906de572013-06-18 17:01:40 -07008985 //fix this, handle 3 byte start code, vc1 terminator entry
8986 OMX_U8 *p_demux_data = NULL;
8987 OMX_U32 desc_data = 0;
8988 OMX_U32 start_addr = 0;
8989 OMX_U32 nal_size = 0;
8990 OMX_U32 suffix_byte = 0;
8991 OMX_U32 demux_index = 0;
8992 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008993
Arun Menon906de572013-06-18 17:01:40 -07008994 if (m_desc_buffer_ptr == NULL) {
8995 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8996 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008997 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008998
Arun Menon906de572013-06-18 17:01:40 -07008999 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9000 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9001 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9002 return OMX_ErrorBadParameter;
9003 }
9004
9005 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9006
9007 if ( ((OMX_U8*)p_demux_data == NULL) ||
9008 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9009 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9010 return OMX_ErrorBadParameter;
9011 } else {
9012 for (; demux_index < m_demux_entries; demux_index++) {
9013 desc_data = 0;
9014 start_addr = m_demux_offsets[demux_index];
9015 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9016 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9017 } else {
9018 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9019 }
9020 if (demux_index < (m_demux_entries - 1)) {
9021 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9022 } else {
9023 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9024 }
9025 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9026 (void *)start_addr,
9027 suffix_byte,
9028 nal_size,
9029 demux_index);
9030 desc_data = (start_addr >> 3) << 1;
9031 desc_data |= (start_addr & 7) << 21;
9032 desc_data |= suffix_byte << 24;
9033
9034 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9035 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9036 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9037 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9038
9039 p_demux_data += 16;
9040 }
9041 if (codec_type_parse == CODEC_TYPE_VC1) {
9042 DEBUG_PRINT_LOW("VC1 terminator entry");
9043 desc_data = 0;
9044 desc_data = 0x82 << 24;
9045 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9046 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9047 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9048 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9049 p_demux_data += 16;
9050 m_demux_entries++;
9051 }
9052 //Add zero word to indicate end of descriptors
9053 memset(p_demux_data, 0, sizeof(OMX_U32));
9054
9055 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9056 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9057 }
9058 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9059 m_demux_entries = 0;
9060 DEBUG_PRINT_LOW("Demux table complete!");
9061 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009062}
9063
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009064OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009065{
Arun Menon906de572013-06-18 17:01:40 -07009066 OMX_ERRORTYPE err = OMX_ErrorNone;
9067 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9068 if (iDivXDrmDecrypt) {
9069 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9070 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009071 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009072 delete iDivXDrmDecrypt;
9073 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009074 }
9075 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009076 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009077 err = OMX_ErrorUndefined;
9078 }
9079 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009080}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009081
Vinay Kaliada4f4422013-01-09 10:45:03 -08009082omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9083{
Arun Menon906de572013-06-18 17:01:40 -07009084 enabled = false;
9085 omx = NULL;
9086 init_members();
9087 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009088}
9089
9090void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9091{
Arun Menon906de572013-06-18 17:01:40 -07009092 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009093}
9094
Arun Menon906de572013-06-18 17:01:40 -07009095void omx_vdec::allocate_color_convert_buf::init_members()
9096{
9097 allocated_count = 0;
9098 buffer_size_req = 0;
9099 buffer_alignment_req = 0;
9100 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9101 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9102 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9103 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009104#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009105 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009106#endif
Arun Menon906de572013-06-18 17:01:40 -07009107 for (int i = 0; i < MAX_COUNT; i++)
9108 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009109}
9110
Arun Menon906de572013-06-18 17:01:40 -07009111omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9112{
9113 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009114}
9115
9116bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9117{
Arun Menon906de572013-06-18 17:01:40 -07009118 bool status = true;
9119 unsigned int src_size = 0, destination_size = 0;
9120 OMX_COLOR_FORMATTYPE drv_color_format;
9121 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009122 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009123 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009124 }
Arun Menon906de572013-06-18 17:01:40 -07009125 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009126 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009127 return status;
9128 }
9129 pthread_mutex_lock(&omx->c_lock);
9130 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9131 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009132 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009133 status = false;
9134 goto fail_update_buf_req;
9135 }
9136 c2d.close();
9137 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9138 omx->drv_ctx.video_resolution.frame_width,
9139 NV12_128m,YCbCr420P);
9140 if (status) {
9141 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9142 if (status)
9143 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9144 }
9145 if (status) {
9146 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9147 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009148 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009149 "driver size %d destination size %d",
9150 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9151 status = false;
9152 c2d.close();
9153 buffer_size_req = 0;
9154 } else {
9155 buffer_size_req = destination_size;
9156 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9157 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9158 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9159 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9160 }
9161 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009162fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009163 pthread_mutex_unlock(&omx->c_lock);
9164 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009165}
9166
9167bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009168 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009169{
Arun Menon906de572013-06-18 17:01:40 -07009170 bool status = true;
9171 OMX_COLOR_FORMATTYPE drv_color_format;
9172 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009173 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009174 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009175 }
Arun Menon906de572013-06-18 17:01:40 -07009176 pthread_mutex_lock(&omx->c_lock);
9177 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9178 drv_color_format = (OMX_COLOR_FORMATTYPE)
9179 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9180 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009181 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009182 status = false;
9183 }
9184 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009185 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07009186 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009187 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009188 status = false;
9189 } else {
9190 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9191 if (enabled)
9192 c2d.destroy();
9193 enabled = false;
9194 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009195 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009196 status = false;
9197 } else
9198 enabled = true;
9199 }
9200 } else {
9201 if (enabled)
9202 c2d.destroy();
9203 enabled = false;
9204 }
9205 pthread_mutex_unlock(&omx->c_lock);
9206 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009207}
9208
9209OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9210{
Arun Menon906de572013-06-18 17:01:40 -07009211 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009212 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009213 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009214 }
Arun Menon906de572013-06-18 17:01:40 -07009215 if (!enabled)
9216 return omx->m_out_mem_ptr;
9217 return m_out_mem_ptr_client;
9218}
9219
9220 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9221(OMX_BUFFERHEADERTYPE *bufadd)
9222{
9223 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009224 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009225 return NULL;
9226 }
9227 if (!enabled)
9228 return bufadd;
9229
9230 unsigned index = 0;
9231 index = bufadd - omx->m_out_mem_ptr;
9232 if (index < omx->drv_ctx.op_buf.actualcount) {
9233 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9234 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9235 bool status;
9236 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9237 pthread_mutex_lock(&omx->c_lock);
9238 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9239 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9240 pmem_baseaddress[index], pmem_baseaddress[index]);
9241 pthread_mutex_unlock(&omx->c_lock);
9242 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9243 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009244 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009245 m_out_mem_ptr_client[index].nFilledLen = 0;
9246 return &m_out_mem_ptr_client[index];
9247 }
9248 } else
9249 m_out_mem_ptr_client[index].nFilledLen = 0;
9250 return &m_out_mem_ptr_client[index];
9251 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009252 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009253 return NULL;
9254}
9255
9256 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9257(OMX_BUFFERHEADERTYPE *bufadd)
9258{
9259 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009260 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009261 return NULL;
9262 }
9263 if (!enabled)
9264 return bufadd;
9265 unsigned index = 0;
9266 index = bufadd - m_out_mem_ptr_client;
9267 if (index < omx->drv_ctx.op_buf.actualcount) {
9268 return &omx->m_out_mem_ptr[index];
9269 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009270 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009271 return NULL;
9272}
9273 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9274(unsigned int &buffer_size)
9275{
9276 bool status = true;
9277 pthread_mutex_lock(&omx->c_lock);
9278 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009279 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009280 else {
9281 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009282 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009283 status = false;
9284 goto fail_get_buffer_size;
9285 }
9286 }
9287 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9288 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9289 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9290 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009291fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009292 pthread_mutex_unlock(&omx->c_lock);
9293 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009294}
9295OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009296 OMX_BUFFERHEADERTYPE *bufhdr)
9297{
9298 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009299
Arun Menon906de572013-06-18 17:01:40 -07009300 if (!enabled)
9301 return omx->free_output_buffer(bufhdr);
9302 if (enabled && omx->is_component_secure())
9303 return OMX_ErrorNone;
9304 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009305 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009306 return OMX_ErrorBadParameter;
9307 }
9308 index = bufhdr - m_out_mem_ptr_client;
9309 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009310 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009311 return OMX_ErrorBadParameter;
9312 }
9313 if (pmem_fd[index] > 0) {
9314 munmap(pmem_baseaddress[index], buffer_size_req);
9315 close(pmem_fd[index]);
9316 }
9317 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009318#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009319 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009320#endif
Arun Menon906de572013-06-18 17:01:40 -07009321 m_heap_ptr[index].video_heap_ptr = NULL;
9322 if (allocated_count > 0)
9323 allocated_count--;
9324 else
9325 allocated_count = 0;
9326 if (!allocated_count) {
9327 pthread_mutex_lock(&omx->c_lock);
9328 c2d.close();
9329 init_members();
9330 pthread_mutex_unlock(&omx->c_lock);
9331 }
9332 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009333}
9334
9335OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009336 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009337{
Arun Menon906de572013-06-18 17:01:40 -07009338 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9339 if (!enabled) {
9340 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9341 return eRet;
9342 }
9343 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009344 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009345 omx->is_component_secure());
9346 return OMX_ErrorUnsupportedSetting;
9347 }
9348 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009349 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9350 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009351 buffer_size_req,bytes);
9352 return OMX_ErrorBadParameter;
9353 }
9354 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009355 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009356 return OMX_ErrorInsufficientResources;
9357 }
9358 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9359 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9360 port,appData,omx->drv_ctx.op_buf.buffer_size);
9361 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009362 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009363 return eRet;
9364 }
9365 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309366 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009367 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009368 (temp_bufferHdr - omx->m_out_mem_ptr));
9369 return OMX_ErrorUndefined;
9370 }
9371 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009372#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009373 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9374 buffer_size_req,buffer_alignment_req,
9375 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9376 0);
9377 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9378 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009379 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009380 return OMX_ErrorInsufficientResources;
9381 }
9382 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9383 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009384
Arun Menon906de572013-06-18 17:01:40 -07009385 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009386 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009387 close(pmem_fd[i]);
9388 omx->free_ion_memory(&op_buf_ion_info[i]);
9389 return OMX_ErrorInsufficientResources;
9390 }
9391 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9392 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9393 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009394#endif
Arun Menon906de572013-06-18 17:01:40 -07009395 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9396 m_pmem_info_client[i].offset = 0;
9397 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9398 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9399 m_platform_list_client[i].nEntries = 1;
9400 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9401 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9402 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9403 m_out_mem_ptr_client[i].nFilledLen = 0;
9404 m_out_mem_ptr_client[i].nFlags = 0;
9405 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9406 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9407 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9408 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9409 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9410 m_out_mem_ptr_client[i].pAppPrivate = appData;
9411 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009412 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009413 allocated_count++;
9414 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009415}
9416
9417bool omx_vdec::is_component_secure()
9418{
Arun Menon906de572013-06-18 17:01:40 -07009419 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009420}
9421
9422bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9423{
Arun Menon906de572013-06-18 17:01:40 -07009424 bool status = true;
9425 if (!enabled) {
9426 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9427 dest_color_format = (OMX_COLOR_FORMATTYPE)
9428 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9429 else
9430 status = false;
9431 } else {
9432 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9433 status = false;
9434 } else
9435 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9436 }
9437 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009438}
Arun Menonbdb80b02013-08-12 17:45:54 -07009439
Arun Menonbdb80b02013-08-12 17:45:54 -07009440void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9441{
9442 int i = 0;
9443 bool buf_present = false;
9444 pthread_mutex_lock(&m_lock);
9445 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9446 //check the buffer fd, offset, uv addr with list contents
9447 //If present increment reference.
9448 if ((out_dynamic_list[i].fd == fd) &&
9449 (out_dynamic_list[i].offset == offset)) {
9450 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009451 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009452 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9453 buf_present = true;
9454 break;
9455 }
9456 }
9457 if (!buf_present) {
9458 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9459 //search for a entry to insert details of the new buffer
9460 if (out_dynamic_list[i].dup_fd == 0) {
9461 out_dynamic_list[i].fd = fd;
9462 out_dynamic_list[i].offset = offset;
9463 out_dynamic_list[i].dup_fd = dup(fd);
9464 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009465 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009466 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9467 break;
9468 }
9469 }
9470 }
9471 pthread_mutex_unlock(&m_lock);
9472}
9473
9474void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9475{
9476 int i = 0;
9477 pthread_mutex_lock(&m_lock);
9478 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9479 //check the buffer fd, offset, uv addr with list contents
9480 //If present decrement reference.
9481 if ((out_dynamic_list[i].fd == fd) &&
9482 (out_dynamic_list[i].offset == offset)) {
9483 out_dynamic_list[i].ref_count--;
9484 if (out_dynamic_list[i].ref_count == 0) {
9485 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009486 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009487 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9488 out_dynamic_list[i].dup_fd = 0;
9489 out_dynamic_list[i].fd = 0;
9490 out_dynamic_list[i].offset = 0;
9491 }
9492 break;
9493 }
9494 }
9495 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009496 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009497 }
9498 pthread_mutex_unlock(&m_lock);
9499}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009500
9501#ifdef _MSM8974_
9502void omx_vdec::send_codec_config() {
9503 if (codec_config_flag) {
9504 unsigned p1 = 0; // Parameter - 1
9505 unsigned p2 = 0; // Parameter - 2
9506 unsigned ident = 0;
9507 pthread_mutex_lock(&m_lock);
9508 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9509 while (m_etb_q.m_size) {
9510 m_etb_q.pop_entry(&p1,&p2,&ident);
9511 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9512 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9513 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9514 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9515 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9516 omx_report_error();
9517 }
9518 } else {
9519 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9520 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9521 }
9522 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9523 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9524 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9525 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9526 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9527 omx_report_error ();
9528 }
9529 } else {
9530 pending_input_buffers++;
9531 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9532 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9533 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9534 }
9535 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9536 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9537 (OMX_BUFFERHEADERTYPE *)p1);
9538 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9539 }
9540 }
9541 pthread_mutex_unlock(&m_lock);
9542 }
9543}
9544#endif