blob: 54e5d2088be5259a3da37326dcc0b3bc9049e4a3 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Maheshwar Ajja507d6552014-01-03 14:54:29 +05302Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080053#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070054
55#ifndef _ANDROID_
56#include <sys/ioctl.h>
57#include <sys/mman.h>
58#endif //_ANDROID_
59
60#ifdef _ANDROID_
61#include <cutils/properties.h>
62#undef USE_EGL_IMAGE_GPU
63#endif
64
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070065#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070066
67#ifdef _ANDROID_
68#include "DivXDrmDecrypt.h"
69#endif //_ANDROID_
70
Arun Menon45346052013-11-13 12:40:08 -080071#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070072#include "QComOMXMetadata.h"
73#endif
74
Shalaj Jain273b3e02012-06-22 19:08:03 -070075#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070081
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070082#define BUFFER_LOG_LOC "/data/misc/media"
83
Shalaj Jain273b3e02012-06-22 19:08:03 -070084#ifdef OUTPUT_EXTRADATA_LOG
85FILE *outputExtradataFile;
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -080086char output_extradata_filename [] = "/data/misc/extradata";
Shalaj Jain273b3e02012-06-22 19:08:03 -070087#endif
88
89#define DEFAULT_FPS 30
Shalaj Jain273b3e02012-06-22 19:08:03 -070090#define MAX_SUPPORTED_FPS 120
Deepak Vermaa2efdb12013-12-26 12:30:05 +053091#define DEFAULT_WIDTH_ALIGNMENT 128
92#define DEFAULT_HEIGHT_ALIGNMENT 32
Shalaj Jain273b3e02012-06-22 19:08:03 -070093
94#define VC1_SP_MP_START_CODE 0xC5000000
95#define VC1_SP_MP_START_CODE_MASK 0xFF000000
96#define VC1_AP_SEQ_START_CODE 0x0F010000
97#define VC1_STRUCT_C_PROFILE_MASK 0xF0
98#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
99#define VC1_SIMPLE_PROFILE 0
100#define VC1_MAIN_PROFILE 1
101#define VC1_ADVANCE_PROFILE 3
102#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
103#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
104#define VC1_STRUCT_C_LEN 4
105#define VC1_STRUCT_C_POS 8
106#define VC1_STRUCT_A_POS 12
107#define VC1_STRUCT_B_POS 24
108#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700109#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700110
111#define MEM_DEVICE "/dev/ion"
112#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
113
114#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700115extern "C" {
116#include<utils/Log.h>
117}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700118#endif//_ANDROID_
119
Vinay Kalia53fa6832012-10-11 17:55:30 -0700120#define SZ_4K 0x1000
121#define SZ_1M 0x100000
122
Shalaj Jain273b3e02012-06-22 19:08:03 -0700123#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
124#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700125#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
126
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800127#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800128#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700129
130int debug_level = PRIO_ERROR;
131
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530132static OMX_U32 maxSmoothStreamingWidth = 1920;
133static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800134
Shalaj Jain273b3e02012-06-22 19:08:03 -0700135void* async_message_thread (void *input)
136{
Arun Menon906de572013-06-18 17:01:40 -0700137 OMX_BUFFERHEADERTYPE *buffer;
138 struct v4l2_plane plane[VIDEO_MAX_PLANES];
139 struct pollfd pfd;
140 struct v4l2_buffer v4l2_buf;
141 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
142 struct v4l2_event dqevent;
143 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
144 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
145 pfd.fd = omx->drv_ctx.video_driver_fd;
146 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700147 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700148 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
149 while (1) {
150 rc = poll(&pfd, 1, POLL_TIMEOUT);
151 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700152 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700153 break;
154 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700155 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700156 break;
157 }
158 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
159 struct vdec_msginfo vdec_msg;
160 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
161 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
162 v4l2_buf.length = omx->drv_ctx.num_planes;
163 v4l2_buf.m.planes = plane;
164 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
165 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
166 vdec_msg.status_code=VDEC_S_SUCCESS;
167 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
168 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
169 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
170 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
171 (uint64_t)v4l2_buf.timestamp.tv_usec;
172 if (vdec_msg.msgdata.output_frame.len) {
173 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
174 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
175 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
176 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
177 }
178 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700179 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700180 break;
181 }
182 }
183 }
184 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
185 struct vdec_msginfo vdec_msg;
186 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
187 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
188 v4l2_buf.length = 1;
189 v4l2_buf.m.planes = plane;
190 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
191 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
192 vdec_msg.status_code=VDEC_S_SUCCESS;
193 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
194 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700195 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700196 break;
197 }
198 }
199 }
200 if (pfd.revents & POLLPRI) {
201 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
202 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
203 struct vdec_msginfo vdec_msg;
204 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
205 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700206 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700207 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700208 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700209 break;
210 }
211 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
212 struct vdec_msginfo vdec_msg;
213 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
214 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700215 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700216 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700217 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700218 break;
219 }
220 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
221 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700222 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700223 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700224 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700225 break;
226 }
227 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700228 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700229 break;
230 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
231 struct vdec_msginfo vdec_msg;
232 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
233 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700234 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700235 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700236 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700237 break;
238 }
Arun Menon45346052013-11-13 12:40:08 -0800239 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700240 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700241 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700242 omx->buf_ref_remove(ptr[0], ptr[1]);
243 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
244 unsigned int *ptr = (unsigned int *)dqevent.u.data;
245 struct vdec_msginfo vdec_msg;
246
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700247 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700248
249 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
250 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
251 v4l2_buf.length = omx->drv_ctx.num_planes;
252 v4l2_buf.m.planes = plane;
253 v4l2_buf.index = ptr[5];
254 v4l2_buf.flags = 0;
255
256 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
257 vdec_msg.status_code = VDEC_S_SUCCESS;
258 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
259 vdec_msg.msgdata.output_frame.len = 0;
260 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
261 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
262 (uint64_t)ptr[4];
263 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700264 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700265 break;
266 }
267 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700268 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700269 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700270 continue;
271 }
272 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700273 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700274 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700275 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700276}
277
278void* message_thread(void *input)
279{
Arun Menon906de572013-06-18 17:01:40 -0700280 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
281 unsigned char id;
282 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700283
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700284 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700285 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
286 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287
Arun Menon906de572013-06-18 17:01:40 -0700288 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700289
Arun Menon906de572013-06-18 17:01:40 -0700290 if (0 == n) {
291 break;
292 }
293
294 if (1 == n) {
295 omx->process_event_cb(omx, id);
296 }
297 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700298 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700299 break;
300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700301 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700302 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700303 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700304}
305
306void post_message(omx_vdec *omx, unsigned char id)
307{
Arun Menon906de572013-06-18 17:01:40 -0700308 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700309 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700310 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700311 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700312}
313
314// omx_cmd_queue destructor
315omx_vdec::omx_cmd_queue::~omx_cmd_queue()
316{
Arun Menon906de572013-06-18 17:01:40 -0700317 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700318}
319
320// omx cmd queue constructor
321omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
322{
323 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
324}
325
326// omx cmd queue insert
327bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
328{
Arun Menon906de572013-06-18 17:01:40 -0700329 bool ret = true;
330 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
331 m_q[m_write].id = id;
332 m_q[m_write].param1 = p1;
333 m_q[m_write].param2 = p2;
334 m_write++;
335 m_size ++;
336 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
337 m_write = 0;
338 }
339 } else {
340 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700341 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342 }
Arun Menon906de572013-06-18 17:01:40 -0700343 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700344}
345
346// omx cmd queue pop
347bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
348{
Arun Menon906de572013-06-18 17:01:40 -0700349 bool ret = true;
350 if (m_size > 0) {
351 *id = m_q[m_read].id;
352 *p1 = m_q[m_read].param1;
353 *p2 = m_q[m_read].param2;
354 // Move the read pointer ahead
355 ++m_read;
356 --m_size;
357 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
358 m_read = 0;
359 }
360 } else {
361 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700362 }
Arun Menon906de572013-06-18 17:01:40 -0700363 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700364}
365
366// Retrieve the first mesg type in the queue
367unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
368{
369 return m_q[m_read].id;
370}
371
372#ifdef _ANDROID_
373omx_vdec::ts_arr_list::ts_arr_list()
374{
Arun Menon906de572013-06-18 17:01:40 -0700375 //initialize timestamps array
376 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700377}
378omx_vdec::ts_arr_list::~ts_arr_list()
379{
Arun Menon906de572013-06-18 17:01:40 -0700380 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700381}
382
383bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
384{
Arun Menon906de572013-06-18 17:01:40 -0700385 bool ret = true;
386 bool duplicate_ts = false;
387 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700388
Arun Menon906de572013-06-18 17:01:40 -0700389 //insert at the first available empty location
390 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
391 if (!m_ts_arr_list[idx].valid) {
392 //found invalid or empty entry, save timestamp
393 m_ts_arr_list[idx].valid = true;
394 m_ts_arr_list[idx].timestamp = ts;
395 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
396 ts, idx);
397 break;
398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400
Arun Menon906de572013-06-18 17:01:40 -0700401 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
402 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
403 ret = false;
404 }
405 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700406}
407
408bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
409{
Arun Menon906de572013-06-18 17:01:40 -0700410 bool ret = true;
411 int min_idx = -1;
412 OMX_TICKS min_ts = 0;
413 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700416
Arun Menon906de572013-06-18 17:01:40 -0700417 if (m_ts_arr_list[idx].valid) {
418 //found valid entry, save index
419 if (min_idx < 0) {
420 //first valid entry
421 min_ts = m_ts_arr_list[idx].timestamp;
422 min_idx = idx;
423 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
424 min_ts = m_ts_arr_list[idx].timestamp;
425 min_idx = idx;
426 }
427 }
428
Shalaj Jain273b3e02012-06-22 19:08:03 -0700429 }
430
Arun Menon906de572013-06-18 17:01:40 -0700431 if (min_idx < 0) {
432 //no valid entries found
433 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
434 ts = 0;
435 ret = false;
436 } else {
437 ts = m_ts_arr_list[min_idx].timestamp;
438 m_ts_arr_list[min_idx].valid = false;
439 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
440 ts, min_idx);
441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442
Arun Menon906de572013-06-18 17:01:40 -0700443 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700444
445}
446
447
448bool omx_vdec::ts_arr_list::reset_ts_list()
449{
Arun Menon906de572013-06-18 17:01:40 -0700450 bool ret = true;
451 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700452
Arun Menon906de572013-06-18 17:01:40 -0700453 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
454 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
455 m_ts_arr_list[idx].valid = false;
456 }
457 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700458}
459#endif
460
461// factory function executed by the core to create instances
462void *get_omx_component_factory_fn(void)
463{
Arun Menon906de572013-06-18 17:01:40 -0700464 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700465}
466
467#ifdef _ANDROID_
468#ifdef USE_ION
469VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700470 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471{
Arun Menon906de572013-06-18 17:01:40 -0700472 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700473}
474#else
475VideoHeap::VideoHeap(int fd, size_t size, void* base)
476{
477 // dup file descriptor, map once, use pmem
478 init(dup(fd), base, size, 0 , MEM_DEVICE);
479}
480#endif
481#endif // _ANDROID_
482/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700483 FUNCTION
484 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700485
Arun Menon906de572013-06-18 17:01:40 -0700486 DESCRIPTION
487 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700488
Arun Menon906de572013-06-18 17:01:40 -0700489 PARAMETERS
490 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700491
Arun Menon906de572013-06-18 17:01:40 -0700492 RETURN VALUE
493 None.
494 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800495omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700496 m_state(OMX_StateInvalid),
497 m_app_data(NULL),
498 m_inp_mem_ptr(NULL),
499 m_out_mem_ptr(NULL),
Arun Menon906de572013-06-18 17:01:40 -0700500 input_flush_progress (false),
501 output_flush_progress (false),
502 input_use_buffer (false),
503 output_use_buffer (false),
504 ouput_egl_buffers(false),
505 m_use_output_pmem(OMX_FALSE),
506 m_out_mem_region_smi(OMX_FALSE),
507 m_out_pvt_entry_pmem(OMX_FALSE),
508 pending_input_buffers(0),
509 pending_output_buffers(0),
510 m_out_bm_count(0),
511 m_inp_bm_count(0),
512 m_inp_bPopulated(OMX_FALSE),
513 m_out_bPopulated(OMX_FALSE),
514 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700515#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700516 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700517#endif
Arun Menon906de572013-06-18 17:01:40 -0700518 m_inp_bEnabled(OMX_TRUE),
519 m_out_bEnabled(OMX_TRUE),
520 m_in_alloc_cnt(0),
521 m_platform_list(NULL),
522 m_platform_entry(NULL),
523 m_pmem_info(NULL),
524 arbitrary_bytes (true),
525 psource_frame (NULL),
526 pdest_frame (NULL),
527 m_inp_heap_ptr (NULL),
528 m_phdr_pmem_ptr(NULL),
529 m_heap_inp_bm_count (0),
530 codec_type_parse ((codec_type)0),
531 first_frame_meta (true),
532 frame_count (0),
533 nal_count (0),
534 nal_length(0),
535 look_ahead_nal (false),
536 first_frame(0),
537 first_buffer(NULL),
538 first_frame_size (0),
539 m_device_file_ptr(NULL),
540 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700541 h264_last_au_ts(LLONG_MAX),
542 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530543 m_disp_hor_size(0),
544 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700545 prev_ts(LLONG_MAX),
546 rst_prev_ts(true),
547 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700548 in_reconfig(false),
549 m_display_id(NULL),
550 h264_parser(NULL),
551 client_extradata(0),
552 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530553 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700554#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700555 m_enable_android_native_buffers(OMX_FALSE),
556 m_use_android_native_buffers(OMX_FALSE),
557 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700558#endif
Arun Menon906de572013-06-18 17:01:40 -0700559 m_desc_buffer_ptr(NULL),
560 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530561 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800562 client_set_fps(false),
563 m_last_rendered_TS(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700564{
Arun Menon906de572013-06-18 17:01:40 -0700565 /* Assumption is that , to begin with , we have all the frames with decoder */
566 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700567 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700568#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700569 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700570 property_get("vidc.debug.level", property_value, "0");
571 debug_level = atoi(property_value);
572 property_value[0] = '\0';
573
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700574 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
575
Arun Menon906de572013-06-18 17:01:40 -0700576 property_get("vidc.dec.debug.perf", property_value, "0");
577 perf_flag = atoi(property_value);
578 if (perf_flag) {
579 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
580 dec_time.start();
581 proc_frms = latency = 0;
582 }
583 prev_n_filled_len = 0;
584 property_value[0] = '\0';
585 property_get("vidc.dec.debug.ts", property_value, "0");
586 m_debug_timestamp = atoi(property_value);
587 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
588 if (m_debug_timestamp) {
589 time_stamp_dts.set_timestamp_reorder_mode(true);
590 time_stamp_dts.enable_debug_print(true);
591 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700592
Arun Menon906de572013-06-18 17:01:40 -0700593 property_value[0] = '\0';
594 property_get("vidc.dec.debug.concealedmb", property_value, "0");
595 m_debug_concealedmb = atoi(property_value);
596 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700597
Arun Menon906de572013-06-18 17:01:40 -0700598 property_value[0] = '\0';
599 property_get("vidc.dec.profile.check", property_value, "0");
600 m_reject_avc_1080p_mp = atoi(property_value);
601 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530602
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700603 property_value[0] = '\0';
604 property_get("vidc.dec.log.in", property_value, "0");
605 m_debug.in_buffer_log = atoi(property_value);
606
607 property_value[0] = '\0';
608 property_get("vidc.dec.log.out", property_value, "0");
609 m_debug.out_buffer_log = atoi(property_value);
610 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
611
612 property_value[0] = '\0';
613 property_get("vidc.log.loc", property_value, "");
614 if (*property_value)
615 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800616
617 property_value[0] = '\0';
618 property_get("vidc.dec.120fps.enabled", property_value, "0");
619
620 //if this feature is not enabled then reset this value -ve
621 if(atoi(property_value)) {
622 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
623 m_last_rendered_TS = 0;
624 }
625
Shalaj Jain273b3e02012-06-22 19:08:03 -0700626#endif
Arun Menon906de572013-06-18 17:01:40 -0700627 memset(&m_cmp,0,sizeof(m_cmp));
628 memset(&m_cb,0,sizeof(m_cb));
629 memset (&drv_ctx,0,sizeof(drv_ctx));
630 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
631 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
632 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
633 m_demux_entries = 0;
634 msg_thread_id = 0;
635 async_thread_id = 0;
636 msg_thread_created = false;
637 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700638#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700639 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700640#endif
Arun Menon906de572013-06-18 17:01:40 -0700641 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530642 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700643 drv_ctx.timestamp_adjust = false;
644 drv_ctx.video_driver_fd = -1;
645 m_vendor_config.pData = NULL;
646 pthread_mutex_init(&m_lock, NULL);
647 pthread_mutex_init(&c_lock, NULL);
648 sem_init(&m_cmd_lock,0,0);
649 streaming[CAPTURE_PORT] =
650 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700651#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700652 char extradata_value[PROPERTY_VALUE_MAX] = {0};
653 property_get("vidc.dec.debug.extradata", extradata_value, "0");
654 m_debug_extradata = atoi(extradata_value);
655 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700656#endif
Arun Menon906de572013-06-18 17:01:40 -0700657 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
658 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700659 dynamic_buf_mode = false;
660 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800661 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800662 m_smoothstreaming_mode = false;
663 m_smoothstreaming_width = 0;
664 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530665 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700666}
667
Vinay Kalia85793762012-06-14 19:12:34 -0700668static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700669 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
670 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
671 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700672 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
673 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700674 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
675 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700676};
677
678static OMX_ERRORTYPE subscribe_to_events(int fd)
679{
Arun Menon906de572013-06-18 17:01:40 -0700680 OMX_ERRORTYPE eRet = OMX_ErrorNone;
681 struct v4l2_event_subscription sub;
682 int array_sz = sizeof(event_type)/sizeof(int);
683 int i,rc;
684 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700685 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700686 return OMX_ErrorBadParameter;
687 }
Vinay Kalia85793762012-06-14 19:12:34 -0700688
Arun Menon906de572013-06-18 17:01:40 -0700689 for (i = 0; i < array_sz; ++i) {
690 memset(&sub, 0, sizeof(sub));
691 sub.type = event_type[i];
692 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
693 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700694 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700695 break;
696 }
697 }
698 if (i < array_sz) {
699 for (--i; i >=0 ; i--) {
700 memset(&sub, 0, sizeof(sub));
701 sub.type = event_type[i];
702 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
703 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700704 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700705 }
706 eRet = OMX_ErrorNotImplemented;
707 }
708 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700709}
710
711
712static OMX_ERRORTYPE unsubscribe_to_events(int fd)
713{
Arun Menon906de572013-06-18 17:01:40 -0700714 OMX_ERRORTYPE eRet = OMX_ErrorNone;
715 struct v4l2_event_subscription sub;
716 int array_sz = sizeof(event_type)/sizeof(int);
717 int i,rc;
718 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700719 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700720 return OMX_ErrorBadParameter;
721 }
Vinay Kalia85793762012-06-14 19:12:34 -0700722
Arun Menon906de572013-06-18 17:01:40 -0700723 for (i = 0; i < array_sz; ++i) {
724 memset(&sub, 0, sizeof(sub));
725 sub.type = event_type[i];
726 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
727 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700728 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700729 break;
730 }
731 }
732 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700733}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700734
735/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700736 FUNCTION
737 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700738
Arun Menon906de572013-06-18 17:01:40 -0700739 DESCRIPTION
740 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700741
Arun Menon906de572013-06-18 17:01:40 -0700742 PARAMETERS
743 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700744
Arun Menon906de572013-06-18 17:01:40 -0700745 RETURN VALUE
746 None.
747 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700748omx_vdec::~omx_vdec()
749{
Arun Menon906de572013-06-18 17:01:40 -0700750 m_pmem_info = NULL;
751 struct v4l2_decoder_cmd dec;
752 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
753 if (m_pipe_in) close(m_pipe_in);
754 if (m_pipe_out) close(m_pipe_out);
755 m_pipe_in = -1;
756 m_pipe_out = -1;
757 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
758 if (msg_thread_created)
759 pthread_join(msg_thread_id,NULL);
760 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
761 dec.cmd = V4L2_DEC_CMD_STOP;
762 if (drv_ctx.video_driver_fd >=0 ) {
763 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700764 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700765 }
766 if (async_thread_created)
767 pthread_join(async_thread_id,NULL);
768 unsubscribe_to_events(drv_ctx.video_driver_fd);
769 close(drv_ctx.video_driver_fd);
770 pthread_mutex_destroy(&m_lock);
771 pthread_mutex_destroy(&c_lock);
772 sem_destroy(&m_cmd_lock);
773 if (perf_flag) {
774 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
775 dec_time.end();
776 }
777 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700778}
779
Arun Menon906de572013-06-18 17:01:40 -0700780int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
781{
782 struct v4l2_requestbuffers bufreq;
783 int rc = 0;
784 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
785 bufreq.memory = V4L2_MEMORY_USERPTR;
786 bufreq.count = 0;
787 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
788 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530789 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
790 bufreq.memory = V4L2_MEMORY_USERPTR;
791 bufreq.count = 0;
792 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
793 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700794 }
795 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700796}
797
Shalaj Jain273b3e02012-06-22 19:08:03 -0700798/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700799 FUNCTION
800 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700801
Arun Menon906de572013-06-18 17:01:40 -0700802 DESCRIPTION
803 IL Client callbacks are generated through this routine. The decoder
804 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700805
Arun Menon906de572013-06-18 17:01:40 -0700806 PARAMETERS
807 ctxt -- Context information related to the self.
808 id -- Event identifier. This could be any of the following:
809 1. Command completion event
810 2. Buffer done callback event
811 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700812
Arun Menon906de572013-06-18 17:01:40 -0700813 RETURN VALUE
814 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700815
Arun Menon906de572013-06-18 17:01:40 -0700816 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700817void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
818{
Arun Menon906de572013-06-18 17:01:40 -0700819 signed p1; // Parameter - 1
820 signed p2; // Parameter - 2
821 unsigned ident;
822 unsigned qsize=0; // qsize
823 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700824
Arun Menon906de572013-06-18 17:01:40 -0700825 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700826 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700827 __func__);
828 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700829 }
830
Arun Menon906de572013-06-18 17:01:40 -0700831 // Protect the shared queue data structure
832 do {
833 /*Read the message id's from the queue*/
834 pthread_mutex_lock(&pThis->m_lock);
835 qsize = pThis->m_cmd_q.m_size;
836 if (qsize) {
837 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700838 }
Arun Menon906de572013-06-18 17:01:40 -0700839
840 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
841 qsize = pThis->m_ftb_q.m_size;
842 if (qsize) {
843 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
844 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700845 }
Arun Menon906de572013-06-18 17:01:40 -0700846
847 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
848 qsize = pThis->m_etb_q.m_size;
849 if (qsize) {
850 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
851 }
852 }
853 pthread_mutex_unlock(&pThis->m_lock);
854
855 /*process message if we have one*/
856 if (qsize > 0) {
857 id = ident;
858 switch (id) {
859 case OMX_COMPONENT_GENERATE_EVENT:
860 if (pThis->m_cb.EventHandler) {
861 switch (p1) {
862 case OMX_CommandStateSet:
863 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700864 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700865 pThis->m_state);
866 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
867 OMX_EventCmdComplete, p1, p2, NULL);
868 break;
869
870 case OMX_EventError:
871 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700872 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700873 pThis->m_state = (OMX_STATETYPE) p2;
874 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
875 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
876 } else if (p2 == OMX_ErrorHardware) {
877 pThis->omx_report_error();
878 } else {
879 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
880 OMX_EventError, p2, (OMX_U32)NULL, NULL );
881 }
882 break;
883
884 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700885 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700886 if (BITMASK_PRESENT(&pThis->m_flags,
887 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
888 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
889 break;
890 }
891 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
892 OMX_ERRORTYPE eRet = OMX_ErrorNone;
893 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
894 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700895 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700896 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
897 pThis->in_reconfig = false;
898 if (eRet != OMX_ErrorNone) {
899 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
900 pThis->omx_report_error();
901 break;
902 }
903 }
904 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
905 OMX_EventCmdComplete, p1, p2, NULL );
906 break;
907 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700908 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700909 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
910 OMX_EventCmdComplete, p1, p2, NULL );
911 break;
912
913 default:
914 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
915 OMX_EventCmdComplete, p1, p2, NULL );
916 break;
917
918 }
919 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700920 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700921 }
922 break;
923 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
924 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
925 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700926 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700927 pThis->omx_report_error ();
928 }
929 break;
930 case OMX_COMPONENT_GENERATE_ETB:
931 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
932 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700933 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700934 pThis->omx_report_error ();
935 }
936 break;
937
938 case OMX_COMPONENT_GENERATE_FTB:
939 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
940 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700941 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700942 pThis->omx_report_error ();
943 }
944 break;
945
946 case OMX_COMPONENT_GENERATE_COMMAND:
947 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
948 (OMX_U32)p2,(OMX_PTR)NULL);
949 break;
950
951 case OMX_COMPONENT_GENERATE_EBD:
952
953 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700954 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700955 pThis->omx_report_error ();
956 } else {
957 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
Arun Menon906de572013-06-18 17:01:40 -0700958 pThis->time_stamp_dts.remove_time_stamp(
959 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
960 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
961 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -0700962 }
Deva Ramasubramanian02b0d882014-04-03 14:58:50 -0700963
Arun Menon906de572013-06-18 17:01:40 -0700964 if ( pThis->empty_buffer_done(&pThis->m_cmp,
965 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700966 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700967 pThis->omx_report_error ();
968 }
Arun Menon906de572013-06-18 17:01:40 -0700969 }
970 break;
971 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
972 int64_t *timestamp = (int64_t *)p1;
973 if (p1) {
974 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
975 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
976 ?true:false);
977 free(timestamp);
978 }
979 }
980 break;
981 case OMX_COMPONENT_GENERATE_FBD:
982 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700983 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700984 pThis->omx_report_error ();
985 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
986 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700987 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700988 pThis->omx_report_error ();
989 }
990 break;
991
992 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700993 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -0700994 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700995 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -0700996 } else {
997 pThis->execute_input_flush();
998 if (pThis->m_cb.EventHandler) {
999 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001000 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001001 pThis->omx_report_error ();
1002 } else {
1003 /*Check if we need generate event for Flush done*/
1004 if (BITMASK_PRESENT(&pThis->m_flags,
1005 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1006 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001007 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001008 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1009 OMX_EventCmdComplete,OMX_CommandFlush,
1010 OMX_CORE_INPUT_PORT_INDEX,NULL );
1011 }
1012 if (BITMASK_PRESENT(&pThis->m_flags,
1013 OMX_COMPONENT_IDLE_PENDING)) {
1014 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001015 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001016 pThis->omx_report_error ();
1017 } else {
1018 pThis->streaming[OUTPUT_PORT] = false;
1019 }
1020 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001021 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001022 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1023 OMX_COMPONENT_GENERATE_STOP_DONE);
1024 }
1025 }
1026 }
1027 } else {
1028 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1029 }
1030 }
1031 break;
1032
1033 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001034 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001035 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001036 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001037 } else {
1038 pThis->execute_output_flush();
1039 if (pThis->m_cb.EventHandler) {
1040 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001041 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001042 pThis->omx_report_error ();
1043 } else {
1044 /*Check if we need generate event for Flush done*/
1045 if (BITMASK_PRESENT(&pThis->m_flags,
1046 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001047 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001048 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1049 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1050 OMX_EventCmdComplete,OMX_CommandFlush,
1051 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1052 }
1053 if (BITMASK_PRESENT(&pThis->m_flags,
1054 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001055 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001056 BITMASK_CLEAR (&pThis->m_flags,
1057 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1058 if (BITMASK_PRESENT(&pThis->m_flags,
1059 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1060 pThis->post_event(OMX_CommandPortDisable,
1061 OMX_CORE_OUTPUT_PORT_INDEX,
1062 OMX_COMPONENT_GENERATE_EVENT);
1063 BITMASK_CLEAR (&pThis->m_flags,
1064 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001065 BITMASK_CLEAR (&pThis->m_flags,
1066 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001067
1068 }
1069 }
1070
1071 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1072 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001073 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001074 pThis->omx_report_error ();
1075 break;
1076 }
1077 pThis->streaming[CAPTURE_PORT] = false;
1078 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001079 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001080 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1081 OMX_COMPONENT_GENERATE_STOP_DONE);
1082 }
1083 }
1084 }
1085 } else {
1086 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1087 }
1088 }
1089 break;
1090
1091 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001092 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001093
1094 if (pThis->m_cb.EventHandler) {
1095 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001096 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001097 pThis->omx_report_error ();
1098 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001099 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001100 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001101 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001102 // Send the callback now
1103 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1104 pThis->m_state = OMX_StateExecuting;
1105 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1106 OMX_EventCmdComplete,OMX_CommandStateSet,
1107 OMX_StateExecuting, NULL);
1108 } else if (BITMASK_PRESENT(&pThis->m_flags,
1109 OMX_COMPONENT_PAUSE_PENDING)) {
1110 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1111 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001112 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001113 pThis->omx_report_error ();
1114 }
1115 }
1116 }
1117 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001118 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001119 }
1120 break;
1121
1122 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001123 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001124 if (pThis->m_cb.EventHandler) {
1125 if (p2 != VDEC_S_SUCCESS) {
1126 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1127 pThis->omx_report_error ();
1128 } else {
1129 pThis->complete_pending_buffer_done_cbs();
1130 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001131 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001132 //Send the callback now
1133 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1134 pThis->m_state = OMX_StatePause;
1135 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1136 OMX_EventCmdComplete,OMX_CommandStateSet,
1137 OMX_StatePause, NULL);
1138 }
1139 }
1140 } else {
1141 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1142 }
1143
1144 break;
1145
1146 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001147 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001148 if (pThis->m_cb.EventHandler) {
1149 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001150 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001151 pThis->omx_report_error ();
1152 } else {
1153 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001154 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001155 // Send the callback now
1156 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1157 pThis->m_state = OMX_StateExecuting;
1158 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1159 OMX_EventCmdComplete,OMX_CommandStateSet,
1160 OMX_StateExecuting,NULL);
1161 }
1162 }
1163 } else {
1164 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1165 }
1166
1167 break;
1168
1169 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001170 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001171 if (pThis->m_cb.EventHandler) {
1172 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001173 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001174 pThis->omx_report_error ();
1175 } else {
1176 pThis->complete_pending_buffer_done_cbs();
1177 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001178 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001179 // Send the callback now
1180 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1181 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001182 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001183 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1184 OMX_EventCmdComplete,OMX_CommandStateSet,
1185 OMX_StateIdle,NULL);
1186 }
1187 }
1188 } else {
1189 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1190 }
1191
1192 break;
1193
1194 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001195 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001196
1197 if (p2 == OMX_IndexParamPortDefinition) {
1198 pThis->in_reconfig = true;
1199 }
1200 if (pThis->m_cb.EventHandler) {
1201 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1202 OMX_EventPortSettingsChanged, p1, p2, NULL );
1203 } else {
1204 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1205 }
1206
Arun Menon906de572013-06-18 17:01:40 -07001207 break;
1208
1209 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001210 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001211 if (pThis->m_cb.EventHandler) {
1212 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1213 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1214 } else {
1215 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1216 }
1217 pThis->prev_ts = LLONG_MAX;
1218 pThis->rst_prev_ts = true;
1219 break;
1220
1221 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001222 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001223 pThis->omx_report_error ();
1224 break;
1225
1226 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001227 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001228 pThis->omx_report_unsupported_setting();
1229 break;
1230
Arun Menon906de572013-06-18 17:01:40 -07001231 default:
1232 break;
1233 }
1234 }
1235 pthread_mutex_lock(&pThis->m_lock);
1236 qsize = pThis->m_cmd_q.m_size;
1237 if (pThis->m_state != OMX_StatePause)
1238 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1239 pthread_mutex_unlock(&pThis->m_lock);
1240 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001241
1242}
1243
Vinay Kaliab9e98102013-04-02 19:31:43 -07001244int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245{
Arun Menon906de572013-06-18 17:01:40 -07001246 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301247 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1248 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001249 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001250 width, drv_ctx.video_resolution.frame_width,
1251 height,drv_ctx.video_resolution.frame_height);
1252 format_changed = 1;
1253 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001254 drv_ctx.video_resolution.frame_height = height;
1255 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001256 drv_ctx.video_resolution.scan_lines = scan_lines;
1257 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001258 rectangle.nLeft = 0;
1259 rectangle.nTop = 0;
1260 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1261 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001262 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001263}
1264
Arun Menon6836ba02013-02-19 20:37:40 -08001265OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1266{
Arun Menon906de572013-06-18 17:01:40 -07001267 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1268 OMX_MAX_STRINGNAME_SIZE) &&
1269 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1270 m_decoder_capability.max_width = 1280;
1271 m_decoder_capability.max_height = 720;
1272 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1273 }
Arun Menon888aa852013-05-30 11:24:42 -07001274
Arun Menon906de572013-06-18 17:01:40 -07001275 if ((drv_ctx.video_resolution.frame_width *
1276 drv_ctx.video_resolution.frame_height >
1277 m_decoder_capability.max_width *
1278 m_decoder_capability.max_height) ||
1279 (drv_ctx.video_resolution.frame_width*
1280 drv_ctx.video_resolution.frame_height <
1281 m_decoder_capability.min_width *
1282 m_decoder_capability.min_height)) {
1283 DEBUG_PRINT_ERROR(
1284 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
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 m_decoder_capability.max_width,
1290 m_decoder_capability.max_height);
1291 return OMX_ErrorUnsupportedSetting;
1292 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001293 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001294 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001295}
1296
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001297int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1298{
1299 if (m_debug.in_buffer_log && !m_debug.infile) {
1300 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1301 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1302 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1303 }
1304 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1305 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); }
1306 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1307 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
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.avc", OMX_MAX_STRINGNAME_SIZE)) {
1311 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1312 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1313 }
1314 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1315 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1316 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1317 }
1318 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1319 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1320 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1321 }
1322 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1323 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1324 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1325 }
1326 m_debug.infile = fopen (m_debug.infile_name, "ab");
1327 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001328 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001329 m_debug.infile_name[0] = '\0';
1330 return -1;
1331 }
1332 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1333 struct ivf_file_header {
1334 OMX_U8 signature[4]; //='DKIF';
1335 OMX_U8 version ; //= 0;
1336 OMX_U8 headersize ; //= 32;
1337 OMX_U32 FourCC;
1338 OMX_U8 width;
1339 OMX_U8 height;
1340 OMX_U32 rate;
1341 OMX_U32 scale;
1342 OMX_U32 length;
1343 OMX_U8 unused[4];
1344 } file_header;
1345
1346 memset((void *)&file_header,0,sizeof(file_header));
1347 file_header.signature[0] = 'D';
1348 file_header.signature[1] = 'K';
1349 file_header.signature[2] = 'I';
1350 file_header.signature[3] = 'F';
1351 file_header.version = 0;
1352 file_header.headersize = 32;
1353 file_header.FourCC = 0x30385056;
1354 fwrite((const char *)&file_header,
1355 sizeof(file_header),1,m_debug.infile);
1356 }
1357 }
1358 if (m_debug.infile && buffer_addr && buffer_len) {
1359 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1360 struct vp8_ivf_frame_header {
1361 OMX_U32 framesize;
1362 OMX_U32 timestamp_lo;
1363 OMX_U32 timestamp_hi;
1364 } vp8_frame_header;
1365 vp8_frame_header.framesize = buffer_len;
1366 /* Currently FW doesn't use timestamp values */
1367 vp8_frame_header.timestamp_lo = 0;
1368 vp8_frame_header.timestamp_hi = 0;
1369 fwrite((const char *)&vp8_frame_header,
1370 sizeof(vp8_frame_header),1,m_debug.infile);
1371 }
1372 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1373 }
1374 return 0;
1375}
1376
1377int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1378 if (m_debug.out_buffer_log && !m_debug.outfile) {
1379 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1380 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1381 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1382 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001383 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001384 m_debug.outfile_name[0] = '\0';
1385 return -1;
1386 }
1387 }
1388 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1389 int buf_index = buffer - m_out_mem_ptr;
1390 int stride = drv_ctx.video_resolution.stride;
1391 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301392 if (m_smoothstreaming_mode) {
1393 stride = drv_ctx.video_resolution.frame_width;
1394 scanlines = drv_ctx.video_resolution.frame_height;
1395 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1396 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1397 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001398 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1399 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301400 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1401 drv_ctx.video_resolution.frame_width,
1402 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001403 int bytes_written = 0;
1404 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1405 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1406 temp += stride;
1407 }
1408 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1409 int stride_c = stride;
1410 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1411 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1412 temp += stride_c;
1413 }
1414 }
1415 return 0;
1416}
1417
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001419 FUNCTION
1420 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001421
Arun Menon906de572013-06-18 17:01:40 -07001422 DESCRIPTION
1423 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001424
Arun Menon906de572013-06-18 17:01:40 -07001425 PARAMETERS
1426 ctxt -- Context information related to the self.
1427 id -- Event identifier. This could be any of the following:
1428 1. Command completion event
1429 2. Buffer done callback event
1430 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001431
Arun Menon906de572013-06-18 17:01:40 -07001432 RETURN VALUE
1433 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001434
Arun Menon906de572013-06-18 17:01:40 -07001435 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001436OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1437{
1438
Arun Menon906de572013-06-18 17:01:40 -07001439 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1440 struct v4l2_fmtdesc fdesc;
1441 struct v4l2_format fmt;
1442 struct v4l2_requestbuffers bufreq;
1443 struct v4l2_control control;
1444 struct v4l2_frmsizeenum frmsize;
1445 unsigned int alignment = 0,buffer_size = 0;
1446 int fds[2];
1447 int r,ret=0;
1448 bool codec_ambiguous = false;
1449 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001450 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001451
1452#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001453 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001454 property_get("ro.board.platform", platform_name, "0");
1455 if (!strncmp(platform_name, "msm8610", 7)) {
1456 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301457 is_q6_platform = true;
1458 maxSmoothStreamingWidth = 1280;
1459 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001460 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001461#endif
1462
Arun Menon906de572013-06-18 17:01:40 -07001463 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1464 struct v4l2_control control;
1465 secure_mode = true;
1466 arbitrary_bytes = false;
1467 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301468 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1469 OMX_MAX_STRINGNAME_SIZE)){
1470 secure_mode = true;
1471 arbitrary_bytes = false;
1472 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001473 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001474
Arun Menon906de572013-06-18 17:01:40 -07001475 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001476
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001477 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001478 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001479
Arun Menon906de572013-06-18 17:01:40 -07001480 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001481 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001482 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1483 close(0);
1484 }
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::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001488 return OMX_ErrorInsufficientResources;
1489 }
1490 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1491 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001492
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001493 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001494 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001495 async_thread_created = true;
1496 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1497 }
1498 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001499 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001500 async_thread_created = false;
1501 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001502 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001503
Shalaj Jain273b3e02012-06-22 19:08:03 -07001504#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001505 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001506#endif
1507
Arun Menon906de572013-06-18 17:01:40 -07001508 // Copy the role information which provides the decoder kind
1509 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001510
Arun Menon906de572013-06-18 17:01:40 -07001511 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1512 OMX_MAX_STRINGNAME_SIZE)) {
1513 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1514 OMX_MAX_STRINGNAME_SIZE);
1515 drv_ctx.timestamp_adjust = true;
1516 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1517 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1518 output_capability=V4L2_PIX_FMT_MPEG4;
1519 /*Initialize Start Code for MPEG4*/
1520 codec_type_parse = CODEC_TYPE_MPEG4;
1521 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001522 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1523 OMX_MAX_STRINGNAME_SIZE)) {
1524 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1525 OMX_MAX_STRINGNAME_SIZE);
1526 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1527 output_capability = V4L2_PIX_FMT_MPEG2;
1528 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1529 /*Initialize Start Code for MPEG2*/
1530 codec_type_parse = CODEC_TYPE_MPEG2;
1531 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001532 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1533 OMX_MAX_STRINGNAME_SIZE)) {
1534 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001535 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001536 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1537 eCompressionFormat = OMX_VIDEO_CodingH263;
1538 output_capability = V4L2_PIX_FMT_H263;
1539 codec_type_parse = CODEC_TYPE_H263;
1540 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001541 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1542 OMX_MAX_STRINGNAME_SIZE)) {
1543 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001544 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001545 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1546 output_capability = V4L2_PIX_FMT_DIVX_311;
1547 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1548 codec_type_parse = CODEC_TYPE_DIVX;
1549 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001550
Arun Menon906de572013-06-18 17:01:40 -07001551 eRet = createDivxDrmContext();
1552 if (eRet != OMX_ErrorNone) {
1553 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1554 return eRet;
1555 }
1556 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1557 OMX_MAX_STRINGNAME_SIZE)) {
1558 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001559 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001560 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1561 output_capability = V4L2_PIX_FMT_DIVX;
1562 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1563 codec_type_parse = CODEC_TYPE_DIVX;
1564 codec_ambiguous = true;
1565 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001566
Arun Menon906de572013-06-18 17:01:40 -07001567 eRet = createDivxDrmContext();
1568 if (eRet != OMX_ErrorNone) {
1569 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1570 return eRet;
1571 }
1572 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1573 OMX_MAX_STRINGNAME_SIZE)) {
1574 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001575 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001576 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1577 output_capability = V4L2_PIX_FMT_DIVX;
1578 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1579 codec_type_parse = CODEC_TYPE_DIVX;
1580 codec_ambiguous = true;
1581 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001582
Arun Menon906de572013-06-18 17:01:40 -07001583 eRet = createDivxDrmContext();
1584 if (eRet != OMX_ErrorNone) {
1585 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1586 return eRet;
1587 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001588
Arun Menon906de572013-06-18 17:01:40 -07001589 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1590 OMX_MAX_STRINGNAME_SIZE)) {
1591 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1592 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1593 output_capability=V4L2_PIX_FMT_H264;
1594 eCompressionFormat = OMX_VIDEO_CodingAVC;
1595 codec_type_parse = CODEC_TYPE_H264;
1596 m_frame_parser.init_start_codes (codec_type_parse);
1597 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001598 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1599 OMX_MAX_STRINGNAME_SIZE)) {
1600 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1601 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1602 eCompressionFormat = OMX_VIDEO_CodingWMV;
1603 codec_type_parse = CODEC_TYPE_VC1;
1604 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1605 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001606 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1607 OMX_MAX_STRINGNAME_SIZE)) {
1608 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1609 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1610 eCompressionFormat = OMX_VIDEO_CodingWMV;
1611 codec_type_parse = CODEC_TYPE_VC1;
1612 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1613 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001614 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1615 OMX_MAX_STRINGNAME_SIZE)) {
1616 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1617 output_capability=V4L2_PIX_FMT_VP8;
1618 eCompressionFormat = OMX_VIDEO_CodingVPX;
1619 codec_type_parse = CODEC_TYPE_VP8;
1620 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001621
Arun Menon906de572013-06-18 17:01:40 -07001622 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001623 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001624 eRet = OMX_ErrorInvalidComponentName;
1625 }
Arun Menon906de572013-06-18 17:01:40 -07001626 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001627
Arun Menon906de572013-06-18 17:01:40 -07001628 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001629 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1630 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1631 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001632 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001633 eRet = OMX_ErrorInsufficientResources;
1634 }
1635
Arun Menon906de572013-06-18 17:01:40 -07001636 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637
Arun Menon906de572013-06-18 17:01:40 -07001638 struct v4l2_capability cap;
1639 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1640 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001641 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001642 /*TODO: How to handle this case */
1643 } else {
1644 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001645 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001646 cap.bus_info, cap.version, cap.capabilities);
1647 }
1648 ret=0;
1649 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1650 fdesc.index=0;
1651 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001652 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001653 fdesc.pixelformat, fdesc.flags);
1654 fdesc.index++;
1655 }
1656 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1657 fdesc.index=0;
1658 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001659
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001660 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001661 fdesc.pixelformat, fdesc.flags);
1662 fdesc.index++;
1663 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001664 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001665 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1666 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1667 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1668 fmt.fmt.pix_mp.pixelformat = output_capability;
1669 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1670 if (ret) {
1671 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001672 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001673 return OMX_ErrorInsufficientResources;
1674 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001675 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001676 if (codec_ambiguous) {
1677 if (output_capability == V4L2_PIX_FMT_DIVX) {
1678 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001679
Arun Menon906de572013-06-18 17:01:40 -07001680 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1681 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1682 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1683 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1684 } else {
1685 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1686 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001687
Arun Menon906de572013-06-18 17:01:40 -07001688 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1689 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1690 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001691 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001692 }
1693 } else {
1694 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1695 }
1696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001697
Jia Meng3a3c6492013-12-19 17:16:52 +08001698 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1699 m_conceal_color= atoi(property_value);
1700 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1701 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1702 control.value = m_conceal_color;
1703 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1704 if (ret) {
1705 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1706 }
1707
Arun Menon906de572013-06-18 17:01:40 -07001708 //Get the hardware capabilities
1709 memset((void *)&frmsize,0,sizeof(frmsize));
1710 frmsize.index = 0;
1711 frmsize.pixel_format = output_capability;
1712 ret = ioctl(drv_ctx.video_driver_fd,
1713 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1714 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001715 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001716 return OMX_ErrorHardware;
1717 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001718
Arun Menon906de572013-06-18 17:01:40 -07001719 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1720 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1721 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1722 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1723 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1724 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001725
Arun Menon906de572013-06-18 17:01:40 -07001726 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1727 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1728 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1729 fmt.fmt.pix_mp.pixelformat = capture_capability;
1730 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1731 if (ret) {
1732 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001733 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001734 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001735 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001736 if (secure_mode) {
1737 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1738 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001739 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001740 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1741 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001742 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001743 return OMX_ErrorInsufficientResources;
1744 }
1745 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001746
Arun Menon906de572013-06-18 17:01:40 -07001747 /*Get the Buffer requirements for input and output ports*/
1748 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1749 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1750 if (secure_mode) {
1751 drv_ctx.op_buf.alignment=SZ_1M;
1752 drv_ctx.ip_buf.alignment=SZ_1M;
1753 } else {
1754 drv_ctx.op_buf.alignment=SZ_4K;
1755 drv_ctx.ip_buf.alignment=SZ_4K;
1756 }
1757 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1758 drv_ctx.extradata = 0;
1759 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1760 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1761 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1762 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1763 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764
Vinay Kalia5713bb32013-01-16 18:39:59 -08001765 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001766#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001767 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1768 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1769 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001770#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001771 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001772 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001773 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001774 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1775 if (m_frame_parser.mutils == NULL) {
1776 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001777
Arun Menon906de572013-06-18 17:01:40 -07001778 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001779 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001780 eRet = OMX_ErrorInsufficientResources;
1781 } else {
1782 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1783 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1784 h264_scratch.nFilledLen = 0;
1785 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001786
Arun Menon906de572013-06-18 17:01:40 -07001787 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001788 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001789 return OMX_ErrorInsufficientResources;
1790 }
1791 m_frame_parser.mutils->initialize_frame_checking_environment();
1792 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1793 }
1794 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001795
Arun Menon906de572013-06-18 17:01:40 -07001796 h264_parser = new h264_stream_parser();
1797 if (!h264_parser) {
1798 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1799 eRet = OMX_ErrorInsufficientResources;
1800 }
1801 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001802
Arun Menon906de572013-06-18 17:01:40 -07001803 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001804 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001805 eRet = OMX_ErrorInsufficientResources;
1806 } else {
1807 int temp1[2];
1808 if (fds[0] == 0 || fds[1] == 0) {
1809 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001810 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001811 return OMX_ErrorInsufficientResources;
1812 }
1813 //close (fds[0]);
1814 //close (fds[1]);
1815 fds[0] = temp1 [0];
1816 fds[1] = temp1 [1];
1817 }
1818 m_pipe_in = fds[0];
1819 m_pipe_out = fds[1];
1820 msg_thread_created = true;
1821 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001822
Arun Menon906de572013-06-18 17:01:40 -07001823 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001824 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001825 msg_thread_created = false;
1826 eRet = OMX_ErrorInsufficientResources;
1827 }
1828 }
1829 }
1830
1831 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001832 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001833 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001834 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001835 }
1836 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1837 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001838}
1839
1840/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001841 FUNCTION
1842 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001843
Arun Menon906de572013-06-18 17:01:40 -07001844 DESCRIPTION
1845 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001846
Arun Menon906de572013-06-18 17:01:40 -07001847 PARAMETERS
1848 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849
Arun Menon906de572013-06-18 17:01:40 -07001850 RETURN VALUE
1851 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852
Arun Menon906de572013-06-18 17:01:40 -07001853 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001855(
1856 OMX_IN OMX_HANDLETYPE hComp,
1857 OMX_OUT OMX_STRING componentName,
1858 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1859 OMX_OUT OMX_VERSIONTYPE* specVersion,
1860 OMX_OUT OMX_UUIDTYPE* componentUUID
1861 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001862{
Arun Menon906de572013-06-18 17:01:40 -07001863 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001864 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001865 return OMX_ErrorInvalidState;
1866 }
Arun Menon906de572013-06-18 17:01:40 -07001867 /* TBD -- Return the proper version */
1868 if (specVersion) {
1869 specVersion->nVersion = OMX_SPEC_VERSION;
1870 }
1871 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001872}
1873/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001874 FUNCTION
1875 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001876
Arun Menon906de572013-06-18 17:01:40 -07001877 DESCRIPTION
1878 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001879
Arun Menon906de572013-06-18 17:01:40 -07001880 PARAMETERS
1881 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001882
Arun Menon906de572013-06-18 17:01:40 -07001883 RETURN VALUE
1884 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001885
Arun Menon906de572013-06-18 17:01:40 -07001886 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001887OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001888 OMX_IN OMX_COMMANDTYPE cmd,
1889 OMX_IN OMX_U32 param1,
1890 OMX_IN OMX_PTR cmdData
1891 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001892{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001893 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001894 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001895 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001896 return OMX_ErrorInvalidState;
1897 }
1898 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001899 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001900 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001901 "to invalid port: %lu", param1);
1902 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001903 }
1904 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1905 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001906 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001907 return OMX_ErrorNone;
1908}
1909
1910/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001911 FUNCTION
1912 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001913
Arun Menon906de572013-06-18 17:01:40 -07001914 DESCRIPTION
1915 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001916
Arun Menon906de572013-06-18 17:01:40 -07001917 PARAMETERS
1918 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001919
Arun Menon906de572013-06-18 17:01:40 -07001920 RETURN VALUE
1921 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001922
Arun Menon906de572013-06-18 17:01:40 -07001923 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001924OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001925 OMX_IN OMX_COMMANDTYPE cmd,
1926 OMX_IN OMX_U32 param1,
1927 OMX_IN OMX_PTR cmdData
1928 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001929{
Arun Menon906de572013-06-18 17:01:40 -07001930 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1931 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1932 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001933
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001934 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1935 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001936 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001937
Arun Menon906de572013-06-18 17:01:40 -07001938 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001939 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1940 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001941 /***************************/
1942 /* Current State is Loaded */
1943 /***************************/
1944 if (m_state == OMX_StateLoaded) {
1945 if (eState == OMX_StateIdle) {
1946 //if all buffers are allocated or all ports disabled
1947 if (allocate_done() ||
1948 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001949 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001950 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001951 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001952 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1953 // Skip the event notification
1954 bFlag = 0;
1955 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001956 }
Arun Menon906de572013-06-18 17:01:40 -07001957 /* Requesting transition from Loaded to Loaded */
1958 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001959 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001960 post_event(OMX_EventError,OMX_ErrorSameState,\
1961 OMX_COMPONENT_GENERATE_EVENT);
1962 eRet = OMX_ErrorSameState;
1963 }
1964 /* Requesting transition from Loaded to WaitForResources */
1965 else if (eState == OMX_StateWaitForResources) {
1966 /* Since error is None , we will post an event
1967 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001968 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001969 }
1970 /* Requesting transition from Loaded to Executing */
1971 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001972 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001973 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1974 OMX_COMPONENT_GENERATE_EVENT);
1975 eRet = OMX_ErrorIncorrectStateTransition;
1976 }
1977 /* Requesting transition from Loaded to Pause */
1978 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001979 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001980 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1981 OMX_COMPONENT_GENERATE_EVENT);
1982 eRet = OMX_ErrorIncorrectStateTransition;
1983 }
1984 /* Requesting transition from Loaded to Invalid */
1985 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001986 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001987 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1988 eRet = OMX_ErrorInvalidState;
1989 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001990 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001991 eState);
1992 eRet = OMX_ErrorBadParameter;
1993 }
1994 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001995
Arun Menon906de572013-06-18 17:01:40 -07001996 /***************************/
1997 /* Current State is IDLE */
1998 /***************************/
1999 else if (m_state == OMX_StateIdle) {
2000 if (eState == OMX_StateLoaded) {
2001 if (release_done()) {
2002 /*
2003 Since error is None , we will post an event at the end
2004 of this function definition
2005 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002006 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002007 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002008 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002009 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2010 // Skip the event notification
2011 bFlag = 0;
2012 }
2013 }
2014 /* Requesting transition from Idle to Executing */
2015 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002016 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002017 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2018 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002019 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002020 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002021 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002022 }
2023 /* Requesting transition from Idle to Idle */
2024 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002025 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002026 post_event(OMX_EventError,OMX_ErrorSameState,\
2027 OMX_COMPONENT_GENERATE_EVENT);
2028 eRet = OMX_ErrorSameState;
2029 }
2030 /* Requesting transition from Idle to WaitForResources */
2031 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002032 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002033 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2034 OMX_COMPONENT_GENERATE_EVENT);
2035 eRet = OMX_ErrorIncorrectStateTransition;
2036 }
2037 /* Requesting transition from Idle to Pause */
2038 else if (eState == OMX_StatePause) {
2039 /*To pause the Video core we need to start the driver*/
2040 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2041 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002042 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002043 omx_report_error ();
2044 eRet = OMX_ErrorHardware;
2045 } else {
2046 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002047 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002048 bFlag = 0;
2049 }
2050 }
2051 /* Requesting transition from Idle to Invalid */
2052 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002053 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002054 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2055 eRet = OMX_ErrorInvalidState;
2056 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002057 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002058 eRet = OMX_ErrorBadParameter;
2059 }
2060 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002061
Arun Menon906de572013-06-18 17:01:40 -07002062 /******************************/
2063 /* Current State is Executing */
2064 /******************************/
2065 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002066 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002067 /* Requesting transition from Executing to Idle */
2068 if (eState == OMX_StateIdle) {
2069 /* Since error is None , we will post an event
2070 at the end of this function definition
2071 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002072 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002073 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2074 if (!sem_posted) {
2075 sem_posted = 1;
2076 sem_post (&m_cmd_lock);
2077 execute_omx_flush(OMX_ALL);
2078 }
2079 bFlag = 0;
2080 }
2081 /* Requesting transition from Executing to Paused */
2082 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002083 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002084 m_state = OMX_StatePause;
2085 bFlag = 1;
2086 }
2087 /* Requesting transition from Executing to Loaded */
2088 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002089 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002090 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2091 OMX_COMPONENT_GENERATE_EVENT);
2092 eRet = OMX_ErrorIncorrectStateTransition;
2093 }
2094 /* Requesting transition from Executing to WaitForResources */
2095 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002096 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002097 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2098 OMX_COMPONENT_GENERATE_EVENT);
2099 eRet = OMX_ErrorIncorrectStateTransition;
2100 }
2101 /* Requesting transition from Executing to Executing */
2102 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002103 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002104 post_event(OMX_EventError,OMX_ErrorSameState,\
2105 OMX_COMPONENT_GENERATE_EVENT);
2106 eRet = OMX_ErrorSameState;
2107 }
2108 /* Requesting transition from Executing to Invalid */
2109 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002110 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002111 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2112 eRet = OMX_ErrorInvalidState;
2113 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002114 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002115 eRet = OMX_ErrorBadParameter;
2116 }
2117 }
2118 /***************************/
2119 /* Current State is Pause */
2120 /***************************/
2121 else if (m_state == OMX_StatePause) {
2122 /* Requesting transition from Pause to Executing */
2123 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002124 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002125 m_state = OMX_StateExecuting;
2126 bFlag = 1;
2127 }
2128 /* Requesting transition from Pause to Idle */
2129 else if (eState == OMX_StateIdle) {
2130 /* Since error is None , we will post an event
2131 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002132 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002133 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2134 if (!sem_posted) {
2135 sem_posted = 1;
2136 sem_post (&m_cmd_lock);
2137 execute_omx_flush(OMX_ALL);
2138 }
2139 bFlag = 0;
2140 }
2141 /* Requesting transition from Pause to loaded */
2142 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002143 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002144 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2145 OMX_COMPONENT_GENERATE_EVENT);
2146 eRet = OMX_ErrorIncorrectStateTransition;
2147 }
2148 /* Requesting transition from Pause to WaitForResources */
2149 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002150 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002151 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2152 OMX_COMPONENT_GENERATE_EVENT);
2153 eRet = OMX_ErrorIncorrectStateTransition;
2154 }
2155 /* Requesting transition from Pause to Pause */
2156 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002157 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002158 post_event(OMX_EventError,OMX_ErrorSameState,\
2159 OMX_COMPONENT_GENERATE_EVENT);
2160 eRet = OMX_ErrorSameState;
2161 }
2162 /* Requesting transition from Pause to Invalid */
2163 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002164 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002165 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2166 eRet = OMX_ErrorInvalidState;
2167 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002168 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002169 eRet = OMX_ErrorBadParameter;
2170 }
2171 }
2172 /***************************/
2173 /* Current State is WaitForResources */
2174 /***************************/
2175 else if (m_state == OMX_StateWaitForResources) {
2176 /* Requesting transition from WaitForResources to Loaded */
2177 if (eState == OMX_StateLoaded) {
2178 /* Since error is None , we will post an event
2179 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002180 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002181 }
2182 /* Requesting transition from WaitForResources to WaitForResources */
2183 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002184 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002185 post_event(OMX_EventError,OMX_ErrorSameState,
2186 OMX_COMPONENT_GENERATE_EVENT);
2187 eRet = OMX_ErrorSameState;
2188 }
2189 /* Requesting transition from WaitForResources to Executing */
2190 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002191 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002192 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2193 OMX_COMPONENT_GENERATE_EVENT);
2194 eRet = OMX_ErrorIncorrectStateTransition;
2195 }
2196 /* Requesting transition from WaitForResources to Pause */
2197 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002198 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002199 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2200 OMX_COMPONENT_GENERATE_EVENT);
2201 eRet = OMX_ErrorIncorrectStateTransition;
2202 }
2203 /* Requesting transition from WaitForResources to Invalid */
2204 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002205 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002206 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2207 eRet = OMX_ErrorInvalidState;
2208 }
2209 /* Requesting transition from WaitForResources to Loaded -
2210 is NOT tested by Khronos TS */
2211
2212 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002213 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002214 eRet = OMX_ErrorBadParameter;
2215 }
2216 }
2217 /********************************/
2218 /* Current State is Invalid */
2219 /*******************************/
2220 else if (m_state == OMX_StateInvalid) {
2221 /* State Transition from Inavlid to any state */
2222 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2223 || OMX_StateIdle || OMX_StateExecuting
2224 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002225 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002226 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2227 OMX_COMPONENT_GENERATE_EVENT);
2228 eRet = OMX_ErrorInvalidState;
2229 }
2230 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002231 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002232 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002233#ifdef _MSM8974_
2234 send_codec_config();
2235#endif
Arun Menon906de572013-06-18 17:01:40 -07002236 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2237 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2238 }
2239 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2240 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2241 }
2242 if (!sem_posted) {
2243 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002244 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002245 sem_post (&m_cmd_lock);
2246 execute_omx_flush(param1);
2247 }
2248 bFlag = 0;
2249 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002250 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002251 "with param1: %lu", param1);
2252 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2253 m_inp_bEnabled = OMX_TRUE;
2254
2255 if ( (m_state == OMX_StateLoaded &&
2256 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2257 || allocate_input_done()) {
2258 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2259 OMX_COMPONENT_GENERATE_EVENT);
2260 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002261 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002262 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2263 // Skip the event notification
2264 bFlag = 0;
2265 }
2266 }
2267 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002268 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002269 m_out_bEnabled = OMX_TRUE;
2270
2271 if ( (m_state == OMX_StateLoaded &&
2272 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2273 || (allocate_output_done())) {
2274 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2275 OMX_COMPONENT_GENERATE_EVENT);
2276
2277 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002278 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002279 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2280 // Skip the event notification
2281 bFlag = 0;
2282 }
2283 }
2284 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002285 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002286 "with param1: %lu", param1);
2287 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002288 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002289 m_inp_bEnabled = OMX_FALSE;
2290 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2291 && release_input_done()) {
2292 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2293 OMX_COMPONENT_GENERATE_EVENT);
2294 } else {
2295 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2296 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2297 if (!sem_posted) {
2298 sem_posted = 1;
2299 sem_post (&m_cmd_lock);
2300 }
2301 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2302 }
2303
2304 // Skip the event notification
2305 bFlag = 0;
2306 }
2307 }
2308 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2309 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002310 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002311 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2312 && release_output_done()) {
2313 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2314 OMX_COMPONENT_GENERATE_EVENT);
2315 } else {
2316 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2317 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2318 if (!sem_posted) {
2319 sem_posted = 1;
2320 sem_post (&m_cmd_lock);
2321 }
2322 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2323 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2324 }
2325 // Skip the event notification
2326 bFlag = 0;
2327
2328 }
2329 }
2330 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002331 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002332 eRet = OMX_ErrorNotImplemented;
2333 }
2334 if (eRet == OMX_ErrorNone && bFlag) {
2335 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2336 }
2337 if (!sem_posted) {
2338 sem_post(&m_cmd_lock);
2339 }
2340
2341 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002342}
2343
2344/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002345 FUNCTION
2346 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002347
Arun Menon906de572013-06-18 17:01:40 -07002348 DESCRIPTION
2349 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002350
Arun Menon906de572013-06-18 17:01:40 -07002351 PARAMETERS
2352 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002353
Arun Menon906de572013-06-18 17:01:40 -07002354 RETURN VALUE
2355 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002356
Arun Menon906de572013-06-18 17:01:40 -07002357 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002358bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2359{
Arun Menon906de572013-06-18 17:01:40 -07002360 bool bRet = false;
2361 struct v4l2_plane plane;
2362 struct v4l2_buffer v4l2_buf;
2363 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302364 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002365 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2366 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002367
Arun Menon906de572013-06-18 17:01:40 -07002368 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002369
Arun Menon906de572013-06-18 17:01:40 -07002370 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2371 output_flush_progress = true;
2372 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2373 } else {
2374 /* XXX: The driver/hardware does not support flushing of individual ports
2375 * in all states. So we pretty much need to flush both ports internally,
2376 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2377 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2378 * we automatically omit sending the FLUSH done for the "opposite" port. */
2379 input_flush_progress = true;
2380 output_flush_progress = true;
2381 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2382 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002383
Arun Menon906de572013-06-18 17:01:40 -07002384 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002385 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002386 bRet = false;
2387 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002388
Arun Menon906de572013-06-18 17:01:40 -07002389 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002390}
2391/*=========================================================================
2392FUNCTION : execute_output_flush
2393
2394DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002395Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002396
2397PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002398None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002399
2400RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002401true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002402==========================================================================*/
2403bool omx_vdec::execute_output_flush()
2404{
Arun Menon906de572013-06-18 17:01:40 -07002405 unsigned p1 = 0; // Parameter - 1
2406 unsigned p2 = 0; // Parameter - 2
2407 unsigned ident = 0;
2408 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002409
Arun Menon906de572013-06-18 17:01:40 -07002410 /*Generate FBD for all Buffers in the FTBq*/
2411 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002412 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002413
2414 //reset last render TS
2415 if(m_last_rendered_TS > 0) {
2416 m_last_rendered_TS = 0;
2417 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002418
Arun Menon906de572013-06-18 17:01:40 -07002419 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002420 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002421 m_ftb_q.m_size,pending_output_buffers);
2422 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002423 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002424 if (ident == m_fill_output_msg ) {
2425 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2426 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2427 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2428 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002429 }
Arun Menon906de572013-06-18 17:01:40 -07002430 pthread_mutex_unlock(&m_lock);
2431 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002432
Arun Menon906de572013-06-18 17:01:40 -07002433 if (arbitrary_bytes) {
2434 prev_ts = LLONG_MAX;
2435 rst_prev_ts = true;
2436 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002437 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002438 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002439}
2440/*=========================================================================
2441FUNCTION : execute_input_flush
2442
2443DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002444Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002445
2446PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002447None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002448
2449RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002450true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002451==========================================================================*/
2452bool omx_vdec::execute_input_flush()
2453{
Arun Menon906de572013-06-18 17:01:40 -07002454 unsigned i =0;
2455 unsigned p1 = 0; // Parameter - 1
2456 unsigned p2 = 0; // Parameter - 2
2457 unsigned ident = 0;
2458 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459
Arun Menon906de572013-06-18 17:01:40 -07002460 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002461 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002462
Arun Menon906de572013-06-18 17:01:40 -07002463 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002464 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002465 while (m_etb_q.m_size) {
2466 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002467
Arun Menon906de572013-06-18 17:01:40 -07002468 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002469 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002470 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2471 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2472 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002473 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002474 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2475 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2476 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002477 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002478 (OMX_BUFFERHEADERTYPE *)p1);
2479 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002481 }
Arun Menon906de572013-06-18 17:01:40 -07002482 time_stamp_dts.flush_timestamp();
2483 /*Check if Heap Buffers are to be flushed*/
2484 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002485 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002486 h264_scratch.nFilledLen = 0;
2487 nal_count = 0;
2488 look_ahead_nal = false;
2489 frame_count = 0;
2490 h264_last_au_ts = LLONG_MAX;
2491 h264_last_au_flags = 0;
2492 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2493 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002494 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002495 if (m_frame_parser.mutils) {
2496 m_frame_parser.mutils->initialize_frame_checking_environment();
2497 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002498
Arun Menon906de572013-06-18 17:01:40 -07002499 while (m_input_pending_q.m_size) {
2500 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2501 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2502 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503
Arun Menon906de572013-06-18 17:01:40 -07002504 if (psource_frame) {
2505 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2506 psource_frame = NULL;
2507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002508
Arun Menon906de572013-06-18 17:01:40 -07002509 if (pdest_frame) {
2510 pdest_frame->nFilledLen = 0;
2511 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2512 (unsigned int)NULL);
2513 pdest_frame = NULL;
2514 }
2515 m_frame_parser.flush();
2516 } else if (codec_config_flag) {
2517 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2518 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002519 }
Arun Menon906de572013-06-18 17:01:40 -07002520 pthread_mutex_unlock(&m_lock);
2521 input_flush_progress = false;
2522 if (!arbitrary_bytes) {
2523 prev_ts = LLONG_MAX;
2524 rst_prev_ts = true;
2525 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002526#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002527 if (m_debug_timestamp) {
2528 m_timestamp_list.reset_ts_list();
2529 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002530#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002531 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002532 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002533}
2534
2535
2536/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002537 FUNCTION
2538 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002539
Arun Menon906de572013-06-18 17:01:40 -07002540 DESCRIPTION
2541 Send the event to decoder pipe. This is needed to generate the callbacks
2542 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002543
Arun Menon906de572013-06-18 17:01:40 -07002544 PARAMETERS
2545 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002546
Arun Menon906de572013-06-18 17:01:40 -07002547 RETURN VALUE
2548 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002549
Arun Menon906de572013-06-18 17:01:40 -07002550 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002551bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002552 unsigned int p2,
2553 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002554{
Arun Menon906de572013-06-18 17:01:40 -07002555 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002556
2557
Arun Menon906de572013-06-18 17:01:40 -07002558 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002559
Arun Menon906de572013-06-18 17:01:40 -07002560 if (id == m_fill_output_msg ||
2561 id == OMX_COMPONENT_GENERATE_FBD) {
2562 m_ftb_q.insert_entry(p1,p2,id);
2563 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2564 id == OMX_COMPONENT_GENERATE_EBD ||
2565 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2566 m_etb_q.insert_entry(p1,p2,id);
2567 } else {
2568 m_cmd_q.insert_entry(p1,p2,id);
2569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002570
Arun Menon906de572013-06-18 17:01:40 -07002571 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002572 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002573 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002574
Arun Menon906de572013-06-18 17:01:40 -07002575 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002576
Arun Menon906de572013-06-18 17:01:40 -07002577 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002578}
2579
2580OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2581{
Arun Menon906de572013-06-18 17:01:40 -07002582 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2583 if (!profileLevelType)
2584 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002585
Arun Menon906de572013-06-18 17:01:40 -07002586 if (profileLevelType->nPortIndex == 0) {
2587 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2588 if (profileLevelType->nProfileIndex == 0) {
2589 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2590 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002591
Arun Menon906de572013-06-18 17:01:40 -07002592 } else if (profileLevelType->nProfileIndex == 1) {
2593 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2594 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2595 } else if (profileLevelType->nProfileIndex == 2) {
2596 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2597 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2598 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002599 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002600 profileLevelType->nProfileIndex);
2601 eRet = OMX_ErrorNoMore;
2602 }
2603 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2604 if (profileLevelType->nProfileIndex == 0) {
2605 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2606 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2607 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002608 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002609 eRet = OMX_ErrorNoMore;
2610 }
2611 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2612 if (profileLevelType->nProfileIndex == 0) {
2613 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2614 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2615 } else if (profileLevelType->nProfileIndex == 1) {
2616 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2617 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2618 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002619 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002620 eRet = OMX_ErrorNoMore;
2621 }
2622 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2623 eRet = OMX_ErrorNoMore;
2624 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2625 if (profileLevelType->nProfileIndex == 0) {
2626 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2627 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2628 } else if (profileLevelType->nProfileIndex == 1) {
2629 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2630 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2631 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002632 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002633 eRet = OMX_ErrorNoMore;
2634 }
2635 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002636 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002637 eRet = OMX_ErrorNoMore;
2638 }
2639 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002640 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002641 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002642 }
Arun Menon906de572013-06-18 17:01:40 -07002643 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002644}
2645
2646/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002647 FUNCTION
2648 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002649
Arun Menon906de572013-06-18 17:01:40 -07002650 DESCRIPTION
2651 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002652
Arun Menon906de572013-06-18 17:01:40 -07002653 PARAMETERS
2654 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002655
Arun Menon906de572013-06-18 17:01:40 -07002656 RETURN VALUE
2657 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002658
Arun Menon906de572013-06-18 17:01:40 -07002659 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002660OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002661 OMX_IN OMX_INDEXTYPE paramIndex,
2662 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002663{
2664 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2665
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002666 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002667 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002668 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002669 return OMX_ErrorInvalidState;
2670 }
Arun Menon906de572013-06-18 17:01:40 -07002671 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002672 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002673 return OMX_ErrorBadParameter;
2674 }
Arun Menon906de572013-06-18 17:01:40 -07002675 switch ((unsigned long)paramIndex) {
2676 case OMX_IndexParamPortDefinition: {
2677 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2678 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002679 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002680 eRet = update_portdef(portDefn);
2681 if (eRet == OMX_ErrorNone)
2682 m_port_def = *portDefn;
2683 break;
2684 }
2685 case OMX_IndexParamVideoInit: {
2686 OMX_PORT_PARAM_TYPE *portParamType =
2687 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002688 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002689
Arun Menon906de572013-06-18 17:01:40 -07002690 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2691 portParamType->nSize = sizeof(portParamType);
2692 portParamType->nPorts = 2;
2693 portParamType->nStartPortNumber = 0;
2694 break;
2695 }
2696 case OMX_IndexParamVideoPortFormat: {
2697 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2698 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002699 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002700
Arun Menon906de572013-06-18 17:01:40 -07002701 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2702 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002703
Arun Menon906de572013-06-18 17:01:40 -07002704 if (0 == portFmt->nPortIndex) {
2705 if (0 == portFmt->nIndex) {
2706 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2707 portFmt->eCompressionFormat = eCompressionFormat;
2708 } else {
2709 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002710 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002711 eRet = OMX_ErrorNoMore;
2712 }
2713 } else if (1 == portFmt->nPortIndex) {
2714 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Praveen Chavandb7776f2014-02-06 18:17:25 -08002715 //On Android, we default to standard YUV formats for non-surface use-cases
2716 //where apps prefer known color formats.
2717 OMX_COLOR_FORMATTYPE formatsNonSurfaceMode[] = {
2718 [0] = OMX_COLOR_FormatYUV420SemiPlanar,
2719 [1] = OMX_COLOR_FormatYUV420Planar,
2720 [2] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2721 };
2722 //for surface mode (normal playback), advertise native/accelerated formats first
2723 OMX_COLOR_FORMATTYPE formatsDefault[] = {
2724 [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2725 [1] = OMX_COLOR_FormatYUV420Planar,
2726 [2] = OMX_COLOR_FormatYUV420SemiPlanar,
2727 };
2728#if _ANDROID_
2729 //Distinguish non-surface mode from normal playback use-case based on
2730 //usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2731 OMX_COLOR_FORMATTYPE *colorFormats =
2732 m_enable_android_native_buffers ? formatsDefault : formatsNonSurfaceMode;
2733 OMX_U32 maxIndex =
2734 m_enable_android_native_buffers ? sizeof(formatsDefault) : sizeof(formatsNonSurfaceMode);
2735 maxIndex /= sizeof(OMX_COLOR_FORMATTYPE);
2736#else
2737 OMX_COLOR_FORMATTYPE *colorFormats = formatsDefault;
2738 OMX_U32 maxIndex = sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE);
2739#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07002740
Praveen Chavandb7776f2014-02-06 18:17:25 -08002741 if (portFmt->nIndex < maxIndex) {
2742 portFmt->eColorFormat = colorFormats[portFmt->nIndex];
2743 } else {
2744 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002745 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002746 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002747 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002748 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002749 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002750 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002751 (int)portFmt->nPortIndex);
2752 eRet = OMX_ErrorBadPortIndex;
2753 }
2754 break;
2755 }
2756 /*Component should support this port definition*/
2757 case OMX_IndexParamAudioInit: {
2758 OMX_PORT_PARAM_TYPE *audioPortParamType =
2759 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002760 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002761 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2762 audioPortParamType->nSize = sizeof(audioPortParamType);
2763 audioPortParamType->nPorts = 0;
2764 audioPortParamType->nStartPortNumber = 0;
2765 break;
2766 }
2767 /*Component should support this port definition*/
2768 case OMX_IndexParamImageInit: {
2769 OMX_PORT_PARAM_TYPE *imagePortParamType =
2770 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002771 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002772 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2773 imagePortParamType->nSize = sizeof(imagePortParamType);
2774 imagePortParamType->nPorts = 0;
2775 imagePortParamType->nStartPortNumber = 0;
2776 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002777
Arun Menon906de572013-06-18 17:01:40 -07002778 }
2779 /*Component should support this port definition*/
2780 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002781 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002782 paramIndex);
2783 eRet =OMX_ErrorUnsupportedIndex;
2784 break;
2785 }
2786 case OMX_IndexParamStandardComponentRole: {
2787 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2788 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2789 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2790 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002791
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002792 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002793 paramIndex);
2794 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2795 OMX_MAX_STRINGNAME_SIZE);
2796 break;
2797 }
2798 /* Added for parameter test */
2799 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002800
Arun Menon906de572013-06-18 17:01:40 -07002801 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2802 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002803 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002804 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2805 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002806
Arun Menon906de572013-06-18 17:01:40 -07002807 break;
2808 }
2809 /* Added for parameter test */
2810 case OMX_IndexParamCompBufferSupplier: {
2811 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2812 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002813 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002814
Arun Menon906de572013-06-18 17:01:40 -07002815 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2816 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2817 if (0 == bufferSupplierType->nPortIndex)
2818 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2819 else if (1 == bufferSupplierType->nPortIndex)
2820 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2821 else
2822 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002823
2824
Arun Menon906de572013-06-18 17:01:40 -07002825 break;
2826 }
2827 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002828 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002829 paramIndex);
2830 break;
2831 }
2832 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002833 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002834 paramIndex);
2835 break;
2836 }
2837 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002838 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002839 paramIndex);
2840 break;
2841 }
2842 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002843 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002844 paramIndex);
2845 break;
2846 }
2847 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002848 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002849 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2850 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2851 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2852 break;
2853 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002854#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002855 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002856 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002857 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2858 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002859
Arun Menon906de572013-06-18 17:01:40 -07002860 if (secure_mode) {
2861 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2862 GRALLOC_USAGE_PRIVATE_UNCACHED);
2863 } else {
2864 nativeBuffersUsage->nUsage =
2865 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2866 GRALLOC_USAGE_PRIVATE_UNCACHED);
2867 }
2868 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002869 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002870 eRet = OMX_ErrorBadParameter;
2871 }
2872 }
2873 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002874#endif
2875
Arun Menon906de572013-06-18 17:01:40 -07002876 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002877 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002878 eRet =OMX_ErrorUnsupportedIndex;
2879 }
2880
Shalaj Jain273b3e02012-06-22 19:08:03 -07002881 }
2882
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002883 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002884 drv_ctx.video_resolution.frame_width,
2885 drv_ctx.video_resolution.frame_height,
2886 drv_ctx.video_resolution.stride,
2887 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002888
Arun Menon906de572013-06-18 17:01:40 -07002889 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002890}
2891
2892#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2893OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2894{
2895 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2896 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2897 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2898
Arun Menon906de572013-06-18 17:01:40 -07002899 if ((params == NULL) ||
2900 (params->nativeBuffer == NULL) ||
2901 (params->nativeBuffer->handle == NULL) ||
2902 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002903 return OMX_ErrorBadParameter;
2904 m_use_android_native_buffers = OMX_TRUE;
2905 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2906 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002907 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 -07002908 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002909 if (!secure_mode) {
2910 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002911 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002912 if (buffer == MAP_FAILED) {
2913 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2914 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002915 }
2916 }
2917 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2918 } else {
2919 eRet = OMX_ErrorBadParameter;
2920 }
2921 return eRet;
2922}
2923#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002924
2925OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2926 struct v4l2_control control;
2927 struct v4l2_format fmt;
2928 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2929 control.value = 1;
2930 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2931 if (rc < 0) {
2932 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2933 return OMX_ErrorHardware;
2934 }
2935 m_smoothstreaming_mode = true;
2936 return OMX_ErrorNone;
2937}
2938
Shalaj Jain273b3e02012-06-22 19:08:03 -07002939/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002940 FUNCTION
2941 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002942
Arun Menon906de572013-06-18 17:01:40 -07002943 DESCRIPTION
2944 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002945
Arun Menon906de572013-06-18 17:01:40 -07002946 PARAMETERS
2947 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002948
Arun Menon906de572013-06-18 17:01:40 -07002949 RETURN VALUE
2950 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002951
Arun Menon906de572013-06-18 17:01:40 -07002952 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002953OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002954 OMX_IN OMX_INDEXTYPE paramIndex,
2955 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002956{
2957 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002958 int ret=0;
2959 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002960 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002961 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002962 return OMX_ErrorInvalidState;
2963 }
Arun Menon906de572013-06-18 17:01:40 -07002964 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002965 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002966 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002967 }
Arun Menon906de572013-06-18 17:01:40 -07002968 if ((m_state != OMX_StateLoaded) &&
2969 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2970 (m_out_bEnabled == OMX_TRUE) &&
2971 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2972 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002973 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002974 return OMX_ErrorIncorrectStateOperation;
2975 }
Arun Menon906de572013-06-18 17:01:40 -07002976 switch ((unsigned long)paramIndex) {
2977 case OMX_IndexParamPortDefinition: {
2978 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2979 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2980 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2981 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002982 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002983 (int)portDefn->format.video.nFrameHeight,
2984 (int)portDefn->format.video.nFrameWidth);
2985 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002986 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002987 m_display_id = portDefn->format.video.pNativeWindow;
2988 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002989 /* update output port resolution with client supplied dimensions
2990 in case scaling is enabled, else it follows input resolution set
2991 */
2992 if (is_down_scalar_enabled) {
2993 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002994 portDefn->format.video.nFrameWidth,
2995 portDefn->format.video.nFrameHeight);
2996 if (portDefn->format.video.nFrameHeight != 0x0 &&
2997 portDefn->format.video.nFrameWidth != 0x0) {
2998 update_resolution(portDefn->format.video.nFrameWidth,
2999 portDefn->format.video.nFrameHeight,
3000 portDefn->format.video.nFrameWidth,
3001 portDefn->format.video.nFrameHeight);
3002 eRet = is_video_session_supported();
3003 if (eRet)
3004 break;
3005 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3006 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3007 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3008 fmt.fmt.pix_mp.pixelformat = capture_capability;
3009 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);
3010 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3011 if (ret) {
3012 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3013 eRet = OMX_ErrorUnsupportedSetting;
3014 } else
3015 eRet = get_buffer_req(&drv_ctx.op_buf);
3016 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003017 }
Arun Menon906de572013-06-18 17:01:40 -07003018 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003019 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003020 eRet = OMX_ErrorBadParameter;
3021 } else {
3022 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3023 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3024 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3025 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3026 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3027 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3028 drv_ctx.extradata_info.buffer_size;
3029 eRet = set_buffer_req(&drv_ctx.op_buf);
3030 if (eRet == OMX_ErrorNone)
3031 m_port_def = *portDefn;
3032 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003033 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003034 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3035 portDefn->nBufferCountActual, portDefn->nBufferSize);
3036 eRet = OMX_ErrorBadParameter;
3037 }
3038 }
3039 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003040 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003041 bool port_format_changed = false;
3042 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3043 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3044 // Frame rate only should be set if this is a "known value" or to
3045 // activate ts prediction logic (arbitrary mode only) sending input
3046 // timestamps with max value (LLONG_MAX).
3047 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3048 portDefn->format.video.xFramerate >> 16);
3049 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3050 drv_ctx.frame_rate.fps_denominator);
3051 if (!drv_ctx.frame_rate.fps_numerator) {
3052 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3053 drv_ctx.frame_rate.fps_numerator = 30;
3054 }
3055 if (drv_ctx.frame_rate.fps_denominator)
3056 drv_ctx.frame_rate.fps_numerator = (int)
3057 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3058 drv_ctx.frame_rate.fps_denominator = 1;
3059 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3060 drv_ctx.frame_rate.fps_numerator;
3061 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3062 frm_int, drv_ctx.frame_rate.fps_numerator /
3063 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003064
3065 struct v4l2_outputparm oparm;
3066 /*XXX: we're providing timing info as seconds per frame rather than frames
3067 * per second.*/
3068 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3069 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3070
3071 struct v4l2_streamparm sparm;
3072 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3073 sparm.parm.output = oparm;
3074 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3075 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3076 eRet = OMX_ErrorHardware;
3077 break;
3078 }
Arun Menon906de572013-06-18 17:01:40 -07003079 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003080
Arun Menon906de572013-06-18 17:01:40 -07003081 if (drv_ctx.video_resolution.frame_height !=
3082 portDefn->format.video.nFrameHeight ||
3083 drv_ctx.video_resolution.frame_width !=
3084 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003085 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003086 portDefn->format.video.nFrameWidth,
3087 portDefn->format.video.nFrameHeight);
3088 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003089 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3090 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3091 if (frameHeight != 0x0 && frameWidth != 0x0) {
3092 if (m_smoothstreaming_mode &&
3093 ((frameWidth * frameHeight) <
3094 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3095 frameWidth = m_smoothstreaming_width;
3096 frameHeight = m_smoothstreaming_height;
3097 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3098 frameWidth, frameHeight);
3099 }
3100 update_resolution(frameWidth, frameHeight,
3101 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003102 eRet = is_video_session_supported();
3103 if (eRet)
3104 break;
3105 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3106 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3107 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3108 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003109 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 -07003110 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3111 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003112 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003113 eRet = OMX_ErrorUnsupportedSetting;
3114 } else
3115 eRet = get_buffer_req(&drv_ctx.op_buf);
3116 }
3117 }
3118 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3119 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3120 port_format_changed = true;
3121 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3122 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3123 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3124 (~(buffer_prop->alignment - 1));
3125 eRet = set_buffer_req(buffer_prop);
3126 }
3127 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003128 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003129 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3130 portDefn->nBufferCountActual, portDefn->nBufferSize);
3131 eRet = OMX_ErrorBadParameter;
3132 }
3133 } else if (portDefn->eDir == OMX_DirMax) {
3134 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3135 (int)portDefn->nPortIndex);
3136 eRet = OMX_ErrorBadPortIndex;
3137 }
3138 }
3139 break;
3140 case OMX_IndexParamVideoPortFormat: {
3141 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3142 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3143 int ret=0;
3144 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003145 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003146 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003147
Arun Menon906de572013-06-18 17:01:40 -07003148 if (1 == portFmt->nPortIndex) {
3149 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3150 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3151 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3152 fmt.fmt.pix_mp.pixelformat = capture_capability;
3153 enum vdec_output_fromat op_format;
3154 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3155 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003156 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3157 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003158 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003159 else
3160 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003161
Arun Menon906de572013-06-18 17:01:40 -07003162 if (eRet == OMX_ErrorNone) {
3163 drv_ctx.output_format = op_format;
3164 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3165 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003166 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003167 eRet = OMX_ErrorUnsupportedSetting;
3168 /*TODO: How to handle this case */
3169 } else {
3170 eRet = get_buffer_req(&drv_ctx.op_buf);
3171 }
3172 }
3173 if (eRet == OMX_ErrorNone) {
3174 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003175 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003176 eRet = OMX_ErrorBadParameter;
3177 }
3178 }
3179 }
3180 }
3181 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003182
Arun Menon906de572013-06-18 17:01:40 -07003183 case OMX_QcomIndexPortDefn: {
3184 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3185 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003186 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003187 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003188
Arun Menon906de572013-06-18 17:01:40 -07003189 /* Input port */
3190 if (portFmt->nPortIndex == 0) {
3191 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3192 if (secure_mode) {
3193 arbitrary_bytes = false;
3194 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3195 eRet = OMX_ErrorUnsupportedSetting;
3196 } else {
3197 arbitrary_bytes = true;
3198 }
3199 } else if (portFmt->nFramePackingFormat ==
3200 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3201 arbitrary_bytes = false;
3202 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003203 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003204 portFmt->nFramePackingFormat);
3205 eRet = OMX_ErrorUnsupportedSetting;
3206 }
3207 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003208 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003209 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3210 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3211 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3212 m_out_mem_region_smi = OMX_TRUE;
3213 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003214 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003215 m_use_output_pmem = OMX_TRUE;
3216 }
3217 }
3218 }
3219 }
3220 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003221
Arun Menon906de572013-06-18 17:01:40 -07003222 case OMX_IndexParamStandardComponentRole: {
3223 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3224 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003225 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003226 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003227
Arun Menon906de572013-06-18 17:01:40 -07003228 if ((m_state == OMX_StateLoaded)&&
3229 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3230 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3231 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003232 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003233 return OMX_ErrorIncorrectStateOperation;
3234 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003235
Arun Menon906de572013-06-18 17:01:40 -07003236 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3237 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3238 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3239 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003240 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003241 eRet =OMX_ErrorUnsupportedSetting;
3242 }
3243 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3244 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3245 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3246 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003247 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003248 eRet = OMX_ErrorUnsupportedSetting;
3249 }
3250 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3251 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3252 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3253 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003254 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003255 eRet =OMX_ErrorUnsupportedSetting;
3256 }
3257 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3258 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3259 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3260 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003261 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003262 eRet = OMX_ErrorUnsupportedSetting;
3263 }
3264 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3265 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3266 ) {
3267 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3268 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3269 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003270 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003271 eRet =OMX_ErrorUnsupportedSetting;
3272 }
3273 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3274 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3275 ) {
3276 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3277 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3278 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003279 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003280 eRet =OMX_ErrorUnsupportedSetting;
3281 }
3282 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3283 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3284 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3285 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3286 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003287 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003288 eRet = OMX_ErrorUnsupportedSetting;
3289 }
3290 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003291 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003292 eRet = OMX_ErrorInvalidComponentName;
3293 }
3294 break;
3295 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003296
Arun Menon906de572013-06-18 17:01:40 -07003297 case OMX_IndexParamPriorityMgmt: {
3298 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003299 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003300 return OMX_ErrorIncorrectStateOperation;
3301 }
3302 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003303 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003304 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003305
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003306 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003307 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003308
Arun Menon906de572013-06-18 17:01:40 -07003309 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3310 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003311
Arun Menon906de572013-06-18 17:01:40 -07003312 break;
3313 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003314
Arun Menon906de572013-06-18 17:01:40 -07003315 case OMX_IndexParamCompBufferSupplier: {
3316 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003317 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003318 bufferSupplierType->eBufferSupplier);
3319 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3320 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003321
Arun Menon906de572013-06-18 17:01:40 -07003322 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003323
Arun Menon906de572013-06-18 17:01:40 -07003324 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003325
Arun Menon906de572013-06-18 17:01:40 -07003326 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003327
Arun Menon906de572013-06-18 17:01:40 -07003328 }
3329 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003330 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003331 paramIndex);
3332 break;
3333 }
3334 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003335 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003336 paramIndex);
3337 break;
3338 }
3339 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003340 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003341 paramIndex);
3342 break;
3343 }
3344 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003345 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003346 paramIndex);
3347 break;
3348 }
3349 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3350 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3351 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3352 struct v4l2_control control;
3353 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003354 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003355 pictureOrder->eOutputPictureOrder);
3356 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3357 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3358 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3359 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3360 time_stamp_dts.set_timestamp_reorder_mode(false);
3361 } else
3362 eRet = OMX_ErrorBadParameter;
3363 if (eRet == OMX_ErrorNone) {
3364 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3365 control.value = pic_order;
3366 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3367 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003368 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003369 eRet = OMX_ErrorUnsupportedSetting;
3370 }
3371 }
3372 break;
3373 }
3374 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303375 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3376 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3377 break;
3378 case OMX_QcomIndexParamFrameInfoExtraData:
3379 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3380 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3381 break;
Arun Menon906de572013-06-18 17:01:40 -07003382 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303383 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3384 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3385 break;
Arun Menon906de572013-06-18 17:01:40 -07003386 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303387 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3388 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3389 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303390 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303391 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3392 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3393 break;
3394 case OMX_QcomIndexParamVideoQPExtraData:
3395 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3396 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3397 break;
3398 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3399 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3400 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3401 break;
Arun Menon906de572013-06-18 17:01:40 -07003402 case OMX_QcomIndexParamVideoDivx: {
3403 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3404 }
3405 break;
3406 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003407 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003408 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3409 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3410 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3411 eRet = OMX_ErrorUnsupportedSetting;
3412 } else {
3413 m_out_pvt_entry_pmem = OMX_TRUE;
3414 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003415 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003416 m_use_output_pmem = OMX_TRUE;
3417 }
3418 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003419
Arun Menon906de572013-06-18 17:01:40 -07003420 }
3421 break;
3422 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3423 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3424 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3425 struct v4l2_control control;
3426 int rc;
3427 drv_ctx.idr_only_decoding = 1;
3428 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3429 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3430 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3431 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003432 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003433 eRet = OMX_ErrorUnsupportedSetting;
3434 } else {
3435 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3436 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3437 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3438 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003439 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003440 eRet = OMX_ErrorUnsupportedSetting;
3441 }
3442 /*Setting sync frame decoding on driver might change buffer
3443 * requirements so update them here*/
3444 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003445 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003446 eRet = OMX_ErrorUnsupportedSetting;
3447 }
3448 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003449 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003450 eRet = OMX_ErrorUnsupportedSetting;
3451 }
3452 }
3453 }
3454 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003455
Arun Menon906de572013-06-18 17:01:40 -07003456 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303457 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3458 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3459 (extradataIndexType->bEnabled == OMX_TRUE) &&
3460 (extradataIndexType->nPortIndex == 1)) {
3461 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3462 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3463 }
3464 }
Arun Menon906de572013-06-18 17:01:40 -07003465 break;
3466 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003467#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003468 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003469#else
Arun Menon906de572013-06-18 17:01:40 -07003470 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003471#endif
Arun Menon906de572013-06-18 17:01:40 -07003472 }
3473 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003474#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003475 /* Need to allow following two set_parameters even in Idle
3476 * state. This is ANDROID architecture which is not in sync
3477 * with openmax standard. */
3478 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3479 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3480 if (enableNativeBuffers) {
3481 m_enable_android_native_buffers = enableNativeBuffers->enable;
3482 }
3483 }
3484 break;
3485 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3486 eRet = use_android_native_buffer(hComp, paramData);
3487 }
3488 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003489#endif
Arun Menon906de572013-06-18 17:01:40 -07003490 case OMX_QcomIndexParamEnableTimeStampReorder: {
3491 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3492 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3493 if (reorder->bEnable == OMX_TRUE) {
3494 frm_int =0;
3495 time_stamp_dts.set_timestamp_reorder_mode(true);
3496 } else
3497 time_stamp_dts.set_timestamp_reorder_mode(false);
3498 } else {
3499 time_stamp_dts.set_timestamp_reorder_mode(false);
3500 if (reorder->bEnable == OMX_TRUE) {
3501 eRet = OMX_ErrorUnsupportedSetting;
3502 }
3503 }
3504 }
3505 break;
3506 case OMX_IndexParamVideoProfileLevelCurrent: {
3507 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3508 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3509 if (pParam) {
3510 m_profile_lvl.eProfile = pParam->eProfile;
3511 m_profile_lvl.eLevel = pParam->eLevel;
3512 }
3513 break;
Arun Menon888aa852013-05-30 11:24:42 -07003514
Arun Menon906de572013-06-18 17:01:40 -07003515 }
Arun Menone5652482013-08-04 13:33:05 -07003516 case OMX_QcomIndexParamVideoMetaBufferMode:
3517 {
3518 StoreMetaDataInBuffersParams *metabuffer =
3519 (StoreMetaDataInBuffersParams *)paramData;
3520 if (!metabuffer) {
3521 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3522 eRet = OMX_ErrorBadParameter;
3523 break;
3524 }
3525 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3526 //set property dynamic buffer mode to driver.
3527 struct v4l2_control control;
3528 struct v4l2_format fmt;
3529 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3530 if (metabuffer->bStoreMetaData == true) {
3531 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3532 } else {
3533 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3534 }
3535 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3536 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003537 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003538 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003539 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003540 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003541 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003542 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3543 eRet = OMX_ErrorUnsupportedSetting;
3544 }
3545 } else {
3546 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003547 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003548 metabuffer->nPortIndex);
3549 eRet = OMX_ErrorUnsupportedSetting;
3550 }
3551 break;
3552 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003553 case OMX_QcomIndexParamVideoDownScalar: {
3554 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3555 struct v4l2_control control;
3556 int rc;
3557 if (pParam) {
3558 is_down_scalar_enabled = pParam->bEnable;
3559 if (is_down_scalar_enabled) {
3560 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3561 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3562 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3563 pParam->bEnable);
3564 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3565 if (rc < 0) {
3566 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3567 eRet = OMX_ErrorUnsupportedSetting;
3568 }
3569 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3570 control.value = 1;
3571 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3572 if (rc < 0) {
3573 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3574 eRet = OMX_ErrorUnsupportedSetting;
3575 }
3576 }
3577 }
3578 break;
3579 }
Praveen Chavancf924182013-12-06 23:16:23 -08003580#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3581 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3582 {
3583 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3584 PrepareForAdaptivePlaybackParams* pParams =
3585 (PrepareForAdaptivePlaybackParams *) paramData;
3586 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3587 if (!pParams->bEnable) {
3588 return OMX_ErrorNone;
3589 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303590 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3591 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003592 DEBUG_PRINT_ERROR(
3593 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3594 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303595 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003596 eRet = OMX_ErrorBadParameter;
3597 } else {
3598 eRet = enable_smoothstreaming();
3599 if (eRet != OMX_ErrorNone) {
3600 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3601 eRet = OMX_ErrorHardware;
3602 } else {
3603 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3604 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3605 m_smoothstreaming_mode = true;
3606 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3607 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3608 }
Deepak Vermaf8771292014-02-03 12:22:50 +05303609 struct v4l2_format fmt;
3610 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
3611 m_smoothstreaming_width, m_smoothstreaming_height);
3612 eRet = is_video_session_supported();
3613 if (eRet)
3614 break;
3615 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3616 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3617 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3618 fmt.fmt.pix_mp.pixelformat = output_capability;
3619 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
3620 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
3621 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3622 if (ret) {
3623 DEBUG_PRINT_ERROR("Set Resolution failed");
3624 eRet = OMX_ErrorUnsupportedSetting;
3625 } else
3626 eRet = get_buffer_req(&drv_ctx.op_buf);
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303627 }
Praveen Chavancf924182013-12-06 23:16:23 -08003628 } else {
3629 DEBUG_PRINT_ERROR(
3630 "Prepare for adaptive playback supported only on output port");
3631 eRet = OMX_ErrorBadParameter;
3632 }
3633 break;
3634 }
3635
3636#endif
Arun Menon906de572013-06-18 17:01:40 -07003637 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003638 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003639 eRet = OMX_ErrorUnsupportedIndex;
3640 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003641 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003642 if (eRet != OMX_ErrorNone)
3643 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003644 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003645}
3646
3647/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003648 FUNCTION
3649 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003650
Arun Menon906de572013-06-18 17:01:40 -07003651 DESCRIPTION
3652 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653
Arun Menon906de572013-06-18 17:01:40 -07003654 PARAMETERS
3655 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003656
Arun Menon906de572013-06-18 17:01:40 -07003657 RETURN VALUE
3658 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003659
Arun Menon906de572013-06-18 17:01:40 -07003660 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003661OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003662 OMX_IN OMX_INDEXTYPE configIndex,
3663 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003664{
Arun Menon906de572013-06-18 17:01:40 -07003665 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003666
Arun Menon906de572013-06-18 17:01:40 -07003667 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003668 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003669 return OMX_ErrorInvalidState;
3670 }
Arun Menon906de572013-06-18 17:01:40 -07003671
3672 switch ((unsigned long)configIndex) {
3673 case OMX_QcomIndexConfigInterlaced: {
3674 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3675 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3676 if (configFmt->nPortIndex == 1) {
3677 if (configFmt->nIndex == 0) {
3678 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3679 } else if (configFmt->nIndex == 1) {
3680 configFmt->eInterlaceType =
3681 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3682 } else if (configFmt->nIndex == 2) {
3683 configFmt->eInterlaceType =
3684 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3685 } else {
3686 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003687 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003688 eRet = OMX_ErrorNoMore;
3689 }
3690
3691 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003692 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003693 (int)configFmt->nPortIndex);
3694 eRet = OMX_ErrorBadPortIndex;
3695 }
3696 break;
3697 }
3698 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3699 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3700 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3701 decoderinstances->nNumOfInstances = 16;
3702 /*TODO: How to handle this case */
3703 break;
3704 }
3705 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3706 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3707 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3708 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303709 memcpy(configFmt, &m_frame_pack_arrangement,
3710 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003711 } else {
3712 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3713 }
3714 break;
3715 }
3716 case OMX_IndexConfigCommonOutputCrop: {
3717 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3718 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3719 break;
3720 }
3721 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003722 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003723 eRet = OMX_ErrorBadParameter;
3724 }
3725
Shalaj Jain273b3e02012-06-22 19:08:03 -07003726 }
Arun Menon906de572013-06-18 17:01:40 -07003727
3728 return eRet;
3729}
3730
3731/* ======================================================================
3732 FUNCTION
3733 omx_vdec::SetConfig
3734
3735 DESCRIPTION
3736 OMX Set Config method implementation
3737
3738 PARAMETERS
3739 <TBD>.
3740
3741 RETURN VALUE
3742 OMX Error None if successful.
3743 ========================================================================== */
3744OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3745 OMX_IN OMX_INDEXTYPE configIndex,
3746 OMX_IN OMX_PTR configData)
3747{
3748 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003749 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003750 return OMX_ErrorInvalidState;
3751 }
3752
3753 OMX_ERRORTYPE ret = OMX_ErrorNone;
3754 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3755
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003756 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003757
3758 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3759 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003760 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003761 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003762 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003763 OMX_U32 extra_size;
3764 // Parsing done here for the AVC atom is definitely not generic
3765 // Currently this piece of code is working, but certainly
3766 // not tested with all .mp4 files.
3767 // Incase of failure, we might need to revisit this
3768 // for a generic piece of code.
3769
3770 // Retrieve size of NAL length field
3771 // byte #4 contains the size of NAL lenght field
3772 nal_length = (config->pData[4] & 0x03) + 1;
3773
3774 extra_size = 0;
3775 if (nal_length > 2) {
3776 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3777 extra_size = (nal_length - 2) * 2;
3778 }
3779
3780 // SPS starts from byte #6
3781 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3782 OMX_U8 *pDestBuf;
3783 m_vendor_config.nPortIndex = config->nPortIndex;
3784
3785 // minus 6 --> SPS starts from byte #6
3786 // minus 1 --> picture param set byte to be ignored from avcatom
3787 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3788 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3789 OMX_U32 len;
3790 OMX_U8 index = 0;
3791 // case where SPS+PPS is sent as part of set_config
3792 pDestBuf = m_vendor_config.pData;
3793
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003794 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003795 m_vendor_config.nPortIndex,
3796 m_vendor_config.nDataSize,
3797 m_vendor_config.pData);
3798 while (index < 2) {
3799 uint8 *psize;
3800 len = *pSrcBuf;
3801 len = len << 8;
3802 len |= *(pSrcBuf + 1);
3803 psize = (uint8 *) & len;
3804 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3805 for (unsigned int i = 0; i < nal_length; i++) {
3806 pDestBuf[i] = psize[nal_length - 1 - i];
3807 }
3808 //memcpy(pDestBuf,pSrcBuf,(len+2));
3809 pDestBuf += len + nal_length;
3810 pSrcBuf += len + 2;
3811 index++;
3812 pSrcBuf++; // skip picture param set
3813 len = 0;
3814 }
3815 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3816 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3817 m_vendor_config.nPortIndex = config->nPortIndex;
3818 m_vendor_config.nDataSize = config->nDataSize;
3819 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3820 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3821 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3822 if (m_vendor_config.pData) {
3823 free(m_vendor_config.pData);
3824 m_vendor_config.pData = NULL;
3825 m_vendor_config.nDataSize = 0;
3826 }
3827
3828 if (((*((OMX_U32 *) config->pData)) &
3829 VC1_SP_MP_START_CODE_MASK) ==
3830 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003831 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003832 m_vendor_config.nPortIndex = config->nPortIndex;
3833 m_vendor_config.nDataSize = config->nDataSize;
3834 m_vendor_config.pData =
3835 (OMX_U8 *) malloc(config->nDataSize);
3836 memcpy(m_vendor_config.pData, config->pData,
3837 config->nDataSize);
3838 m_vc1_profile = VC1_SP_MP_RCV;
3839 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003840 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003841 m_vendor_config.nPortIndex = config->nPortIndex;
3842 m_vendor_config.nDataSize = config->nDataSize;
3843 m_vendor_config.pData =
3844 (OMX_U8 *) malloc((config->nDataSize));
3845 memcpy(m_vendor_config.pData, config->pData,
3846 config->nDataSize);
3847 m_vc1_profile = VC1_AP;
3848 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003849 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003850 m_vendor_config.nPortIndex = config->nPortIndex;
3851 m_vendor_config.nDataSize = config->nDataSize;
3852 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3853 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3854 m_vc1_profile = VC1_SP_MP_RCV;
3855 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003856 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003857 }
3858 }
3859 return ret;
3860 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3861 struct v4l2_control temp;
3862 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3863
3864 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3865 switch (pNal->nNaluBytes) {
3866 case 0:
3867 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3868 break;
3869 case 2:
3870 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3871 break;
3872 case 4:
3873 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3874 break;
3875 default:
3876 return OMX_ErrorUnsupportedSetting;
3877 }
3878
3879 if (!arbitrary_bytes) {
3880 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3881 * with start code, so only need to notify driver in frame by frame mode */
3882 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3883 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3884 return OMX_ErrorHardware;
3885 }
3886 }
3887
3888 nal_length = pNal->nNaluBytes;
3889 m_frame_parser.init_nal_length(nal_length);
3890
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003891 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003892 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303893 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003894 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303895 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003896
3897 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3898 if (config->bEnabled) {
3899 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303900 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003901 config->nFps >> 16);
3902 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3903 drv_ctx.frame_rate.fps_denominator);
3904
3905 if (!drv_ctx.frame_rate.fps_numerator) {
3906 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3907 drv_ctx.frame_rate.fps_numerator = 30;
3908 }
3909
3910 if (drv_ctx.frame_rate.fps_denominator) {
3911 drv_ctx.frame_rate.fps_numerator = (int)
3912 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3913 }
3914
3915 drv_ctx.frame_rate.fps_denominator = 1;
3916 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3917 drv_ctx.frame_rate.fps_numerator;
3918
3919 struct v4l2_outputparm oparm;
3920 /*XXX: we're providing timing info as seconds per frame rather than frames
3921 * per second.*/
3922 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3923 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3924
3925 struct v4l2_streamparm sparm;
3926 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3927 sparm.parm.output = oparm;
3928 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3929 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3930 performance might be affected");
3931 ret = OMX_ErrorHardware;
3932 }
3933 client_set_fps = true;
3934 } else {
3935 DEBUG_PRINT_ERROR("Frame rate not supported.");
3936 ret = OMX_ErrorUnsupportedSetting;
3937 }
3938 } else {
3939 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3940 client_set_fps = false;
3941 }
3942 } else {
3943 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3944 (int)config->nPortIndex);
3945 ret = OMX_ErrorBadPortIndex;
3946 }
3947
3948 return ret;
3949 }
3950
3951 return OMX_ErrorNotImplemented;
3952}
3953
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303954#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3955
Arun Menon906de572013-06-18 17:01:40 -07003956/* ======================================================================
3957 FUNCTION
3958 omx_vdec::GetExtensionIndex
3959
3960 DESCRIPTION
3961 OMX GetExtensionIndex method implementaion. <TBD>
3962
3963 PARAMETERS
3964 <TBD>.
3965
3966 RETURN VALUE
3967 OMX Error None if everything successful.
3968
3969 ========================================================================== */
3970OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3971 OMX_IN OMX_STRING paramName,
3972 OMX_OUT OMX_INDEXTYPE* indexType)
3973{
3974 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003975 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003976 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303977 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003978 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303979 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003980 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303981 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3982 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3983 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3984 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003985 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
3986 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08003987 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
3988 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003989 }
3990#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303991 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003992 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303993 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003994 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303995 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003996 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003997 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303998 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003999 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4000 }
4001#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304002 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004003 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4004 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304005#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004006 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4007 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4008 }
4009#endif
Arun Menon906de572013-06-18 17:01:40 -07004010 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004011 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004012 return OMX_ErrorNotImplemented;
4013 }
4014 return OMX_ErrorNone;
4015}
4016
4017/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004018 FUNCTION
4019 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004020
Arun Menon906de572013-06-18 17:01:40 -07004021 DESCRIPTION
4022 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004023
Arun Menon906de572013-06-18 17:01:40 -07004024 PARAMETERS
4025 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004026
Arun Menon906de572013-06-18 17:01:40 -07004027 RETURN VALUE
4028 Error None if everything is successful.
4029 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004030OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004031 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004032{
Arun Menon906de572013-06-18 17:01:40 -07004033 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004034 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004035 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004036}
4037
4038/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004039 FUNCTION
4040 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004041
Arun Menon906de572013-06-18 17:01:40 -07004042 DESCRIPTION
4043 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004044
Arun Menon906de572013-06-18 17:01:40 -07004045 PARAMETERS
4046 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004047
Arun Menon906de572013-06-18 17:01:40 -07004048 RETURN VALUE
4049 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004050
Arun Menon906de572013-06-18 17:01:40 -07004051 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004052OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004053 OMX_IN OMX_U32 port,
4054 OMX_IN OMX_HANDLETYPE peerComponent,
4055 OMX_IN OMX_U32 peerPort,
4056 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004057{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004058 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004059 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004060}
4061
4062/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004063 FUNCTION
4064 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004065
Arun Menon906de572013-06-18 17:01:40 -07004066 DESCRIPTION
4067 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004068
Arun Menon906de572013-06-18 17:01:40 -07004069 PARAMETERS
4070 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004071
Arun Menon906de572013-06-18 17:01:40 -07004072 RETURN VALUE
4073 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004074
Arun Menon906de572013-06-18 17:01:40 -07004075 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004076OMX_ERRORTYPE omx_vdec::allocate_extradata()
4077{
4078#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004079 if (drv_ctx.extradata_info.buffer_size) {
4080 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4081 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4082 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4083 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004084 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004085 }
4086 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4087 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4088 drv_ctx.extradata_info.size, 4096,
4089 &drv_ctx.extradata_info.ion.ion_alloc_data,
4090 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4091 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004092 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004093 return OMX_ErrorInsufficientResources;
4094 }
4095 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4096 drv_ctx.extradata_info.size,
4097 PROT_READ|PROT_WRITE, MAP_SHARED,
4098 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4099 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004100 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004101 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4102 free_ion_memory(&drv_ctx.extradata_info.ion);
4103 return OMX_ErrorInsufficientResources;
4104 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004105 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004106#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304107 if (!m_other_extradata) {
4108 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4109 if (!m_other_extradata) {
4110 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4111 return OMX_ErrorInsufficientResources;
4112 }
4113 }
Arun Menon906de572013-06-18 17:01:40 -07004114 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004115}
4116
Arun Menon906de572013-06-18 17:01:40 -07004117void omx_vdec::free_extradata()
4118{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004119#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004120 if (drv_ctx.extradata_info.uaddr) {
4121 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4122 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4123 free_ion_memory(&drv_ctx.extradata_info.ion);
4124 }
4125 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004126#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304127 if (m_other_extradata) {
4128 free(m_other_extradata);
4129 m_other_extradata = NULL;
4130 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004131}
4132
Shalaj Jain273b3e02012-06-22 19:08:03 -07004133OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004134 OMX_IN OMX_HANDLETYPE hComp,
4135 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4136 OMX_IN OMX_U32 port,
4137 OMX_IN OMX_PTR appData,
4138 OMX_IN OMX_U32 bytes,
4139 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004140{
Arun Menon906de572013-06-18 17:01:40 -07004141 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4142 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4143 unsigned i= 0; // Temporary counter
4144 struct vdec_setbuffer_cmd setbuffers;
4145 OMX_PTR privateAppData = NULL;
4146 private_handle_t *handle = NULL;
4147 OMX_U8 *buff = buffer;
4148 struct v4l2_buffer buf;
4149 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4150 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004151
Arun Menon906de572013-06-18 17:01:40 -07004152 if (!m_out_mem_ptr) {
4153 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4154 eRet = allocate_output_headers();
4155 if (eRet == OMX_ErrorNone)
4156 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004158
Arun Menon906de572013-06-18 17:01:40 -07004159 if (eRet == OMX_ErrorNone) {
4160 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4161 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4162 break;
4163 }
4164 }
4165 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004166
Arun Menon906de572013-06-18 17:01:40 -07004167 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004168 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004169 eRet = OMX_ErrorInsufficientResources;
4170 }
4171
Arun Menonbdb80b02013-08-12 17:45:54 -07004172 if (dynamic_buf_mode) {
4173 *bufferHdr = (m_out_mem_ptr + i );
4174 (*bufferHdr)->pBuffer = NULL;
4175 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4176 enum v4l2_buf_type buf_type;
4177 int rr = 0;
4178 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4179 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4180 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4181 return OMX_ErrorInsufficientResources;
4182 } else {
4183 streaming[CAPTURE_PORT] = true;
4184 DEBUG_PRINT_LOW("STREAMON Successful");
4185 }
4186 }
4187 BITMASK_SET(&m_out_bm_count,i);
4188 (*bufferHdr)->pAppPrivate = appData;
4189 (*bufferHdr)->pBuffer = buffer;
4190 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4191 return eRet;
4192 }
Arun Menon906de572013-06-18 17:01:40 -07004193 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004194#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004195 if (m_enable_android_native_buffers) {
4196 if (m_use_android_native_buffers) {
4197 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4198 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4199 handle = (private_handle_t *)nBuf->handle;
4200 privateAppData = params->pAppPrivate;
4201 } else {
4202 handle = (private_handle_t *)buff;
4203 privateAppData = appData;
4204 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004205
Arun Menon906de572013-06-18 17:01:40 -07004206 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4207 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4208 " expected %u, got %lu",
4209 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4210 return OMX_ErrorBadParameter;
4211 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004212
Arun Menon906de572013-06-18 17:01:40 -07004213 if (!m_use_android_native_buffers) {
4214 if (!secure_mode) {
4215 buff = (OMX_U8*)mmap(0, handle->size,
4216 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4217 if (buff == MAP_FAILED) {
4218 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4219 return OMX_ErrorInsufficientResources;
4220 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004221 }
4222 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004223#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004224 native_buffer[i].nativehandle = handle;
4225 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226#endif
Arun Menon906de572013-06-18 17:01:40 -07004227 if (!handle) {
4228 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4229 return OMX_ErrorBadParameter;
4230 }
4231 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4232 drv_ctx.ptr_outputbuffer[i].offset = 0;
4233 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4234 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4235 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4236 } else
4237#endif
4238
4239 if (!ouput_egl_buffers && !m_use_output_pmem) {
4240#ifdef USE_ION
4241 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4242 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4243 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4244 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4245 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004246 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 -07004247 return OMX_ErrorInsufficientResources;
4248 }
4249 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4250 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4251#else
4252 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4253 open (MEM_DEVICE,O_RDWR);
4254
4255 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004256 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004257 return OMX_ErrorInsufficientResources;
4258 }
4259
4260 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4261 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4262 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4263 open (MEM_DEVICE,O_RDWR);
4264 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004265 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004266 return OMX_ErrorInsufficientResources;
4267 }
4268 }
4269
4270 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4271 drv_ctx.op_buf.buffer_size,
4272 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004273 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004274 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4275 return OMX_ErrorInsufficientResources;
4276 }
4277#endif
4278 if (!secure_mode) {
4279 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4280 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4281 PROT_READ|PROT_WRITE, MAP_SHARED,
4282 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4283 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4284 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4285#ifdef USE_ION
4286 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4287#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004288 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004289 return OMX_ErrorInsufficientResources;
4290 }
4291 }
4292 drv_ctx.ptr_outputbuffer[i].offset = 0;
4293 privateAppData = appData;
4294 } else {
4295
4296 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4297 if (!appData || !bytes ) {
4298 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004299 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004300 return OMX_ErrorBadParameter;
4301 }
4302 }
4303
4304 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4305 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4306 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4307 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4308 !pmem_list->nEntries ||
4309 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004310 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004311 return OMX_ErrorBadParameter;
4312 }
4313 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4314 pmem_list->entryList->entry;
4315 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4316 pmem_info->pmem_fd);
4317 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4318 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4319 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4320 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4321 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4322 privateAppData = appData;
4323 }
4324 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4325 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304326 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4327 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4328 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004329
4330 *bufferHdr = (m_out_mem_ptr + i );
4331 if (secure_mode)
4332 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4333 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4334 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4335 sizeof (vdec_bufferpayload));
4336
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004337 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004338 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4339 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4340
4341 buf.index = i;
4342 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4343 buf.memory = V4L2_MEMORY_USERPTR;
4344 plane[0].length = drv_ctx.op_buf.buffer_size;
4345 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4346 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4347 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4348 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4349 plane[0].data_offset = 0;
4350 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4351 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4352 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4353 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4354#ifdef USE_ION
4355 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4356#endif
4357 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4358 plane[extra_idx].data_offset = 0;
4359 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004360 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004361 return OMX_ErrorBadParameter;
4362 }
Arun Menon906de572013-06-18 17:01:40 -07004363 buf.m.planes = plane;
4364 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004365
Arun Menon906de572013-06-18 17:01:40 -07004366 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004367 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004368 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004370 }
4371
Arun Menon906de572013-06-18 17:01:40 -07004372 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4373 enum v4l2_buf_type buf_type;
4374 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4375 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4376 return OMX_ErrorInsufficientResources;
4377 } else {
4378 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004379 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004380 }
4381 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004382
Arun Menon906de572013-06-18 17:01:40 -07004383 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4384 if (m_enable_android_native_buffers) {
4385 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4386 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4387 } else {
4388 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004389 }
Arun Menon906de572013-06-18 17:01:40 -07004390 (*bufferHdr)->pAppPrivate = privateAppData;
4391 BITMASK_SET(&m_out_bm_count,i);
4392 }
4393 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004394}
4395
4396/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004397 FUNCTION
4398 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399
Arun Menon906de572013-06-18 17:01:40 -07004400 DESCRIPTION
4401 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004402
Arun Menon906de572013-06-18 17:01:40 -07004403 PARAMETERS
4404 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004405
Arun Menon906de572013-06-18 17:01:40 -07004406 RETURN VALUE
4407 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408
Arun Menon906de572013-06-18 17:01:40 -07004409 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004410OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004411 OMX_IN OMX_HANDLETYPE hComp,
4412 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4413 OMX_IN OMX_U32 port,
4414 OMX_IN OMX_PTR appData,
4415 OMX_IN OMX_U32 bytes,
4416 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004417{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004418 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004419 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4420 if (!m_inp_heap_ptr)
4421 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4422 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4423 drv_ctx.ip_buf.actualcount);
4424 if (!m_phdr_pmem_ptr)
4425 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4426 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4427 drv_ctx.ip_buf.actualcount);
4428 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4429 DEBUG_PRINT_ERROR("Insufficent memory");
4430 eRet = OMX_ErrorInsufficientResources;
4431 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4432 input_use_buffer = true;
4433 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4434 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4435 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4436 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4437 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4438 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4439 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4440 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004441 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 -07004442 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4443 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004444 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004445 return OMX_ErrorInsufficientResources;
4446 }
4447 m_in_alloc_cnt++;
4448 } else {
4449 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4450 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004451 }
Arun Menon906de572013-06-18 17:01:40 -07004452 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004453}
4454
4455/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004456 FUNCTION
4457 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004458
Arun Menon906de572013-06-18 17:01:40 -07004459 DESCRIPTION
4460 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004461
Arun Menon906de572013-06-18 17:01:40 -07004462 PARAMETERS
4463 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004464
Arun Menon906de572013-06-18 17:01:40 -07004465 RETURN VALUE
4466 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004467
Arun Menon906de572013-06-18 17:01:40 -07004468 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004469OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004470 OMX_IN OMX_HANDLETYPE hComp,
4471 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4472 OMX_IN OMX_U32 port,
4473 OMX_IN OMX_PTR appData,
4474 OMX_IN OMX_U32 bytes,
4475 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004476{
Arun Menon906de572013-06-18 17:01:40 -07004477 OMX_ERRORTYPE error = OMX_ErrorNone;
4478 struct vdec_setbuffer_cmd setbuffers;
4479
4480 if (bufferHdr == NULL || bytes == 0) {
4481 if (!secure_mode && buffer == NULL) {
4482 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4483 return OMX_ErrorBadParameter;
4484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004485 }
Arun Menon906de572013-06-18 17:01:40 -07004486 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004487 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004488 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004489 }
Arun Menon906de572013-06-18 17:01:40 -07004490 if (port == OMX_CORE_INPUT_PORT_INDEX)
4491 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4492 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4493 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4494 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004495 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004496 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004497 }
Arun Menon906de572013-06-18 17:01:40 -07004498 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4499 if (error == OMX_ErrorNone) {
4500 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4501 // Send the callback now
4502 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4503 post_event(OMX_CommandStateSet,OMX_StateIdle,
4504 OMX_COMPONENT_GENERATE_EVENT);
4505 }
4506 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4507 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4508 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4509 post_event(OMX_CommandPortEnable,
4510 OMX_CORE_INPUT_PORT_INDEX,
4511 OMX_COMPONENT_GENERATE_EVENT);
4512 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4513 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4514 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4515 post_event(OMX_CommandPortEnable,
4516 OMX_CORE_OUTPUT_PORT_INDEX,
4517 OMX_COMPONENT_GENERATE_EVENT);
4518 }
4519 }
4520 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521}
4522
4523OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004524 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004525{
Arun Menon906de572013-06-18 17:01:40 -07004526 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4527 if (m_inp_heap_ptr[bufferindex].pBuffer)
4528 free(m_inp_heap_ptr[bufferindex].pBuffer);
4529 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4530 }
4531 if (pmem_bufferHdr)
4532 free_input_buffer(pmem_bufferHdr);
4533 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004534}
4535
4536OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4537{
Arun Menon906de572013-06-18 17:01:40 -07004538 unsigned int index = 0;
4539 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4540 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004542
Arun Menon906de572013-06-18 17:01:40 -07004543 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004544 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004545
4546 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004547 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004548 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4549 struct vdec_setbuffer_cmd setbuffers;
4550 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4551 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4552 sizeof (vdec_bufferpayload));
4553 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004554 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004555 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004556 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004557 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4558 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4559 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4560 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4561 }
4562 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4563 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4564 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4565 free(m_desc_buffer_ptr[index].buf_addr);
4566 m_desc_buffer_ptr[index].buf_addr = NULL;
4567 m_desc_buffer_ptr[index].desc_data_size = 0;
4568 }
4569#ifdef USE_ION
4570 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4571#endif
4572 }
4573 }
4574
4575 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576}
4577
4578OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4579{
Arun Menon906de572013-06-18 17:01:40 -07004580 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004581
Arun Menon906de572013-06-18 17:01:40 -07004582 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4583 return OMX_ErrorBadParameter;
4584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585
Arun Menon906de572013-06-18 17:01:40 -07004586 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004587 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004588
Arun Menon906de572013-06-18 17:01:40 -07004589 if (index < drv_ctx.op_buf.actualcount
4590 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004591 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004592 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004593
Arun Menon906de572013-06-18 17:01:40 -07004594 struct vdec_setbuffer_cmd setbuffers;
4595 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4596 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4597 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004598
4599 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004600#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004601 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004602 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004603 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4604 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4605 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4606 }
Arun Menon906de572013-06-18 17:01:40 -07004607 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004608 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4609 } else {
4610#endif
4611 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4612 if (!secure_mode) {
4613 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4614 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4615 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4616 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4617 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4618 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4619 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4620 }
4621 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4622 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004623#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004624 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004625#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004627#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004628 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004629#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004630 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004631 if (release_output_done()) {
4632 free_extradata();
4633 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004634 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004635
Arun Menon906de572013-06-18 17:01:40 -07004636 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004637
4638}
4639
4640OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004641 OMX_BUFFERHEADERTYPE **bufferHdr,
4642 OMX_U32 port,
4643 OMX_PTR appData,
4644 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645{
Arun Menon906de572013-06-18 17:01:40 -07004646 OMX_BUFFERHEADERTYPE *input = NULL;
4647 unsigned char *buf_addr = NULL;
4648 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4649 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004650
Arun Menon906de572013-06-18 17:01:40 -07004651 /* Sanity Check*/
4652 if (bufferHdr == NULL) {
4653 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004654 }
4655
Arun Menon906de572013-06-18 17:01:40 -07004656 if (m_inp_heap_ptr == NULL) {
4657 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4658 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4659 drv_ctx.ip_buf.actualcount);
4660 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4661 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4662 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663
Arun Menon906de572013-06-18 17:01:40 -07004664 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004665 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004666 return OMX_ErrorInsufficientResources;
4667 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004669
Arun Menon906de572013-06-18 17:01:40 -07004670 /*Find a Free index*/
4671 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4672 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004673 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004674 break;
4675 }
4676 }
4677
4678 if (i < drv_ctx.ip_buf.actualcount) {
4679 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4680
4681 if (buf_addr == NULL) {
4682 return OMX_ErrorInsufficientResources;
4683 }
4684
4685 *bufferHdr = (m_inp_heap_ptr + i);
4686 input = *bufferHdr;
4687 BITMASK_SET(&m_heap_inp_bm_count,i);
4688
4689 input->pBuffer = (OMX_U8 *)buf_addr;
4690 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4691 input->nVersion.nVersion = OMX_SPEC_VERSION;
4692 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4693 input->pAppPrivate = appData;
4694 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004695 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004696 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004697 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004698 /*Add the Buffers to freeq*/
4699 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4700 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004701 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004702 return OMX_ErrorInsufficientResources;
4703 }
4704 } else {
4705 return OMX_ErrorBadParameter;
4706 }
4707
4708 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004709
4710}
4711
4712
4713/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004714 FUNCTION
4715 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004716
Arun Menon906de572013-06-18 17:01:40 -07004717 DESCRIPTION
4718 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004719
Arun Menon906de572013-06-18 17:01:40 -07004720 PARAMETERS
4721 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004722
Arun Menon906de572013-06-18 17:01:40 -07004723 RETURN VALUE
4724 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004725
Arun Menon906de572013-06-18 17:01:40 -07004726 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004727OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004728 OMX_IN OMX_HANDLETYPE hComp,
4729 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4730 OMX_IN OMX_U32 port,
4731 OMX_IN OMX_PTR appData,
4732 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004733{
4734
Arun Menon906de572013-06-18 17:01:40 -07004735 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4736 struct vdec_setbuffer_cmd setbuffers;
4737 OMX_BUFFERHEADERTYPE *input = NULL;
4738 unsigned i = 0;
4739 unsigned char *buf_addr = NULL;
4740 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004741
Arun Menon906de572013-06-18 17:01:40 -07004742 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004743 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004744 bytes, drv_ctx.ip_buf.buffer_size);
4745 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004746 }
4747
Arun Menon906de572013-06-18 17:01:40 -07004748 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004749 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004750 drv_ctx.ip_buf.actualcount,
4751 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004752
Arun Menon906de572013-06-18 17:01:40 -07004753 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4754 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4755
4756 if (m_inp_mem_ptr == NULL) {
4757 return OMX_ErrorInsufficientResources;
4758 }
4759
4760 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4761 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4762
4763 if (drv_ctx.ptr_inputbuffer == NULL) {
4764 return OMX_ErrorInsufficientResources;
4765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004766#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004767 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4768 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769
Arun Menon906de572013-06-18 17:01:40 -07004770 if (drv_ctx.ip_buf_ion_info == NULL) {
4771 return OMX_ErrorInsufficientResources;
4772 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004773#endif
4774
Arun Menon906de572013-06-18 17:01:40 -07004775 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4776 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004777#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004778 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004779#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004780 }
4781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782
Arun Menon906de572013-06-18 17:01:40 -07004783 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4784 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004785 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004786 break;
4787 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004788 }
Arun Menon906de572013-06-18 17:01:40 -07004789
4790 if (i < drv_ctx.ip_buf.actualcount) {
4791 struct v4l2_buffer buf;
4792 struct v4l2_plane plane;
4793 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004794 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004795#ifdef USE_ION
4796 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4797 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4798 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4799 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4800 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4801 return OMX_ErrorInsufficientResources;
4802 }
4803 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4804#else
4805 pmem_fd = open (MEM_DEVICE,O_RDWR);
4806
4807 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004808 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004809 return OMX_ErrorInsufficientResources;
4810 }
4811
4812 if (pmem_fd == 0) {
4813 pmem_fd = open (MEM_DEVICE,O_RDWR);
4814
4815 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004816 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004817 return OMX_ErrorInsufficientResources;
4818 }
4819 }
4820
4821 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4822 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004823 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004824 close(pmem_fd);
4825 return OMX_ErrorInsufficientResources;
4826 }
4827#endif
4828 if (!secure_mode) {
4829 buf_addr = (unsigned char *)mmap(NULL,
4830 drv_ctx.ip_buf.buffer_size,
4831 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4832
4833 if (buf_addr == MAP_FAILED) {
4834 close(pmem_fd);
4835#ifdef USE_ION
4836 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4837#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004838 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004839 return OMX_ErrorInsufficientResources;
4840 }
4841 }
4842 *bufferHdr = (m_inp_mem_ptr + i);
4843 if (secure_mode)
4844 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4845 else
4846 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4847 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4848 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4849 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4850 drv_ctx.ptr_inputbuffer [i].offset = 0;
4851
4852
4853 buf.index = i;
4854 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4855 buf.memory = V4L2_MEMORY_USERPTR;
4856 plane.bytesused = 0;
4857 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4858 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4859 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4860 plane.reserved[1] = 0;
4861 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4862 buf.m.planes = &plane;
4863 buf.length = 1;
4864
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004865 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004866 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4867
4868 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4869
4870 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004871 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004872 /*TODO: How to handle this case */
4873 return OMX_ErrorInsufficientResources;
4874 }
4875
4876 input = *bufferHdr;
4877 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004878 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004879 if (secure_mode)
4880 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4881 else
4882 input->pBuffer = (OMX_U8 *)buf_addr;
4883 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4884 input->nVersion.nVersion = OMX_SPEC_VERSION;
4885 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4886 input->pAppPrivate = appData;
4887 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4888 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4889
4890 if (drv_ctx.disable_dmx) {
4891 eRet = allocate_desc_buffer(i);
4892 }
4893 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004894 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004895 eRet = OMX_ErrorInsufficientResources;
4896 }
4897 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004898}
4899
4900
4901/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004902 FUNCTION
4903 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904
Arun Menon906de572013-06-18 17:01:40 -07004905 DESCRIPTION
4906 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004907
Arun Menon906de572013-06-18 17:01:40 -07004908 PARAMETERS
4909 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910
Arun Menon906de572013-06-18 17:01:40 -07004911 RETURN VALUE
4912 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004913
Arun Menon906de572013-06-18 17:01:40 -07004914 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004916 OMX_IN OMX_HANDLETYPE hComp,
4917 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4918 OMX_IN OMX_U32 port,
4919 OMX_IN OMX_PTR appData,
4920 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004921{
Arun Menon906de572013-06-18 17:01:40 -07004922 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4923 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4924 unsigned i= 0; // Temporary counter
4925 struct vdec_setbuffer_cmd setbuffers;
4926 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004928 int ion_device_fd =-1;
4929 struct ion_allocation_data ion_alloc_data;
4930 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004931#endif
Arun Menon906de572013-06-18 17:01:40 -07004932 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004933 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004934 drv_ctx.op_buf.actualcount,
4935 drv_ctx.op_buf.buffer_size);
4936 int nBufHdrSize = 0;
4937 int nPlatformEntrySize = 0;
4938 int nPlatformListSize = 0;
4939 int nPMEMInfoSize = 0;
4940 int pmem_fd = -1;
4941 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004942
Arun Menon906de572013-06-18 17:01:40 -07004943 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4944 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4945 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004946
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004947 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004948 drv_ctx.op_buf.actualcount);
4949 nBufHdrSize = drv_ctx.op_buf.actualcount *
4950 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004951
Arun Menon906de572013-06-18 17:01:40 -07004952 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4953 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4954 nPlatformListSize = drv_ctx.op_buf.actualcount *
4955 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4956 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4957 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004958
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004959 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004960 sizeof(OMX_BUFFERHEADERTYPE),
4961 nPMEMInfoSize,
4962 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004963 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004964 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004965#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004966 ion_device_fd = alloc_map_ion_memory(
4967 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4968 drv_ctx.op_buf.alignment,
4969 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4970 if (ion_device_fd < 0) {
4971 return OMX_ErrorInsufficientResources;
4972 }
4973 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004974#else
Arun Menon906de572013-06-18 17:01:40 -07004975 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976
Arun Menon906de572013-06-18 17:01:40 -07004977 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004978 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004979 drv_ctx.op_buf.buffer_size);
4980 return OMX_ErrorInsufficientResources;
4981 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982
Arun Menon906de572013-06-18 17:01:40 -07004983 if (pmem_fd == 0) {
4984 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004985
Arun Menon906de572013-06-18 17:01:40 -07004986 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004987 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004988 drv_ctx.op_buf.buffer_size);
4989 return OMX_ErrorInsufficientResources;
4990 }
4991 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004992
Arun Menon906de572013-06-18 17:01:40 -07004993 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4994 drv_ctx.op_buf.actualcount,
4995 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004996 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004997 close(pmem_fd);
4998 return OMX_ErrorInsufficientResources;
4999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000#endif
Arun Menon906de572013-06-18 17:01:40 -07005001 if (!secure_mode) {
5002 pmem_baseaddress = (unsigned char *)mmap(NULL,
5003 (drv_ctx.op_buf.buffer_size *
5004 drv_ctx.op_buf.actualcount),
5005 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5006 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005007 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005008 drv_ctx.op_buf.buffer_size);
5009 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005010#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005011 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005012#endif
Arun Menon906de572013-06-18 17:01:40 -07005013 return OMX_ErrorInsufficientResources;
5014 }
5015 }
5016 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5017 // Alloc mem for platform specific info
5018 char *pPtr=NULL;
5019 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5020 nPMEMInfoSize,1);
5021 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5022 calloc (sizeof(struct vdec_bufferpayload),
5023 drv_ctx.op_buf.actualcount);
5024 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5025 calloc (sizeof (struct vdec_output_frameinfo),
5026 drv_ctx.op_buf.actualcount);
5027#ifdef USE_ION
5028 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5029 calloc (sizeof(struct vdec_ion),
5030 drv_ctx.op_buf.actualcount);
5031#endif
5032
5033 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5034 && drv_ctx.ptr_respbuffer) {
5035 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5036 (drv_ctx.op_buf.buffer_size *
5037 drv_ctx.op_buf.actualcount);
5038 bufHdr = m_out_mem_ptr;
5039 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5040 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5041 (((char *) m_platform_list) + nPlatformListSize);
5042 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5043 (((char *) m_platform_entry) + nPlatformEntrySize);
5044 pPlatformList = m_platform_list;
5045 pPlatformEntry = m_platform_entry;
5046 pPMEMInfo = m_pmem_info;
5047
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005048 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005049
5050 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005051 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5052 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005053 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5054 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5055 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5056 // Set the values when we determine the right HxW param
5057 bufHdr->nAllocLen = bytes;
5058 bufHdr->nFilledLen = 0;
5059 bufHdr->pAppPrivate = appData;
5060 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5061 // Platform specific PMEM Information
5062 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005063 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005064 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5065 pPlatformEntry->entry = pPMEMInfo;
5066 // Initialize the Platform List
5067 pPlatformList->nEntries = 1;
5068 pPlatformList->entryList = pPlatformEntry;
5069 // Keep pBuffer NULL till vdec is opened
5070 bufHdr->pBuffer = NULL;
5071 bufHdr->nOffset = 0;
5072
5073 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5074 pPMEMInfo->pmem_fd = 0;
5075 bufHdr->pPlatformPrivate = pPlatformList;
5076
5077 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5078 m_pmem_info[i].pmem_fd = pmem_fd;
5079#ifdef USE_ION
5080 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5081 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5082 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5083#endif
5084
5085 /*Create a mapping between buffers*/
5086 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5087 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5088 &drv_ctx.ptr_outputbuffer[i];
5089 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5090 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5091 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305092 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5093 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5094 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005095
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005096 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005097 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5098 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5099 // Move the buffer and buffer header pointers
5100 bufHdr++;
5101 pPMEMInfo++;
5102 pPlatformEntry++;
5103 pPlatformList++;
5104 }
5105 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005106 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005107 m_out_mem_ptr, pPtr);
5108 if (m_out_mem_ptr) {
5109 free(m_out_mem_ptr);
5110 m_out_mem_ptr = NULL;
5111 }
5112 if (pPtr) {
5113 free(pPtr);
5114 pPtr = NULL;
5115 }
5116 if (drv_ctx.ptr_outputbuffer) {
5117 free(drv_ctx.ptr_outputbuffer);
5118 drv_ctx.ptr_outputbuffer = NULL;
5119 }
5120 if (drv_ctx.ptr_respbuffer) {
5121 free(drv_ctx.ptr_respbuffer);
5122 drv_ctx.ptr_respbuffer = NULL;
5123 }
5124#ifdef USE_ION
5125 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005126 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005127 free(drv_ctx.op_buf_ion_info);
5128 drv_ctx.op_buf_ion_info = NULL;
5129 }
5130#endif
5131 eRet = OMX_ErrorInsufficientResources;
5132 }
5133 if (eRet == OMX_ErrorNone)
5134 eRet = allocate_extradata();
5135 }
5136
5137 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5138 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005139 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005140 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005141 }
5142 }
Arun Menon906de572013-06-18 17:01:40 -07005143
5144 if (eRet == OMX_ErrorNone) {
5145 if (i < drv_ctx.op_buf.actualcount) {
5146 struct v4l2_buffer buf;
5147 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5148 int rc;
5149 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5150
5151 drv_ctx.ptr_outputbuffer[i].buffer_len =
5152 drv_ctx.op_buf.buffer_size;
5153
5154 *bufferHdr = (m_out_mem_ptr + i );
5155 if (secure_mode) {
5156 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5157 }
5158 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5159
5160 buf.index = i;
5161 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5162 buf.memory = V4L2_MEMORY_USERPTR;
5163 plane[0].length = drv_ctx.op_buf.buffer_size;
5164 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5165 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005166#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005167 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005168#endif
Arun Menon906de572013-06-18 17:01:40 -07005169 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5170 plane[0].data_offset = 0;
5171 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5172 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5173 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5174 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 -07005175#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005176 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005177#endif
Arun Menon906de572013-06-18 17:01:40 -07005178 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5179 plane[extra_idx].data_offset = 0;
5180 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005182 return OMX_ErrorBadParameter;
5183 }
5184 buf.m.planes = plane;
5185 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005186 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 -07005187 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5188 if (rc) {
5189 /*TODO: How to handle this case */
5190 return OMX_ErrorInsufficientResources;
5191 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192
Arun Menon906de572013-06-18 17:01:40 -07005193 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5194 enum v4l2_buf_type buf_type;
5195 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5196 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5197 if (rc) {
5198 return OMX_ErrorInsufficientResources;
5199 } else {
5200 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005201 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005202 }
5203 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204
Arun Menon906de572013-06-18 17:01:40 -07005205 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5206 (*bufferHdr)->pAppPrivate = appData;
5207 BITMASK_SET(&m_out_bm_count,i);
5208 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005209 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005210 eRet = OMX_ErrorInsufficientResources;
5211 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005212 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005213
Arun Menon906de572013-06-18 17:01:40 -07005214 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005215}
5216
5217
5218// AllocateBuffer -- API Call
5219/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005220 FUNCTION
5221 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005222
Arun Menon906de572013-06-18 17:01:40 -07005223 DESCRIPTION
5224 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005225
Arun Menon906de572013-06-18 17:01:40 -07005226 PARAMETERS
5227 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 RETURN VALUE
5230 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005231
Arun Menon906de572013-06-18 17:01:40 -07005232 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005234 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5235 OMX_IN OMX_U32 port,
5236 OMX_IN OMX_PTR appData,
5237 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005238{
5239 unsigned i = 0;
5240 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5241
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005242 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005243 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005244 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245 return OMX_ErrorInvalidState;
5246 }
5247
Arun Menon906de572013-06-18 17:01:40 -07005248 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5249 if (arbitrary_bytes) {
5250 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5251 } else {
5252 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5253 }
5254 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005255 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5256 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005257 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005258 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005259 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005260 }
5261 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005262 if (eRet == OMX_ErrorNone) {
5263 if (allocate_done()) {
5264 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005265 // Send the callback now
5266 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5267 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005268 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005269 }
5270 }
Arun Menon906de572013-06-18 17:01:40 -07005271 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5272 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5273 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5274 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005275 OMX_CORE_INPUT_PORT_INDEX,
5276 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005277 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005278 }
Arun Menon906de572013-06-18 17:01:40 -07005279 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5280 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5281 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005282 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005283 OMX_CORE_OUTPUT_PORT_INDEX,
5284 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005285 }
5286 }
5287 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005288 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005289 return eRet;
5290}
5291
5292// Free Buffer - API call
5293/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005294 FUNCTION
5295 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005296
Arun Menon906de572013-06-18 17:01:40 -07005297 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298
Arun Menon906de572013-06-18 17:01:40 -07005299 PARAMETERS
5300 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005301
Arun Menon906de572013-06-18 17:01:40 -07005302 RETURN VALUE
5303 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005304
Arun Menon906de572013-06-18 17:01:40 -07005305 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005306OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005307 OMX_IN OMX_U32 port,
5308 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005309{
5310 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5311 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005312 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005313
Arun Menon906de572013-06-18 17:01:40 -07005314 if (m_state == OMX_StateIdle &&
5315 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005316 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005317 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5318 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005319 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005320 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5321 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5322 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5323 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005324 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005325 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005326 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005328 OMX_ErrorPortUnpopulated,
5329 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005330
5331 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005332 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005333 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005334 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005335 OMX_ErrorPortUnpopulated,
5336 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005337 }
5338
Arun Menon906de572013-06-18 17:01:40 -07005339 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5340 /*Check if arbitrary bytes*/
5341 if (!arbitrary_bytes && !input_use_buffer)
5342 nPortIndex = buffer - m_inp_mem_ptr;
5343 else
5344 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005346 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005347 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5348 // Clear the bit associated with it.
5349 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5350 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5351 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005352
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005353 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005354 if (m_phdr_pmem_ptr)
5355 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5356 } else {
5357 if (arbitrary_bytes) {
5358 if (m_phdr_pmem_ptr)
5359 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5360 else
5361 free_input_buffer(nPortIndex,NULL);
5362 } else
5363 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005364 }
Arun Menon906de572013-06-18 17:01:40 -07005365 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305366 if(release_input_done())
5367 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005368 /*Free the Buffer Header*/
5369 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005370 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005371 free_input_buffer_header();
5372 }
5373 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005374 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005375 eRet = OMX_ErrorBadPortIndex;
5376 }
5377
Arun Menon906de572013-06-18 17:01:40 -07005378 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5379 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005380 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005381 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5382 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005383 OMX_CORE_INPUT_PORT_INDEX,
5384 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005385 }
Arun Menon906de572013-06-18 17:01:40 -07005386 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005387 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005388 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005389 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005390 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391 // Clear the bit associated with it.
5392 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5393 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005394 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395
Surajit Podder12aefac2013-08-06 18:43:32 +05305396 if(release_output_done()) {
5397 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5398 }
Arun Menon906de572013-06-18 17:01:40 -07005399 if (release_output_done()) {
5400 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401 }
Arun Menon906de572013-06-18 17:01:40 -07005402 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005403 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005404 eRet = OMX_ErrorBadPortIndex;
5405 }
Arun Menon906de572013-06-18 17:01:40 -07005406 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5407 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005408 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005410 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005411 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005412#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005413 if (m_enable_android_native_buffers) {
5414 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5415 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5416 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005417#endif
5418
Arun Menon906de572013-06-18 17:01:40 -07005419 post_event(OMX_CommandPortDisable,
5420 OMX_CORE_OUTPUT_PORT_INDEX,
5421 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005422 }
Arun Menon906de572013-06-18 17:01:40 -07005423 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005424 eRet = OMX_ErrorBadPortIndex;
5425 }
Arun Menon906de572013-06-18 17:01:40 -07005426 if ((eRet == OMX_ErrorNone) &&
5427 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5428 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005429 // Send the callback now
5430 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5431 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005432 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005433 }
5434 }
5435 return eRet;
5436}
5437
5438
5439/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005440 FUNCTION
5441 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005442
Arun Menon906de572013-06-18 17:01:40 -07005443 DESCRIPTION
5444 This routine is used to push the encoded video frames to
5445 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005446
Arun Menon906de572013-06-18 17:01:40 -07005447 PARAMETERS
5448 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449
Arun Menon906de572013-06-18 17:01:40 -07005450 RETURN VALUE
5451 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452
Arun Menon906de572013-06-18 17:01:40 -07005453 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005454OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005455 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005456{
Arun Menon906de572013-06-18 17:01:40 -07005457 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5458 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005459
Arun Menon906de572013-06-18 17:01:40 -07005460 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005461 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005462 return OMX_ErrorInvalidState;
5463 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005464
Arun Menon906de572013-06-18 17:01:40 -07005465 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005466 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005467 return OMX_ErrorBadParameter;
5468 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005469
Arun Menon906de572013-06-18 17:01:40 -07005470 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005471 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005472 return OMX_ErrorIncorrectStateOperation;
5473 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474
Arun Menon906de572013-06-18 17:01:40 -07005475 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005476 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005477 return OMX_ErrorBadPortIndex;
5478 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005479
5480#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005481 if (iDivXDrmDecrypt) {
5482 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5483 if (drmErr != OMX_ErrorNone) {
5484 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005485 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005489 if (perf_flag) {
5490 if (!latency) {
5491 dec_time.stop();
5492 latency = dec_time.processing_time_us();
5493 dec_time.start();
5494 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005496
Arun Menon906de572013-06-18 17:01:40 -07005497 if (arbitrary_bytes) {
5498 nBufferIndex = buffer - m_inp_heap_ptr;
5499 } else {
5500 if (input_use_buffer == true) {
5501 nBufferIndex = buffer - m_inp_heap_ptr;
5502 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5503 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5504 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5505 buffer = &m_inp_mem_ptr[nBufferIndex];
5506 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5507 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5508 } else {
5509 nBufferIndex = buffer - m_inp_mem_ptr;
5510 }
5511 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512
Arun Menon906de572013-06-18 17:01:40 -07005513 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005514 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005515 return OMX_ErrorBadParameter;
5516 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005517
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005518 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5519 codec_config_flag = true;
5520 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5521 }
5522
Arun Menon906de572013-06-18 17:01:40 -07005523 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5524 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5525 if (arbitrary_bytes) {
5526 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005528 } else {
Arun Menon906de572013-06-18 17:01:40 -07005529 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5530 }
5531 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005532}
5533
5534/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005535 FUNCTION
5536 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005537
Arun Menon906de572013-06-18 17:01:40 -07005538 DESCRIPTION
5539 This routine is used to push the encoded video frames to
5540 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005541
Arun Menon906de572013-06-18 17:01:40 -07005542 PARAMETERS
5543 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005544
Arun Menon906de572013-06-18 17:01:40 -07005545 RETURN VALUE
5546 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005547
Arun Menon906de572013-06-18 17:01:40 -07005548 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005550 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551{
Arun Menon906de572013-06-18 17:01:40 -07005552 int push_cnt = 0,i=0;
5553 unsigned nPortIndex = 0;
5554 OMX_ERRORTYPE ret = OMX_ErrorNone;
5555 struct vdec_input_frameinfo frameinfo;
5556 struct vdec_bufferpayload *temp_buffer;
5557 struct vdec_seqheader seq_header;
5558 bool port_setting_changed = true;
5559 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005560
Arun Menon906de572013-06-18 17:01:40 -07005561 /*Should we generate a Aync error event*/
5562 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005563 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005564 return OMX_ErrorBadParameter;
5565 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005566
Arun Menon906de572013-06-18 17:01:40 -07005567 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005568
Arun Menon906de572013-06-18 17:01:40 -07005569 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005570 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005571 nPortIndex);
5572 return OMX_ErrorBadParameter;
5573 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005574
Arun Menon906de572013-06-18 17:01:40 -07005575 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005576
Arun Menon906de572013-06-18 17:01:40 -07005577 /* return zero length and not an EOS buffer */
5578 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5579 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005580 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005581 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5582 OMX_COMPONENT_GENERATE_EBD);
5583 return OMX_ErrorNone;
5584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585
5586
Arun Menon906de572013-06-18 17:01:40 -07005587 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5588 mp4StreamType psBits;
5589 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5590 psBits.numBytes = buffer->nFilledLen;
5591 mp4_headerparser.parseHeader(&psBits);
5592 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5593 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5594 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005595 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005596 buffer->nFilledLen,frame_count);
5597 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005598 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005599 not_coded_vop = false;
5600 buffer->nFilledLen = 0;
5601 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602 }
5603 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604
Arun Menon906de572013-06-18 17:01:40 -07005605 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005606
Arun Menon906de572013-06-18 17:01:40 -07005607 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608
Arun Menon906de572013-06-18 17:01:40 -07005609 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005610 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005611 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5612 OMX_COMPONENT_GENERATE_EBD);
5613 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005614 }
5615
Arun Menon906de572013-06-18 17:01:40 -07005616 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005617
Surajit Podderd2644d52013-08-28 17:59:06 +05305618 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005619 return OMX_ErrorBadParameter;
5620 }
5621 /* If its first frame, H264 codec and reject is true, then parse the nal
5622 and get the profile. Based on this, reject the clip playback */
5623 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5624 m_reject_avc_1080p_mp) {
5625 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005626 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005627 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5628 NALU_TYPE_SPS);
5629 m_profile = h264_parser->get_profile();
5630 ret = is_video_session_supported();
5631 if (ret) {
5632 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5633 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5634 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5635 m_state = OMX_StateInvalid;
5636 return OMX_ErrorNone;
5637 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005638 }
5639
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005640 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005641 /*for use buffer we need to memcpy the data*/
5642 temp_buffer->buffer_len = buffer->nFilledLen;
5643
5644 if (input_use_buffer) {
5645 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5646 if (arbitrary_bytes) {
5647 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5648 } else {
5649 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5650 buffer->nFilledLen);
5651 }
5652 } else {
5653 return OMX_ErrorBadParameter;
5654 }
5655
5656 }
5657
5658 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5659 frameinfo.client_data = (void *) buffer;
5660 frameinfo.datalen = temp_buffer->buffer_len;
5661 frameinfo.flags = 0;
5662 frameinfo.offset = buffer->nOffset;
5663 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5664 frameinfo.pmem_offset = temp_buffer->offset;
5665 frameinfo.timestamp = buffer->nTimeStamp;
5666 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5667 DEBUG_PRINT_LOW("ETB: dmx enabled");
5668 if (m_demux_entries == 0) {
5669 extract_demux_addr_offsets(buffer);
5670 }
5671
5672 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5673 handle_demux_data(buffer);
5674 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5675 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5676 } else {
5677 frameinfo.desc_addr = NULL;
5678 frameinfo.desc_size = 0;
5679 }
5680 if (!arbitrary_bytes) {
5681 frameinfo.flags |= buffer->nFlags;
5682 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005683
5684#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005685 if (m_debug_timestamp) {
5686 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005687 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005688 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5689 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005690 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005691 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5692 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005693 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694#endif
5695
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005696log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005698if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005699 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5700 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5701 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702
Arun Menon906de572013-06-18 17:01:40 -07005703 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005704 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005705 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5706 h264_scratch.nFilledLen = 0;
5707 nal_count = 0;
5708 look_ahead_nal = false;
5709 frame_count = 0;
5710 if (m_frame_parser.mutils)
5711 m_frame_parser.mutils->initialize_frame_checking_environment();
5712 m_frame_parser.flush();
5713 h264_last_au_ts = LLONG_MAX;
5714 h264_last_au_flags = 0;
5715 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5716 m_demux_entries = 0;
5717 }
5718 struct v4l2_buffer buf;
5719 struct v4l2_plane plane;
5720 memset( (void *)&buf, 0, sizeof(buf));
5721 memset( (void *)&plane, 0, sizeof(plane));
5722 int rc;
5723 unsigned long print_count;
5724 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005725 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005726 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005727 }
5728 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5729 buf.index = nPortIndex;
5730 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5731 buf.memory = V4L2_MEMORY_USERPTR;
5732 plane.bytesused = temp_buffer->buffer_len;
5733 plane.length = drv_ctx.ip_buf.buffer_size;
5734 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5735 (unsigned long)temp_buffer->offset;
5736 plane.reserved[0] = temp_buffer->pmem_fd;
5737 plane.reserved[1] = temp_buffer->offset;
5738 plane.data_offset = 0;
5739 buf.m.planes = &plane;
5740 buf.length = 1;
5741 if (frameinfo.timestamp >= LLONG_MAX) {
5742 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5743 }
5744 //assumption is that timestamp is in milliseconds
5745 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5746 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5747 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5748 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005749
Arun Menon906de572013-06-18 17:01:40 -07005750 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5751 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005752 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005753 return OMX_ErrorHardware;
5754 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005755 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5756 codec_config_flag = false;
5757 }
Arun Menon906de572013-06-18 17:01:40 -07005758 if (!streaming[OUTPUT_PORT]) {
5759 enum v4l2_buf_type buf_type;
5760 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005761
Arun Menon906de572013-06-18 17:01:40 -07005762 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005763 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005764 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5765 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005766 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005767 streaming[OUTPUT_PORT] = true;
5768 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005769 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005770 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5771 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5772 OMX_COMPONENT_GENERATE_EBD);
5773 return OMX_ErrorBadParameter;
5774 }
5775 }
5776 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5777 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5778 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779
Arun Menon906de572013-06-18 17:01:40 -07005780 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005781}
5782
5783/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005784 FUNCTION
5785 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005786
Arun Menon906de572013-06-18 17:01:40 -07005787 DESCRIPTION
5788 IL client uses this method to release the frame buffer
5789 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 PARAMETERS
5792 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 RETURN VALUE
5795 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005796
Arun Menon906de572013-06-18 17:01:40 -07005797 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005799 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005800{
Arun Menonbdb80b02013-08-12 17:45:54 -07005801 if (dynamic_buf_mode) {
5802 private_handle_t *handle = NULL;
5803 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005804 unsigned int nPortIndex = 0;
5805
5806 if (!buffer || !buffer->pBuffer) {
5807 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5808 return OMX_ErrorBadParameter;
5809 }
5810
5811 //get the buffer type and fd info
5812 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5813 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005814 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5815
5816 if (!handle) {
5817 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5818 return OMX_ErrorBadParameter;
5819 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005820 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5821 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5822 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005823 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005824
5825 //Store private handle from GraphicBuffer
5826 native_buffer[nPortIndex].privatehandle = handle;
5827 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005828 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005829
Arun Menon906de572013-06-18 17:01:40 -07005830 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005831 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005832 return OMX_ErrorInvalidState;
5833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834
Arun Menon906de572013-06-18 17:01:40 -07005835 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005836 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005837 return OMX_ErrorIncorrectStateOperation;
5838 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005839
Arun Menon906de572013-06-18 17:01:40 -07005840 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305841 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005842 return OMX_ErrorBadParameter;
5843 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005844
Arun Menon906de572013-06-18 17:01:40 -07005845 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005846 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005847 return OMX_ErrorBadPortIndex;
5848 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005849
Arun Menon906de572013-06-18 17:01:40 -07005850 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5851 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5852 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005853}
5854/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005855 FUNCTION
5856 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005857
Arun Menon906de572013-06-18 17:01:40 -07005858 DESCRIPTION
5859 IL client uses this method to release the frame buffer
5860 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005861
Arun Menon906de572013-06-18 17:01:40 -07005862 PARAMETERS
5863 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005864
Arun Menon906de572013-06-18 17:01:40 -07005865 RETURN VALUE
5866 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005867
Arun Menon906de572013-06-18 17:01:40 -07005868 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005869OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005870 OMX_IN OMX_HANDLETYPE hComp,
5871 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005872{
Arun Menon906de572013-06-18 17:01:40 -07005873 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5874 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5875 unsigned nPortIndex = 0;
5876 struct vdec_fillbuffer_cmd fillbuffer;
5877 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5878 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005879
Arun Menon906de572013-06-18 17:01:40 -07005880 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005881
Arun Menon906de572013-06-18 17:01:40 -07005882 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5883 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005884
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005885 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005886 bufferAdd, bufferAdd->pBuffer);
5887 /*Return back the output buffer to client*/
5888 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005889 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005890 buffer->nFilledLen = 0;
5891 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5892 return OMX_ErrorNone;
5893 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005894
5895 if (dynamic_buf_mode) {
5896 //map the buffer handle based on the size set on output port definition.
5897 if (!secure_mode) {
5898 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5899 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5900 PROT_READ|PROT_WRITE, MAP_SHARED,
5901 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5902 }
5903 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5904 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5905 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5906 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5907 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5908 }
5909
Arun Menon906de572013-06-18 17:01:40 -07005910 pending_output_buffers++;
5911 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5912 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5913 if (ptr_respbuffer) {
5914 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916
Arun Menon906de572013-06-18 17:01:40 -07005917 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5918 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5919 buffer->nFilledLen = 0;
5920 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5921 pending_output_buffers--;
5922 return OMX_ErrorBadParameter;
5923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924
Arun Menon906de572013-06-18 17:01:40 -07005925 int rc = 0;
5926 struct v4l2_buffer buf;
5927 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5928 memset( (void *)&buf, 0, sizeof(buf));
5929 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5930 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005931
Arun Menon906de572013-06-18 17:01:40 -07005932 buf.index = nPortIndex;
5933 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5934 buf.memory = V4L2_MEMORY_USERPTR;
5935 plane[0].bytesused = buffer->nFilledLen;
5936 plane[0].length = drv_ctx.op_buf.buffer_size;
5937 plane[0].m.userptr =
5938 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5939 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5940 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5941 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5942 plane[0].data_offset = 0;
5943 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5944 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5945 plane[extra_idx].bytesused = 0;
5946 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5947 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 -07005948#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005949 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005950#endif
Arun Menon906de572013-06-18 17:01:40 -07005951 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5952 plane[extra_idx].data_offset = 0;
5953 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005954 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005955 return OMX_ErrorBadParameter;
5956 }
5957 buf.m.planes = plane;
5958 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005959 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005960 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5961
Arun Menon906de572013-06-18 17:01:40 -07005962 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5963 if (rc) {
5964 /*TODO: How to handle this case */
5965 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5966 }
Arun Menon906de572013-06-18 17:01:40 -07005967return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005968}
5969
5970/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005971 FUNCTION
5972 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005973
Arun Menon906de572013-06-18 17:01:40 -07005974 DESCRIPTION
5975 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005976
Arun Menon906de572013-06-18 17:01:40 -07005977 PARAMETERS
5978 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005979
Arun Menon906de572013-06-18 17:01:40 -07005980 RETURN VALUE
5981 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005982
Arun Menon906de572013-06-18 17:01:40 -07005983 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005984OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005985 OMX_IN OMX_CALLBACKTYPE* callbacks,
5986 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005987{
5988
Arun Menon906de572013-06-18 17:01:40 -07005989 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005990 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005991 m_cb.EventHandler,m_cb.FillBufferDone);
5992 m_app_data = appData;
5993 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005994}
5995
5996/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005997 FUNCTION
5998 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005999
Arun Menon906de572013-06-18 17:01:40 -07006000 DESCRIPTION
6001 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006002
Arun Menon906de572013-06-18 17:01:40 -07006003 PARAMETERS
6004 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006005
Arun Menon906de572013-06-18 17:01:40 -07006006 RETURN VALUE
6007 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006008
Arun Menon906de572013-06-18 17:01:40 -07006009 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6011{
6012#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006013 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006014 delete iDivXDrmDecrypt;
6015 iDivXDrmDecrypt=NULL;
6016 }
6017#endif //_ANDROID_
6018
Shalaj Jain286b0062013-02-21 20:35:48 -08006019 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006020 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006021 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006022 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006023 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006024 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006025 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006026 }
6027
6028 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006029 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006030 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006031 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6032 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033 }
6034#ifdef _ANDROID_ICS_
6035 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6036#endif
6037 }
6038
6039 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006040 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006041 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006042 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6043 if (m_inp_mem_ptr)
6044 free_input_buffer (i,&m_inp_mem_ptr[i]);
6045 else
6046 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006047 }
6048 }
6049 free_input_buffer_header();
6050 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006051 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006052 free(h264_scratch.pBuffer);
6053 h264_scratch.pBuffer = NULL;
6054 }
6055
Arun Menon906de572013-06-18 17:01:40 -07006056 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006058 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006059 }
6060
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006061 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006062 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006063 delete (m_frame_parser.mutils);
6064 m_frame_parser.mutils = NULL;
6065 }
6066
Arun Menon906de572013-06-18 17:01:40 -07006067 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006068 free(m_platform_list);
6069 m_platform_list = NULL;
6070 }
Arun Menon906de572013-06-18 17:01:40 -07006071 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072 free(m_vendor_config.pData);
6073 m_vendor_config.pData = NULL;
6074 }
6075
6076 // Reset counters in mesg queues
6077 m_ftb_q.m_size=0;
6078 m_cmd_q.m_size=0;
6079 m_etb_q.m_size=0;
6080 m_ftb_q.m_read = m_ftb_q.m_write =0;
6081 m_cmd_q.m_read = m_cmd_q.m_write =0;
6082 m_etb_q.m_read = m_etb_q.m_write =0;
6083#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006084 if (m_debug_timestamp) {
6085 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086 }
6087#endif
6088
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006089 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006090 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006091 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006092 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006093
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006094 if (m_debug.infile) {
6095 fclose(m_debug.infile);
6096 m_debug.infile = NULL;
6097 }
6098 if (m_debug.outfile) {
6099 fclose(m_debug.outfile);
6100 m_debug.outfile = NULL;
6101 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006102#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006103 if (outputExtradataFile)
6104 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006105#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006106 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006107 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108}
6109
6110/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006111 FUNCTION
6112 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113
Arun Menon906de572013-06-18 17:01:40 -07006114 DESCRIPTION
6115 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006116
Arun Menon906de572013-06-18 17:01:40 -07006117 PARAMETERS
6118 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006119
Arun Menon906de572013-06-18 17:01:40 -07006120 RETURN VALUE
6121 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006122
Arun Menon906de572013-06-18 17:01:40 -07006123 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006125 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6126 OMX_IN OMX_U32 port,
6127 OMX_IN OMX_PTR appData,
6128 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006129{
Arun Menon906de572013-06-18 17:01:40 -07006130 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6131 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6132 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006133
6134#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006135 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6136 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006137#else
Arun Menon906de572013-06-18 17:01:40 -07006138 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006139#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006140 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006141 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006142 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006143 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006145 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006146 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006148 }
6149 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6150 eglGetProcAddress("eglQueryImageKHR");
6151 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6152 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6153 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006154#else //with OMX test app
6155 struct temp_egl {
6156 int pmem_fd;
6157 int offset;
6158 };
6159 struct temp_egl *temp_egl_id = NULL;
6160 void * pmemPtr = (void *) eglImage;
6161 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006162 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006163 fd = temp_egl_id->pmem_fd;
6164 offset = temp_egl_id->offset;
6165 }
6166#endif
6167 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006168 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006169 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006170 }
6171 pmem_info.pmem_fd = (OMX_U32) fd;
6172 pmem_info.offset = (OMX_U32) offset;
6173 pmem_entry.entry = (void *) &pmem_info;
6174 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6175 pmem_list.entryList = &pmem_entry;
6176 pmem_list.nEntries = 1;
6177 ouput_egl_buffers = true;
6178 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6179 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6180 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006181 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006182 return OMX_ErrorInsufficientResources;
6183 }
6184 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006185}
6186
6187/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006188 FUNCTION
6189 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006190
Arun Menon906de572013-06-18 17:01:40 -07006191 DESCRIPTION
6192 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006193
Arun Menon906de572013-06-18 17:01:40 -07006194 PARAMETERS
6195 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006196
Arun Menon906de572013-06-18 17:01:40 -07006197 RETURN VALUE
6198 OMX Error None if everything is successful.
6199 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006200OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006201 OMX_OUT OMX_U8* role,
6202 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006203{
Arun Menon906de572013-06-18 17:01:40 -07006204 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006205
Arun Menon906de572013-06-18 17:01:40 -07006206 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6207 if ((0 == index) && role) {
6208 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006209 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006210 } else {
6211 eRet = OMX_ErrorNoMore;
6212 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213 }
Arun Menon906de572013-06-18 17:01:40 -07006214 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6215 if ((0 == index) && role) {
6216 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006217 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006218 } else {
6219 eRet = OMX_ErrorNoMore;
6220 }
6221 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6222 if ((0 == index) && role) {
6223 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006224 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006225 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006226 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006227 eRet = OMX_ErrorNoMore;
6228 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006230
Arun Menon906de572013-06-18 17:01:40 -07006231 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6232 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6233 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006234
Shalaj Jain273b3e02012-06-22 19:08:03 -07006235 {
Arun Menon906de572013-06-18 17:01:40 -07006236 if ((0 == index) && role) {
6237 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006238 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006239 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006240 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006241 eRet = OMX_ErrorNoMore;
6242 }
6243 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6244 if ((0 == index) && role) {
6245 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006246 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006247 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006248 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006249 eRet = OMX_ErrorNoMore;
6250 }
6251 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6252 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6253 ) {
6254 if ((0 == index) && role) {
6255 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006256 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006257 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006258 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006259 eRet = OMX_ErrorNoMore;
6260 }
6261 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6262 if ((0 == index) && role) {
6263 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006264 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006265 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006266 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006267 eRet = OMX_ErrorNoMore;
6268 }
6269 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006270 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006271 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006272 }
Arun Menon906de572013-06-18 17:01:40 -07006273 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006274}
6275
6276
6277
6278
6279/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006280 FUNCTION
6281 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006282
Arun Menon906de572013-06-18 17:01:40 -07006283 DESCRIPTION
6284 Checks if entire buffer pool is allocated by IL Client or not.
6285 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006286
Arun Menon906de572013-06-18 17:01:40 -07006287 PARAMETERS
6288 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006289
Arun Menon906de572013-06-18 17:01:40 -07006290 RETURN VALUE
6291 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006292
Arun Menon906de572013-06-18 17:01:40 -07006293 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006294bool omx_vdec::allocate_done(void)
6295{
Arun Menon906de572013-06-18 17:01:40 -07006296 bool bRet = false;
6297 bool bRet_In = false;
6298 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006299
Arun Menon906de572013-06-18 17:01:40 -07006300 bRet_In = allocate_input_done();
6301 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302
Arun Menon906de572013-06-18 17:01:40 -07006303 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006304 bRet = true;
6305 }
Arun Menon906de572013-06-18 17:01:40 -07006306
6307 return bRet;
6308}
6309/* ======================================================================
6310 FUNCTION
6311 omx_vdec::AllocateInputDone
6312
6313 DESCRIPTION
6314 Checks if I/P buffer pool is allocated by IL Client or not.
6315
6316 PARAMETERS
6317 None.
6318
6319 RETURN VALUE
6320 true/false.
6321
6322 ========================================================================== */
6323bool omx_vdec::allocate_input_done(void)
6324{
6325 bool bRet = false;
6326 unsigned i=0;
6327
6328 if (m_inp_mem_ptr == NULL) {
6329 return bRet;
6330 }
6331 if (m_inp_mem_ptr ) {
6332 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6333 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6334 break;
6335 }
6336 }
6337 }
6338 if (i == drv_ctx.ip_buf.actualcount) {
6339 bRet = true;
6340 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6341 }
6342 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6343 m_inp_bPopulated = OMX_TRUE;
6344 }
6345 return bRet;
6346}
6347/* ======================================================================
6348 FUNCTION
6349 omx_vdec::AllocateOutputDone
6350
6351 DESCRIPTION
6352 Checks if entire O/P buffer pool is allocated by IL Client or not.
6353
6354 PARAMETERS
6355 None.
6356
6357 RETURN VALUE
6358 true/false.
6359
6360 ========================================================================== */
6361bool omx_vdec::allocate_output_done(void)
6362{
6363 bool bRet = false;
6364 unsigned j=0;
6365
6366 if (m_out_mem_ptr == NULL) {
6367 return bRet;
6368 }
6369
6370 if (m_out_mem_ptr) {
6371 for (; j < drv_ctx.op_buf.actualcount; j++) {
6372 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6373 break;
6374 }
6375 }
6376 }
6377
6378 if (j == drv_ctx.op_buf.actualcount) {
6379 bRet = true;
6380 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6381 if (m_out_bEnabled)
6382 m_out_bPopulated = OMX_TRUE;
6383 }
6384
6385 return bRet;
6386}
6387
6388/* ======================================================================
6389 FUNCTION
6390 omx_vdec::ReleaseDone
6391
6392 DESCRIPTION
6393 Checks if IL client has released all the buffers.
6394
6395 PARAMETERS
6396 None.
6397
6398 RETURN VALUE
6399 true/false
6400
6401 ========================================================================== */
6402bool omx_vdec::release_done(void)
6403{
6404 bool bRet = false;
6405
6406 if (release_input_done()) {
6407 if (release_output_done()) {
6408 bRet = true;
6409 }
6410 }
6411 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006412}
6413
6414
6415/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006416 FUNCTION
6417 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006418
Arun Menon906de572013-06-18 17:01:40 -07006419 DESCRIPTION
6420 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006421
Arun Menon906de572013-06-18 17:01:40 -07006422 PARAMETERS
6423 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006424
Arun Menon906de572013-06-18 17:01:40 -07006425 RETURN VALUE
6426 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006427
Arun Menon906de572013-06-18 17:01:40 -07006428 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006429bool omx_vdec::release_output_done(void)
6430{
Arun Menon906de572013-06-18 17:01:40 -07006431 bool bRet = false;
6432 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006433
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006434 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006435 if (m_out_mem_ptr) {
6436 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6437 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6438 break;
6439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006440 }
Arun Menon906de572013-06-18 17:01:40 -07006441 if (j == drv_ctx.op_buf.actualcount) {
6442 m_out_bm_count = 0;
6443 bRet = true;
6444 }
6445 } else {
6446 m_out_bm_count = 0;
6447 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006448 }
Arun Menon906de572013-06-18 17:01:40 -07006449 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006450}
6451/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006452 FUNCTION
6453 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006454
Arun Menon906de572013-06-18 17:01:40 -07006455 DESCRIPTION
6456 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457
Arun Menon906de572013-06-18 17:01:40 -07006458 PARAMETERS
6459 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006460
Arun Menon906de572013-06-18 17:01:40 -07006461 RETURN VALUE
6462 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006463
Arun Menon906de572013-06-18 17:01:40 -07006464 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006465bool omx_vdec::release_input_done(void)
6466{
Arun Menon906de572013-06-18 17:01:40 -07006467 bool bRet = false;
6468 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006469
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006470 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006471 if (m_inp_mem_ptr) {
6472 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6473 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6474 break;
6475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006476 }
Arun Menon906de572013-06-18 17:01:40 -07006477 if (j==drv_ctx.ip_buf.actualcount) {
6478 bRet = true;
6479 }
6480 } else {
6481 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006482 }
Arun Menon906de572013-06-18 17:01:40 -07006483 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006484}
6485
6486OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006487 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006488{
Arun Menon906de572013-06-18 17:01:40 -07006489 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306490 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006491 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006492 return OMX_ErrorBadParameter;
6493 } else if (output_flush_progress) {
6494 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6495 buffer->nFilledLen = 0;
6496 buffer->nTimeStamp = 0;
6497 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6498 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6499 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006500 }
6501
Arun Menon906de572013-06-18 17:01:40 -07006502 if (m_debug_extradata) {
6503 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006504 DEBUG_PRINT_HIGH("");
6505 DEBUG_PRINT_HIGH("***************************************************");
6506 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6507 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006508 }
6509
6510 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006511 DEBUG_PRINT_HIGH("");
6512 DEBUG_PRINT_HIGH("***************************************************");
6513 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6514 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006515 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006516 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006517
6518
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006519 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006520 buffer, buffer->pBuffer);
6521 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006522
Arun Menon906de572013-06-18 17:01:40 -07006523 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006524 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006525 if (!output_flush_progress)
6526 post_event((unsigned)NULL, (unsigned)NULL,
6527 OMX_COMPONENT_GENERATE_EOS_DONE);
6528
6529 if (psource_frame) {
6530 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6531 psource_frame = NULL;
6532 }
6533 if (pdest_frame) {
6534 pdest_frame->nFilledLen = 0;
6535 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6536 (unsigned)NULL);
6537 pdest_frame = NULL;
6538 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006539 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006540
Shalaj Jain273b3e02012-06-22 19:08:03 -07006541
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006542 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6543 DEBUG_PRINT_LOW("Processing extradata");
6544 handle_extradata(buffer);
6545 }
6546
Arun Menon906de572013-06-18 17:01:40 -07006547 /* For use buffer we need to copy the data */
6548 if (!output_flush_progress) {
6549 /* This is the error check for non-recoverable errros */
6550 bool is_duplicate_ts_valid = true;
6551 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006552
Arun Menon906de572013-06-18 17:01:40 -07006553 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6554 output_capability == V4L2_PIX_FMT_MPEG2 ||
6555 output_capability == V4L2_PIX_FMT_DIVX ||
6556 output_capability == V4L2_PIX_FMT_DIVX_311)
6557 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006558
Arun Menon906de572013-06-18 17:01:40 -07006559 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006560 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006561 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306562 }
Arun Menon906de572013-06-18 17:01:40 -07006563 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306564
Arun Menon906de572013-06-18 17:01:40 -07006565 if (buffer->nFilledLen > 0) {
6566 time_stamp_dts.get_next_timestamp(buffer,
6567 is_interlaced && is_duplicate_ts_valid);
6568 if (m_debug_timestamp) {
6569 {
6570 OMX_TICKS expected_ts = 0;
6571 m_timestamp_list.pop_min_ts(expected_ts);
6572 if (is_interlaced && is_duplicate_ts_valid) {
6573 m_timestamp_list.pop_min_ts(expected_ts);
6574 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006575 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006576 buffer->nTimeStamp, expected_ts);
6577
6578 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006579 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006580 }
6581 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306582 }
Arun Menon906de572013-06-18 17:01:40 -07006583 } else {
Arun Menon906de572013-06-18 17:01:40 -07006584 time_stamp_dts.remove_time_stamp(
6585 buffer->nTimeStamp,
6586 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306587 }
Arun Menon906de572013-06-18 17:01:40 -07006588
6589
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006590 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006591
Arun Menon906de572013-06-18 17:01:40 -07006592 if (m_cb.FillBufferDone) {
6593 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006594 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006595 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006596 else
6597 set_frame_rate(buffer->nTimeStamp);
6598
Arun Menon906de572013-06-18 17:01:40 -07006599 if (perf_flag) {
6600 if (!proc_frms) {
6601 dec_time.stop();
6602 latency = dec_time.processing_time_us() - latency;
6603 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6604 dec_time.start();
6605 fps_metrics.start();
6606 }
6607 proc_frms++;
6608 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6609 OMX_U64 proc_time = 0;
6610 fps_metrics.stop();
6611 proc_time = fps_metrics.processing_time_us();
6612 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006613 proc_frms, (float)proc_time / 1e6,
6614 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006615 proc_frms = 0;
6616 }
6617 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006618
6619#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006620 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006621
Arun Menon906de572013-06-18 17:01:40 -07006622 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6623 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6624 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6625 buffer->nFilledLen + 3)&(~3));
6626 while (p_extra &&
6627 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006628 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006629 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6630 if (p_extra->eType == OMX_ExtraDataNone) {
6631 break;
6632 }
6633 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6634 }
6635 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006636#endif
Arun Menon906de572013-06-18 17:01:40 -07006637 }
6638 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6639 prev_ts = LLONG_MAX;
6640 rst_prev_ts = true;
6641 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006642
Arun Menon906de572013-06-18 17:01:40 -07006643 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6644 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6645 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006646 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006647 OMX_BUFFERHEADERTYPE *il_buffer;
6648 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006649
vivek mehta79cff222014-01-22 12:17:07 -08006650 if (il_buffer && m_last_rendered_TS >= 0) {
6651 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306652 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006653
6654 // Current frame can be send for rendering if
6655 // (a) current FPS is <= 60
6656 // (b) is the next frame after the frame with TS 0
6657 // (c) is the first frame after seek
6658 // (d) the delta TS b\w two consecutive frames is > 16 ms
6659 // (e) its TS is equal to previous frame TS
6660 // (f) if marked EOS
6661
6662 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6663 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6664 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006665 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006666 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006667 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006668 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006669 }
6670
6671 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6672 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6673 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006674 }
6675
vivek mehta79cff222014-01-22 12:17:07 -08006676 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006677 log_output_buffers(il_buffer);
6678 if (dynamic_buf_mode) {
6679 unsigned int nPortIndex = 0;
6680 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6681
6682 if (!secure_mode) {
6683 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6684 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6685 }
6686
6687 //Clear graphic buffer handles in dynamic mode
6688 native_buffer[nPortIndex].privatehandle = NULL;
6689 native_buffer[nPortIndex].nativehandle = NULL;
6690 }
Arun Menon906de572013-06-18 17:01:40 -07006691 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006692 } else {
Arun Menon906de572013-06-18 17:01:40 -07006693 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6694 return OMX_ErrorBadParameter;
6695 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006696 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006697 } else {
6698 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006699 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006700
Praveen Chavancf924182013-12-06 23:16:23 -08006701#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306702 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006703 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6704 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306705 private_handle_t *private_handle = NULL;
Praveen Chavancf924182013-12-06 23:16:23 -08006706 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6707 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306708 if (native_buffer[buf_index].privatehandle)
6709 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006710 if (private_handle) {
6711 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6712 dim.sliceWidth, dim.sliceHeight);
6713 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6714 }
6715 }
6716#endif
6717
Arun Menon906de572013-06-18 17:01:40 -07006718 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006719}
6720
6721OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006722 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006723{
6724
Surajit Podderd2644d52013-08-28 17:59:06 +05306725 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006726 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006727 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006728 }
6729
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006730 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006731 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006732 pending_input_buffers--;
6733
Arun Menon906de572013-06-18 17:01:40 -07006734 if (arbitrary_bytes) {
6735 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006736 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006737 pdest_frame = buffer;
6738 buffer->nFilledLen = 0;
6739 buffer->nTimeStamp = LLONG_MAX;
6740 push_input_buffer (hComp);
6741 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006742 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006743 buffer->nFilledLen = 0;
6744 if (!m_input_free_q.insert_entry((unsigned)buffer,
6745 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006746 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006747 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006748 }
Arun Menon906de572013-06-18 17:01:40 -07006749 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006750 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006751 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006752 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6753 }
6754 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6755 }
6756 return OMX_ErrorNone;
6757}
6758
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759int omx_vdec::async_message_process (void *context, void* message)
6760{
Arun Menon906de572013-06-18 17:01:40 -07006761 omx_vdec* omx = NULL;
6762 struct vdec_msginfo *vdec_msg = NULL;
6763 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6764 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6765 struct vdec_output_frameinfo *output_respbuf = NULL;
6766 int rc=1;
6767 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006768 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006769 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006770 }
Arun Menon906de572013-06-18 17:01:40 -07006771 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006772
Arun Menon906de572013-06-18 17:01:40 -07006773 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006774
Arun Menon906de572013-06-18 17:01:40 -07006775 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006776
Arun Menon906de572013-06-18 17:01:40 -07006777 case VDEC_MSG_EVT_HW_ERROR:
6778 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6779 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6780 break;
6781
6782 case VDEC_MSG_RESP_START_DONE:
6783 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6784 OMX_COMPONENT_GENERATE_START_DONE);
6785 break;
6786
6787 case VDEC_MSG_RESP_STOP_DONE:
6788 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6789 OMX_COMPONENT_GENERATE_STOP_DONE);
6790 break;
6791
6792 case VDEC_MSG_RESP_RESUME_DONE:
6793 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6794 OMX_COMPONENT_GENERATE_RESUME_DONE);
6795 break;
6796
6797 case VDEC_MSG_RESP_PAUSE_DONE:
6798 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6799 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6800 break;
6801
6802 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6803 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6804 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6805 break;
6806 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6807 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6808 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6809 break;
6810 case VDEC_MSG_RESP_INPUT_FLUSHED:
6811 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6812
6813 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6814 vdec_msg->msgdata.input_frame_clientdata; */
6815
6816 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6817 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6818 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306819 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006820 omxhdr = NULL;
6821 vdec_msg->status_code = VDEC_S_EFATAL;
6822 }
6823 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6824 DEBUG_PRINT_HIGH("Unsupported input");
6825 omx->omx_report_error ();
6826 }
6827 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6828 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6829 }
6830 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6831 OMX_COMPONENT_GENERATE_EBD);
6832 break;
6833 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6834 int64_t *timestamp;
6835 timestamp = (int64_t *) malloc(sizeof(int64_t));
6836 if (timestamp) {
6837 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6838 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6839 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006840 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006841 vdec_msg->msgdata.output_frame.time_stamp);
6842 }
6843 break;
6844 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6845 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6846
6847 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6848 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6849 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6850 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6851 vdec_msg->msgdata.output_frame.pic_type);
6852
6853 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306854 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006855 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306856 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006857 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6858 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6859 }
Arun Menon906de572013-06-18 17:01:40 -07006860 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6861 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6862 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6863 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6864 omxhdr->nFlags = 0;
6865
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006866 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006867 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6868 //rc = -1;
6869 }
6870 if (omxhdr->nFilledLen) {
6871 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6872 }
6873 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6874 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6875 } else {
6876 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6877 }
6878 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6879 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6880 }
6881 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6882 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6883 }
Arun Menon7b6fd642014-02-13 16:48:36 -08006884
6885 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
6886 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
6887 }
6888
Arun Menonbdb80b02013-08-12 17:45:54 -07006889 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006890 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006891 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6892 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6893 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006894 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6895 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6896 omxhdr->nOffset);
6897 }
Arun Menon906de572013-06-18 17:01:40 -07006898 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6899 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006900 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006901 omx->time_stamp_dts.remove_time_stamp(
6902 omxhdr->nTimeStamp,
6903 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6904 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006905 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6906 OMX_COMPONENT_GENERATE_FTB);
6907 break;
6908 }
6909 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6910 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6911 }
6912 vdec_msg->msgdata.output_frame.bufferaddr =
6913 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6914 int format_notably_changed = 0;
6915 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306916 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006917 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6918 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006919 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006920 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6921 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6922 format_notably_changed = 1;
6923 }
6924 }
6925 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6926 vdec_msg->msgdata.output_frame.framesize.left)
6927 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6928 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6929 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6930 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6931 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6932 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6933 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006934 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006935 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6936 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6937 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006938 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006939 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6940 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006941 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6942 omx->drv_ctx.video_resolution.frame_width) {
6943 vdec_msg->msgdata.output_frame.framesize.left = 0;
6944 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6945 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6946 }
6947 }
6948 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6949 omx->drv_ctx.video_resolution.frame_height) {
6950 vdec_msg->msgdata.output_frame.framesize.top = 0;
6951 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6952 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6953 }
6954 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006955 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 -07006956 vdec_msg->msgdata.output_frame.framesize.left,
6957 vdec_msg->msgdata.output_frame.framesize.top,
6958 vdec_msg->msgdata.output_frame.framesize.right,
6959 vdec_msg->msgdata.output_frame.framesize.bottom,
6960 omx->drv_ctx.video_resolution.frame_width,
6961 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006962 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6963 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6964 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6965 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6966 format_notably_changed = 1;
6967 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006968 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006969 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6970 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006971 if (format_notably_changed) {
6972 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306973 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006974 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6975 } else {
6976 if (!omx->client_buffers.update_buffer_req()) {
6977 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6978 }
6979 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6980 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6981 }
6982 }
6983 if (omxhdr->nFilledLen)
6984 omx->prev_n_filled_len = omxhdr->nFilledLen;
6985
6986 output_respbuf = (struct vdec_output_frameinfo *)\
6987 omxhdr->pOutputPortPrivate;
6988 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6989 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6990 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6991 output_respbuf->pic_type = PICTURE_TYPE_I;
6992 }
6993 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6994 output_respbuf->pic_type = PICTURE_TYPE_P;
6995 }
6996 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6997 output_respbuf->pic_type = PICTURE_TYPE_B;
6998 }
6999
7000 if (omx->output_use_buffer)
7001 memcpy ( omxhdr->pBuffer, (void *)
7002 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7003 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7004 vdec_msg->msgdata.output_frame.len);
7005 } else
7006 omxhdr->nFilledLen = 0;
7007 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7008 OMX_COMPONENT_GENERATE_FBD);
7009 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
7010 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7011 OMX_COMPONENT_GENERATE_EOS_DONE);
7012 else
7013 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7014 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7015 break;
7016 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007017 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007018 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7019 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7020 break;
7021 default:
7022 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007023 }
Arun Menon906de572013-06-18 17:01:40 -07007024 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007025}
7026
7027OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007028 OMX_HANDLETYPE hComp,
7029 OMX_BUFFERHEADERTYPE *buffer
7030 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007031{
Arun Menon906de572013-06-18 17:01:40 -07007032 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007033 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007034
Arun Menon906de572013-06-18 17:01:40 -07007035 if (buffer == NULL) {
7036 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007037 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007038 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7039 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007040 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7041
7042 /* return zero length and not an EOS buffer */
7043 /* return buffer if input flush in progress */
7044 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7045 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007046 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007047 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7048 return OMX_ErrorNone;
7049 }
7050
7051 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007052 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007053 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007054 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007055 push_input_buffer (hComp);
7056 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007057 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007058 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7059 (unsigned)NULL)) {
7060 return OMX_ErrorBadParameter;
7061 }
7062 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063
7064
Arun Menon906de572013-06-18 17:01:40 -07007065 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007066}
7067
7068OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7069{
Arun Menon906de572013-06-18 17:01:40 -07007070 unsigned address,p2,id;
7071 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007072
Arun Menon906de572013-06-18 17:01:40 -07007073 if (pdest_frame == NULL || psource_frame == NULL) {
7074 /*Check if we have a destination buffer*/
7075 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007076 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007077 if (m_input_free_q.m_size) {
7078 m_input_free_q.pop_entry(&address,&p2,&id);
7079 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7080 pdest_frame->nFilledLen = 0;
7081 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007082 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007083 }
7084 }
7085
7086 /*Check if we have a destination buffer*/
7087 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007088 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007089 if (m_input_pending_q.m_size) {
7090 m_input_pending_q.pop_entry(&address,&p2,&id);
7091 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007092 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007093 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007094 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007095 psource_frame->nFlags,psource_frame->nFilledLen);
7096
7097 }
7098 }
7099
Shalaj Jain273b3e02012-06-22 19:08:03 -07007100 }
7101
Arun Menon906de572013-06-18 17:01:40 -07007102 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7103 switch (codec_type_parse) {
7104 case CODEC_TYPE_MPEG4:
7105 case CODEC_TYPE_H263:
7106 case CODEC_TYPE_MPEG2:
7107 ret = push_input_sc_codec(hComp);
7108 break;
7109 case CODEC_TYPE_H264:
7110 ret = push_input_h264(hComp);
7111 break;
7112 case CODEC_TYPE_VC1:
7113 ret = push_input_vc1(hComp);
7114 break;
7115 default:
7116 break;
7117 }
7118 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007119 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007120 omx_report_error ();
7121 break;
7122 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007123 }
7124
Arun Menon906de572013-06-18 17:01:40 -07007125 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007126}
7127
7128OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7129{
Arun Menon906de572013-06-18 17:01:40 -07007130 OMX_U32 partial_frame = 1;
7131 OMX_BOOL generate_ebd = OMX_TRUE;
7132 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007133
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007134 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007135 psource_frame,psource_frame->nTimeStamp);
7136 if (m_frame_parser.parse_sc_frame(psource_frame,
7137 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007138 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007139 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007140 }
Arun Menon906de572013-06-18 17:01:40 -07007141
7142 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007143 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007144 pdest_frame->nFilledLen,psource_frame,frame_count);
7145
7146
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007147 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007148 /*First Parsed buffer will have only header Hence skip*/
7149 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007150 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007151
7152 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7153 codec_type_parse == CODEC_TYPE_DIVX) {
7154 mp4StreamType psBits;
7155 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7156 psBits.numBytes = pdest_frame->nFilledLen;
7157 mp4_headerparser.parseHeader(&psBits);
7158 }
7159
7160 frame_count++;
7161 } else {
7162 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7163 if (pdest_frame->nFilledLen) {
7164 /*Push the frame to the Decoder*/
7165 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7166 return OMX_ErrorBadParameter;
7167 }
7168 frame_count++;
7169 pdest_frame = NULL;
7170
7171 if (m_input_free_q.m_size) {
7172 m_input_free_q.pop_entry(&address,&p2,&id);
7173 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7174 pdest_frame->nFilledLen = 0;
7175 }
7176 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007177 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007178 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7179 (unsigned)NULL);
7180 pdest_frame = NULL;
7181 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007182 }
Arun Menon906de572013-06-18 17:01:40 -07007183 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007184 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007185 /*Check if Destination Buffer is full*/
7186 if (pdest_frame->nAllocLen ==
7187 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007188 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007189 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007190 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007191 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007192
Arun Menon906de572013-06-18 17:01:40 -07007193 if (psource_frame->nFilledLen == 0) {
7194 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7195 if (pdest_frame) {
7196 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007197 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007198 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007199 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007200 pdest_frame->nFilledLen,frame_count++);
7201 /*Push the frame to the Decoder*/
7202 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7203 return OMX_ErrorBadParameter;
7204 }
7205 frame_count++;
7206 pdest_frame = NULL;
7207 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007208 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007209 generate_ebd = OMX_FALSE;
7210 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007211 }
Arun Menon906de572013-06-18 17:01:40 -07007212 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007213 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007214 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7215 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007216
Arun Menon906de572013-06-18 17:01:40 -07007217 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007218 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007219 m_input_pending_q.pop_entry(&address,&p2,&id);
7220 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007221 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007222 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007223 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007224 psource_frame->nFlags,psource_frame->nFilledLen);
7225 }
7226 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007227 }
Arun Menon906de572013-06-18 17:01:40 -07007228 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007229}
7230
7231OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7232{
Arun Menon906de572013-06-18 17:01:40 -07007233 OMX_U32 partial_frame = 1;
7234 unsigned address = 0, p2 = 0, id = 0;
7235 OMX_BOOL isNewFrame = OMX_FALSE;
7236 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007237
Arun Menon906de572013-06-18 17:01:40 -07007238 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007240 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007241 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007242 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007243 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007244 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007245 if (h264_scratch.nFilledLen && look_ahead_nal) {
7246 look_ahead_nal = false;
7247 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7248 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007249 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7250 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7251 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007252 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007253 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007254 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007255 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007256 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007257 }
Arun Menon906de572013-06-18 17:01:40 -07007258 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007259
7260 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7261 in EOS flag getting associated with the destination
7262 */
7263 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7264 pdest_frame->nFilledLen) {
7265 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7266 generate_ebd = OMX_FALSE;
7267 }
7268
Arun Menon906de572013-06-18 17:01:40 -07007269 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007270 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007271 if (m_frame_parser.parse_sc_frame(psource_frame,
7272 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007274 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007275 }
Arun Menon906de572013-06-18 17:01:40 -07007276 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007277 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007278 if (m_frame_parser.parse_h264_nallength(psource_frame,
7279 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007280 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007281 return OMX_ErrorBadParameter;
7282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007284
Arun Menon906de572013-06-18 17:01:40 -07007285 if (partial_frame == 0) {
7286 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007287 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007288 nal_count++;
7289 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7290 h264_scratch.nFlags = psource_frame->nFlags;
7291 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007292 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007293 if (h264_scratch.nFilledLen) {
7294 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7295 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007296#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007297 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7298 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7299 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7300 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7301 // If timeinfo is present frame info from SEI is already processed
7302 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7303 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007304#endif
Arun Menon906de572013-06-18 17:01:40 -07007305 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7306 nal_count++;
7307 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7308 pdest_frame->nTimeStamp = h264_last_au_ts;
7309 pdest_frame->nFlags = h264_last_au_flags;
7310#ifdef PANSCAN_HDLR
7311 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7312 h264_parser->update_panscan_data(h264_last_au_ts);
7313#endif
7314 }
7315 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7316 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7317 h264_last_au_ts = h264_scratch.nTimeStamp;
7318 h264_last_au_flags = h264_scratch.nFlags;
7319#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7320 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7321 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7322 if (!VALID_TS(h264_last_au_ts))
7323 h264_last_au_ts = ts_in_sei;
7324 }
7325#endif
7326 } else
7327 h264_last_au_ts = LLONG_MAX;
7328 }
7329
7330 if (!isNewFrame) {
7331 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7332 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007333 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007334 h264_scratch.nFilledLen);
7335 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7336 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7337 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7338 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7339 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7340 h264_scratch.nFilledLen = 0;
7341 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007342 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007343 return OMX_ErrorBadParameter;
7344 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007345 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007346 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007347 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007348 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007349 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007350 pdest_frame->nFilledLen,frame_count++);
7351
7352 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007353 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007354 look_ahead_nal = false;
7355 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7356 h264_scratch.nFilledLen) {
7357 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7358 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7359 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7360 h264_scratch.nFilledLen = 0;
7361 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007362 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007363 return OMX_ErrorBadParameter;
7364 }
7365 } else {
7366 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007367 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007368 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7369 }
7370 /*Push the frame to the Decoder*/
7371 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7372 return OMX_ErrorBadParameter;
7373 }
7374 //frame_count++;
7375 pdest_frame = NULL;
7376 if (m_input_free_q.m_size) {
7377 m_input_free_q.pop_entry(&address,&p2,&id);
7378 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007379 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007380 pdest_frame->nFilledLen = 0;
7381 pdest_frame->nFlags = 0;
7382 pdest_frame->nTimeStamp = LLONG_MAX;
7383 }
7384 }
7385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007386 }
Arun Menon906de572013-06-18 17:01:40 -07007387 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007388 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007389 /*Check if Destination Buffer is full*/
7390 if (h264_scratch.nAllocLen ==
7391 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007392 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007393 return OMX_ErrorStreamCorrupt;
7394 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007395 }
Arun Menon906de572013-06-18 17:01:40 -07007396
7397 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007398 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007399
7400 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7401 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007402 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007403 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7404 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007405 if(pdest_frame->nFilledLen == 0) {
7406 /* No residual frame from before, send whatever
7407 * we have left */
7408 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7409 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7410 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7411 h264_scratch.nFilledLen = 0;
7412 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7413 } else {
7414 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7415 if(!isNewFrame) {
7416 /* Have a residual frame, but we know that the
7417 * AU in this frame is belonging to whatever
7418 * frame we had left over. So append it */
7419 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7420 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7421 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7422 h264_scratch.nFilledLen = 0;
7423 pdest_frame->nTimeStamp = h264_last_au_ts;
7424 } else {
7425 /* Completely new frame, let's just push what
7426 * we have now. The resulting EBD would trigger
7427 * another push */
7428 generate_ebd = OMX_FALSE;
7429 pdest_frame->nTimeStamp = h264_last_au_ts;
7430 h264_last_au_ts = h264_scratch.nTimeStamp;
7431 }
7432 }
Arun Menon906de572013-06-18 17:01:40 -07007433 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007434 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007435 return OMX_ErrorBadParameter;
7436 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007437
7438 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7439 if(generate_ebd == OMX_TRUE) {
7440 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7441 }
Arun Menon906de572013-06-18 17:01:40 -07007442
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007443 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007444 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007445 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007446#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7447 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7448 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7449 if (!VALID_TS(pdest_frame->nTimeStamp))
7450 pdest_frame->nTimeStamp = ts_in_sei;
7451 }
7452#endif
7453 /*Push the frame to the Decoder*/
7454 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7455 return OMX_ErrorBadParameter;
7456 }
7457 frame_count++;
7458 pdest_frame = NULL;
7459 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007460 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007461 pdest_frame,h264_scratch.nFilledLen);
7462 generate_ebd = OMX_FALSE;
7463 }
7464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007465 }
Arun Menon906de572013-06-18 17:01:40 -07007466 if (generate_ebd && !psource_frame->nFilledLen) {
7467 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7468 psource_frame = NULL;
7469 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007470 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007471 m_input_pending_q.pop_entry(&address,&p2,&id);
7472 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007473 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007474 psource_frame->nFlags,psource_frame->nFilledLen);
7475 }
7476 }
7477 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007478}
7479
7480OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7481{
7482 OMX_U8 *buf, *pdest;
7483 OMX_U32 partial_frame = 1;
7484 OMX_U32 buf_len, dest_len;
7485
Arun Menon906de572013-06-18 17:01:40 -07007486 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007487 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007488 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007489 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007490 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007491 buf = psource_frame->pBuffer;
7492 buf_len = psource_frame->nFilledLen;
7493
7494 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007495 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007496 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007497 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007498 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007499 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007500 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007501 return OMX_ErrorStreamCorrupt;
7502 }
Arun Menon906de572013-06-18 17:01:40 -07007503 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007504 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7505 pdest_frame->nOffset;
7506 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007507 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007508
Arun Menon906de572013-06-18 17:01:40 -07007509 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007510 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007511 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007512 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007513 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7514 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7515 }
7516 }
7517 }
7518
Arun Menon906de572013-06-18 17:01:40 -07007519 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007520 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007521 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007522 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007523 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007524 return OMX_ErrorBadParameter;
7525 }
Arun Menon906de572013-06-18 17:01:40 -07007526 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007527
7528 case VC1_SP_MP_RCV:
7529 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007530 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007531 return OMX_ErrorBadParameter;
7532 }
7533 return OMX_ErrorNone;
7534}
7535
David Ng38e2d232013-03-15 20:05:58 -07007536#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007537bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007538 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007539{
Arun Menon906de572013-06-18 17:01:40 -07007540 struct pmem_allocation allocation;
7541 allocation.size = buffer_size;
7542 allocation.align = clip2(alignment);
7543 if (allocation.align < 4096) {
7544 allocation.align = 4096;
7545 }
7546 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007547 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007548 allocation.align, allocation.size);
7549 return false;
7550 }
7551 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007552}
David Ng38e2d232013-03-15 20:05:58 -07007553#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007554#ifdef USE_ION
7555int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007556 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7557 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007558{
Arun Menon906de572013-06-18 17:01:40 -07007559 int fd = -EINVAL;
7560 int rc = -EINVAL;
7561 int ion_dev_flag;
7562 struct vdec_ion ion_buf_info;
7563 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007564 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007565 return -EINVAL;
7566 }
7567 ion_dev_flag = O_RDONLY;
7568 fd = open (MEM_DEVICE, ion_dev_flag);
7569 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007570 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007571 return fd;
7572 }
7573 alloc_data->flags = 0;
7574 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7575 alloc_data->flags |= ION_FLAG_CACHED;
7576 }
7577 alloc_data->len = buffer_size;
7578 alloc_data->align = clip2(alignment);
7579 if (alloc_data->align < 4096) {
7580 alloc_data->align = 4096;
7581 }
7582 if ((secure_mode) && (flag & ION_SECURE))
7583 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007584
Arun Menon906de572013-06-18 17:01:40 -07007585 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307586 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007587 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7588 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7589 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007590 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007591 alloc_data->handle = NULL;
7592 close(fd);
7593 fd = -ENOMEM;
7594 return fd;
7595 }
7596 fd_data->handle = alloc_data->handle;
7597 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7598 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007599 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007600 ion_buf_info.ion_alloc_data = *alloc_data;
7601 ion_buf_info.ion_device_fd = fd;
7602 ion_buf_info.fd_ion_data = *fd_data;
7603 free_ion_memory(&ion_buf_info);
7604 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007605 fd = -ENOMEM;
7606 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007607
Arun Menon906de572013-06-18 17:01:40 -07007608 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007609}
7610
Arun Menon906de572013-06-18 17:01:40 -07007611void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7612{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007613
Arun Menon906de572013-06-18 17:01:40 -07007614 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007615 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007616 return;
7617 }
7618 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7619 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007620 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007621 }
7622 close(buf_ion_info->ion_device_fd);
7623 buf_ion_info->ion_device_fd = -1;
7624 buf_ion_info->ion_alloc_data.handle = NULL;
7625 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007626}
7627#endif
7628void omx_vdec::free_output_buffer_header()
7629{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007630 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007631 output_use_buffer = false;
7632 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007633
Arun Menon906de572013-06-18 17:01:40 -07007634 if (m_out_mem_ptr) {
7635 free (m_out_mem_ptr);
7636 m_out_mem_ptr = NULL;
7637 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007638
Arun Menon906de572013-06-18 17:01:40 -07007639 if (m_platform_list) {
7640 free(m_platform_list);
7641 m_platform_list = NULL;
7642 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007643
Arun Menon906de572013-06-18 17:01:40 -07007644 if (drv_ctx.ptr_respbuffer) {
7645 free (drv_ctx.ptr_respbuffer);
7646 drv_ctx.ptr_respbuffer = NULL;
7647 }
7648 if (drv_ctx.ptr_outputbuffer) {
7649 free (drv_ctx.ptr_outputbuffer);
7650 drv_ctx.ptr_outputbuffer = NULL;
7651 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007652#ifdef USE_ION
7653 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007654 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007655 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007656 drv_ctx.op_buf_ion_info = NULL;
7657 }
7658#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007659 if (out_dynamic_list) {
7660 free(out_dynamic_list);
7661 out_dynamic_list = NULL;
7662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007663}
7664
7665void omx_vdec::free_input_buffer_header()
7666{
7667 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007668 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007669 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007670 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007671 free (m_inp_heap_ptr);
7672 m_inp_heap_ptr = NULL;
7673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007674
Arun Menon906de572013-06-18 17:01:40 -07007675 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007676 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007677 free (m_phdr_pmem_ptr);
7678 m_phdr_pmem_ptr = NULL;
7679 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007680 }
Arun Menon906de572013-06-18 17:01:40 -07007681 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007682 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007683 free (m_inp_mem_ptr);
7684 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007685 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007686 /* We just freed all the buffer headers, every thing in m_input_free_q,
7687 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007688 while (m_input_free_q.m_size) {
7689 unsigned address, p2, id;
7690 m_input_free_q.pop_entry(&address, &p2, &id);
7691 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007692 while (m_input_pending_q.m_size) {
7693 unsigned address, p2, id;
7694 m_input_pending_q.pop_entry(&address, &p2, &id);
7695 }
7696 pdest_frame = NULL;
7697 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007698 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007699 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007700 free (drv_ctx.ptr_inputbuffer);
7701 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007702 }
7703#ifdef USE_ION
7704 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007706 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007707 drv_ctx.ip_buf_ion_info = NULL;
7708 }
7709#endif
7710}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007711
7712int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007713{
Arun Menon906de572013-06-18 17:01:40 -07007714 enum v4l2_buf_type btype;
7715 int rc = 0;
7716 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007717
Arun Menon906de572013-06-18 17:01:40 -07007718 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7719 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7720 v4l2_port = OUTPUT_PORT;
7721 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7722 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7723 v4l2_port = CAPTURE_PORT;
7724 } else if (port == OMX_ALL) {
7725 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7726 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007727
Arun Menon906de572013-06-18 17:01:40 -07007728 if (!rc_input)
7729 return rc_input;
7730 else
7731 return rc_output;
7732 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007733
Arun Menon906de572013-06-18 17:01:40 -07007734 if (!streaming[v4l2_port]) {
7735 // already streamed off, warn and move on
7736 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7737 " which is already streamed off", v4l2_port);
7738 return 0;
7739 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007740
Arun Menon906de572013-06-18 17:01:40 -07007741 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007742
Arun Menon906de572013-06-18 17:01:40 -07007743 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7744 if (rc) {
7745 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007746 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007747 } else {
7748 streaming[v4l2_port] = false;
7749 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007750
Arun Menon906de572013-06-18 17:01:40 -07007751 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007752}
7753
7754OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7755{
Arun Menon906de572013-06-18 17:01:40 -07007756 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7757 struct v4l2_requestbuffers bufreq;
7758 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307759 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007760 struct v4l2_format fmt;
7761 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007762 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007763 buffer_prop->actualcount, buffer_prop->buffer_size);
7764 bufreq.memory = V4L2_MEMORY_USERPTR;
7765 bufreq.count = 1;
7766 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7767 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7768 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7769 fmt.fmt.pix_mp.pixelformat = output_capability;
7770 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7771 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7772 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7773 fmt.fmt.pix_mp.pixelformat = capture_capability;
7774 } else {
7775 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007776 }
Arun Menon906de572013-06-18 17:01:40 -07007777 if (eRet==OMX_ErrorNone) {
7778 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007779 }
Arun Menon906de572013-06-18 17:01:40 -07007780 if (ret) {
7781 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7782 /*TODO: How to handle this case */
7783 eRet = OMX_ErrorInsufficientResources;
7784 return eRet;
7785 } else {
7786 buffer_prop->actualcount = bufreq.count;
7787 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007788 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007789 }
Arun Menon906de572013-06-18 17:01:40 -07007790 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7791 buffer_prop->actualcount, buffer_prop->buffer_size);
7792
7793 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7794 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7795
7796 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7797
7798 update_resolution(fmt.fmt.pix_mp.width,
7799 fmt.fmt.pix_mp.height,
7800 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7801 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7802 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7803 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007804 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007805
7806 if (ret) {
7807 /*TODO: How to handle this case */
7808 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7809 eRet = OMX_ErrorInsufficientResources;
7810 } else {
7811 int extra_idx = 0;
7812
7813 eRet = is_video_session_supported();
7814 if (eRet)
7815 return eRet;
7816
7817 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7818 buf_size = buffer_prop->buffer_size;
7819 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7820 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7821 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7822 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007823 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007824 return OMX_ErrorBadParameter;
7825 }
7826 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7827 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7828 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7829 }
7830 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7831 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7832 }
7833 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7834 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007835 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007836 client_extra_data_size);
7837 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307838 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7839 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7840 DEBUG_PRINT_HIGH("framepack extradata enabled");
7841 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007842 if (client_extradata & OMX_QP_EXTRADATA) {
7843 client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
7844 DEBUG_PRINT_HIGH("QP extradata enabled");
7845 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08007846 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
7847 client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
7848 DEBUG_PRINT_HIGH("Input bits info extradata enabled");
7849 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007850
Arun Menon906de572013-06-18 17:01:40 -07007851 if (client_extra_data_size) {
7852 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7853 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7854 }
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307855 final_extra_data_size = (extra_data_size > client_extra_data_size ?
7856 extra_data_size : client_extra_data_size);
7857 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007858 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307859 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007860 buf_size += client_extra_data_size;
7861 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7862 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7863 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7864 if (in_reconfig) // BufReq will be set to driver when port is disabled
7865 buffer_prop->buffer_size = buf_size;
7866 else if (buf_size != buffer_prop->buffer_size) {
7867 buffer_prop->buffer_size = buf_size;
7868 eRet = set_buffer_req(buffer_prop);
7869 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007870 }
Arun Menon906de572013-06-18 17:01:40 -07007871 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7872 buffer_prop->actualcount, buffer_prop->buffer_size);
7873 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007874}
7875
7876OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7877{
Arun Menon906de572013-06-18 17:01:40 -07007878 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7879 unsigned buf_size = 0;
7880 struct v4l2_format fmt;
7881 struct v4l2_requestbuffers bufreq;
7882 int ret;
7883 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7884 buffer_prop->actualcount, buffer_prop->buffer_size);
7885 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7886 if (buf_size != buffer_prop->buffer_size) {
7887 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7888 buffer_prop->buffer_size, buf_size);
7889 eRet = OMX_ErrorBadParameter;
7890 } else {
7891 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7892 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007893
Arun Menon906de572013-06-18 17:01:40 -07007894 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7895 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7896 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007897 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007898 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7899 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7900 fmt.fmt.pix_mp.pixelformat = capture_capability;
7901 } else {
7902 eRet = OMX_ErrorBadParameter;
7903 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007904
Arun Menon906de572013-06-18 17:01:40 -07007905 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7906 if (ret) {
7907 /*TODO: How to handle this case */
7908 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7909 eRet = OMX_ErrorInsufficientResources;
7910 }
7911
7912 bufreq.memory = V4L2_MEMORY_USERPTR;
7913 bufreq.count = buffer_prop->actualcount;
7914 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7915 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7916 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7917 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7918 } else {
7919 eRet = OMX_ErrorBadParameter;
7920 }
7921
7922 if (eRet==OMX_ErrorNone) {
7923 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7924 }
7925
7926 if (ret) {
7927 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7928 /*TODO: How to handle this case */
7929 eRet = OMX_ErrorInsufficientResources;
7930 } else if (bufreq.count < buffer_prop->actualcount) {
7931 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7932 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7933 buffer_prop->actualcount, bufreq.count);
7934 eRet = OMX_ErrorInsufficientResources;
7935 } else {
7936 if (!client_buffers.update_buffer_req()) {
7937 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7938 eRet = OMX_ErrorInsufficientResources;
7939 }
7940 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007941 }
Arun Menon906de572013-06-18 17:01:40 -07007942 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007943}
7944
Shalaj Jain273b3e02012-06-22 19:08:03 -07007945OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7946{
Arun Menon906de572013-06-18 17:01:40 -07007947 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7948 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007949}
7950
7951OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7952{
Arun Menon906de572013-06-18 17:01:40 -07007953 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7954 if (!portDefn) {
7955 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007956 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007957 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007958 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7959 portDefn->nSize = sizeof(portDefn);
7960 portDefn->eDomain = OMX_PortDomainVideo;
7961 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08007962 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
7963 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07007964 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007965 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007966 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007967 }
Arun Menon906de572013-06-18 17:01:40 -07007968 if (0 == portDefn->nPortIndex) {
7969 portDefn->eDir = OMX_DirInput;
7970 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7971 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7972 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7973 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7974 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7975 portDefn->bEnabled = m_inp_bEnabled;
7976 portDefn->bPopulated = m_inp_bPopulated;
7977 } else if (1 == portDefn->nPortIndex) {
7978 unsigned int buf_size = 0;
7979 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007980 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007981 return OMX_ErrorHardware;
7982 }
7983 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007984 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007985 return OMX_ErrorHardware;
7986 }
7987 portDefn->nBufferSize = buf_size;
7988 portDefn->eDir = OMX_DirOutput;
7989 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7990 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7991 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7992 portDefn->bEnabled = m_out_bEnabled;
7993 portDefn->bPopulated = m_out_bPopulated;
7994 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007995 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007996 return OMX_ErrorHardware;
7997 }
7998 } else {
7999 portDefn->eDir = OMX_DirMax;
8000 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8001 (int)portDefn->nPortIndex);
8002 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008003 }
Arun Menon906de572013-06-18 17:01:40 -07008004 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8005 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8006 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8007 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praveen Chavandb7776f2014-02-06 18:17:25 -08008008 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8009 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308010 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8011 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8012 }
8013 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8014 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8015 portDefn->nPortIndex,
8016 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008017 portDefn->format.video.nFrameHeight,
8018 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308019 portDefn->format.video.nSliceHeight,
8020 portDefn->format.video.eColorFormat,
8021 portDefn->nBufferSize,
8022 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008023
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308024 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008025}
8026
8027OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8028{
Arun Menon906de572013-06-18 17:01:40 -07008029 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8030 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8031 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008032
Arun Menon906de572013-06-18 17:01:40 -07008033 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008034 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008035 int nBufHdrSize = 0;
8036 int nPlatformEntrySize = 0;
8037 int nPlatformListSize = 0;
8038 int nPMEMInfoSize = 0;
8039 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8040 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8041 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008042
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008043 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008044 drv_ctx.op_buf.actualcount);
8045 nBufHdrSize = drv_ctx.op_buf.actualcount *
8046 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008047
Arun Menon906de572013-06-18 17:01:40 -07008048 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8049 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8050 nPlatformListSize = drv_ctx.op_buf.actualcount *
8051 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8052 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8053 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008054
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008055 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008056 sizeof(OMX_BUFFERHEADERTYPE),
8057 nPMEMInfoSize,
8058 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008059 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008060 m_out_bm_count);
8061 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8062 // Alloc mem for platform specific info
8063 char *pPtr=NULL;
8064 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8065 nPMEMInfoSize,1);
8066 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8067 calloc (sizeof(struct vdec_bufferpayload),
8068 drv_ctx.op_buf.actualcount);
8069 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8070 calloc (sizeof (struct vdec_output_frameinfo),
8071 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008072#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008073 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8074 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008075#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008076 if (dynamic_buf_mode) {
8077 out_dynamic_list = (struct dynamic_buf_list *) \
8078 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8079 }
Arun Menon906de572013-06-18 17:01:40 -07008080 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8081 && drv_ctx.ptr_respbuffer) {
8082 bufHdr = m_out_mem_ptr;
8083 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8084 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8085 (((char *) m_platform_list) + nPlatformListSize);
8086 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8087 (((char *) m_platform_entry) + nPlatformEntrySize);
8088 pPlatformList = m_platform_list;
8089 pPlatformEntry = m_platform_entry;
8090 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008091
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008092 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008093
Arun Menon906de572013-06-18 17:01:40 -07008094 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008095 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008096 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008097 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008098 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8099 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8100 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8101 // Set the values when we determine the right HxW param
8102 bufHdr->nAllocLen = 0;
8103 bufHdr->nFilledLen = 0;
8104 bufHdr->pAppPrivate = NULL;
8105 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8106 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8107 pPlatformEntry->entry = pPMEMInfo;
8108 // Initialize the Platform List
8109 pPlatformList->nEntries = 1;
8110 pPlatformList->entryList = pPlatformEntry;
8111 // Keep pBuffer NULL till vdec is opened
8112 bufHdr->pBuffer = NULL;
8113 pPMEMInfo->offset = 0;
8114 pPMEMInfo->pmem_fd = 0;
8115 bufHdr->pPlatformPrivate = pPlatformList;
8116 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008117#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008118 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008119#endif
Arun Menon906de572013-06-18 17:01:40 -07008120 /*Create a mapping between buffers*/
8121 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8122 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8123 &drv_ctx.ptr_outputbuffer[i];
8124 // Move the buffer and buffer header pointers
8125 bufHdr++;
8126 pPMEMInfo++;
8127 pPlatformEntry++;
8128 pPlatformList++;
8129 }
8130 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008131 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008132 m_out_mem_ptr, pPtr);
8133 if (m_out_mem_ptr) {
8134 free(m_out_mem_ptr);
8135 m_out_mem_ptr = NULL;
8136 }
8137 if (pPtr) {
8138 free(pPtr);
8139 pPtr = NULL;
8140 }
8141 if (drv_ctx.ptr_outputbuffer) {
8142 free(drv_ctx.ptr_outputbuffer);
8143 drv_ctx.ptr_outputbuffer = NULL;
8144 }
8145 if (drv_ctx.ptr_respbuffer) {
8146 free(drv_ctx.ptr_respbuffer);
8147 drv_ctx.ptr_respbuffer = NULL;
8148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008149#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008150 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008151 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008152 free(drv_ctx.op_buf_ion_info);
8153 drv_ctx.op_buf_ion_info = NULL;
8154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008155#endif
Arun Menon906de572013-06-18 17:01:40 -07008156 eRet = OMX_ErrorInsufficientResources;
8157 }
8158 } else {
8159 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008160 }
Arun Menon906de572013-06-18 17:01:40 -07008161 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008162}
8163
8164void omx_vdec::complete_pending_buffer_done_cbs()
8165{
Arun Menon906de572013-06-18 17:01:40 -07008166 unsigned p1;
8167 unsigned p2;
8168 unsigned ident;
8169 omx_cmd_queue tmp_q, pending_bd_q;
8170 pthread_mutex_lock(&m_lock);
8171 // pop all pending GENERATE FDB from ftb queue
8172 while (m_ftb_q.m_size) {
8173 m_ftb_q.pop_entry(&p1,&p2,&ident);
8174 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8175 pending_bd_q.insert_entry(p1,p2,ident);
8176 } else {
8177 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008178 }
Arun Menon906de572013-06-18 17:01:40 -07008179 }
8180 //return all non GENERATE FDB to ftb queue
8181 while (tmp_q.m_size) {
8182 tmp_q.pop_entry(&p1,&p2,&ident);
8183 m_ftb_q.insert_entry(p1,p2,ident);
8184 }
8185 // pop all pending GENERATE EDB from etb queue
8186 while (m_etb_q.m_size) {
8187 m_etb_q.pop_entry(&p1,&p2,&ident);
8188 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8189 pending_bd_q.insert_entry(p1,p2,ident);
8190 } else {
8191 tmp_q.insert_entry(p1,p2,ident);
8192 }
8193 }
8194 //return all non GENERATE FDB to etb queue
8195 while (tmp_q.m_size) {
8196 tmp_q.pop_entry(&p1,&p2,&ident);
8197 m_etb_q.insert_entry(p1,p2,ident);
8198 }
8199 pthread_mutex_unlock(&m_lock);
8200 // process all pending buffer dones
8201 while (pending_bd_q.m_size) {
8202 pending_bd_q.pop_entry(&p1,&p2,&ident);
8203 switch (ident) {
8204 case OMX_COMPONENT_GENERATE_EBD:
8205 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008206 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008207 omx_report_error ();
8208 }
8209 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008210
Arun Menon906de572013-06-18 17:01:40 -07008211 case OMX_COMPONENT_GENERATE_FBD:
8212 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008213 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008214 omx_report_error ();
8215 }
8216 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008218 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008219}
8220
8221void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8222{
Arun Menon906de572013-06-18 17:01:40 -07008223 OMX_U32 new_frame_interval = 0;
8224 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8225 && llabs(act_timestamp - prev_ts) > 2000) {
8226 new_frame_interval = client_set_fps ? frm_int :
8227 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008228 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008229 frm_int = new_frame_interval;
8230 if (frm_int) {
8231 drv_ctx.frame_rate.fps_numerator = 1e6;
8232 drv_ctx.frame_rate.fps_denominator = frm_int;
8233 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8234 frm_int, drv_ctx.frame_rate.fps_numerator /
8235 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008236
Arun Menon906de572013-06-18 17:01:40 -07008237 /* We need to report the difference between this FBD and the previous FBD
8238 * back to the driver for clock scaling purposes. */
8239 struct v4l2_outputparm oparm;
8240 /*XXX: we're providing timing info as seconds per frame rather than frames
8241 * per second.*/
8242 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8243 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008244
Arun Menon906de572013-06-18 17:01:40 -07008245 struct v4l2_streamparm sparm;
8246 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8247 sparm.parm.output = oparm;
8248 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8249 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8250 performance might be affected");
8251 }
8252
8253 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008254 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008255 }
Arun Menon906de572013-06-18 17:01:40 -07008256 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008257}
8258
8259void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8260{
Arun Menon906de572013-06-18 17:01:40 -07008261 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8262 prev_ts = act_timestamp;
8263 rst_prev_ts = false;
8264 } else if (VALID_TS(prev_ts)) {
8265 bool codec_cond = (drv_ctx.timestamp_adjust)?
8266 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8267 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8268 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8269 if (frm_int > 0 && codec_cond) {
8270 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8271 act_timestamp = prev_ts + frm_int;
8272 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8273 prev_ts = act_timestamp;
8274 } else
8275 set_frame_rate(act_timestamp);
8276 } else if (frm_int > 0) // In this case the frame rate was set along
8277 { // with the port definition, start ts with 0
8278 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8279 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008280 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008281}
8282
8283void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8284{
Arun Menon906de572013-06-18 17:01:40 -07008285 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8286 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308287 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008288 OMX_U32 frame_rate = 0;
8289 int consumed_len = 0;
8290 OMX_U32 num_MB_in_frame;
8291 OMX_U32 recovery_sei_flags = 1;
8292 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008293
Arun Menon906de572013-06-18 17:01:40 -07008294 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008295 if (buf_index >= drv_ctx.extradata_info.count) {
8296 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8297 buf_index, drv_ctx.extradata_info.count);
8298 return;
8299 }
Arun Menon906de572013-06-18 17:01:40 -07008300 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8301 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8302 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308303
Arun Menon906de572013-06-18 17:01:40 -07008304 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308305 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008306 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008307 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308308 if (!secure_mode)
8309 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008310 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308311 else
8312 p_extra = m_other_extradata;
8313
Arun Menon906de572013-06-18 17:01:40 -07008314 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308315
8316 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008317 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308318 return;
8319 }
Arun Menon906de572013-06-18 17:01:40 -07008320 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8321 if (data) {
8322 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8323 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308324 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008325 DEBUG_PRINT_LOW("Invalid extra data size");
8326 break;
8327 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308328 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008329 switch ((unsigned long)data->eType) {
8330 case EXTRADATA_INTERLACE_VIDEO:
8331 struct msm_vidc_interlace_payload *payload;
8332 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008333 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008334 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008335 switch (payload->format) {
8336 case INTERLACE_FRAME_PROGRESSIVE:
8337 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8338 enable = 0;
8339 break;
8340 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8341 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8342 break;
8343 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8344 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8345 break;
8346 default:
8347 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8348 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8349 }
Arun Menon906de572013-06-18 17:01:40 -07008350 }
8351 if (m_enable_android_native_buffers)
8352 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8353 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308354 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008355 append_interlace_extradata(p_extra, payload->format,
8356 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008357 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8358 }
8359 break;
8360 case EXTRADATA_FRAME_RATE:
8361 struct msm_vidc_framerate_payload *frame_rate_payload;
8362 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8363 frame_rate = frame_rate_payload->frame_rate;
8364 break;
8365 case EXTRADATA_TIMESTAMP:
8366 struct msm_vidc_ts_payload *time_stamp_payload;
8367 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308368 time_stamp = time_stamp_payload->timestamp_lo;
8369 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8370 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008371 break;
8372 case EXTRADATA_NUM_CONCEALED_MB:
8373 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8374 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8375 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8376 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8377 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8378 break;
8379 case EXTRADATA_INDEX:
8380 int *etype;
8381 etype = (int *)(data->data);
8382 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8383 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8384 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8385 if (aspect_ratio_payload) {
8386 ((struct vdec_output_frameinfo *)
8387 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8388 ((struct vdec_output_frameinfo *)
8389 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8390 }
8391 }
8392 break;
8393 case EXTRADATA_RECOVERY_POINT_SEI:
8394 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8395 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8396 recovery_sei_flags = recovery_sei_payload->flags;
8397 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8398 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008399 DEBUG_PRINT_HIGH("");
8400 DEBUG_PRINT_HIGH("***************************************************");
8401 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8402 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008403 }
8404 break;
8405 case EXTRADATA_PANSCAN_WINDOW:
8406 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8407 break;
8408 case EXTRADATA_MPEG2_SEQDISP:
8409 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8410 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8411 if (seqdisp_payload) {
8412 m_disp_hor_size = seqdisp_payload->disp_width;
8413 m_disp_vert_size = seqdisp_payload->disp_height;
8414 }
8415 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308416 case EXTRADATA_S3D_FRAME_PACKING:
8417 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8418 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308419 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308420 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8421 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8422 }
8423 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008424 case EXTRADATA_FRAME_QP:
8425 struct msm_vidc_frame_qp_payload *qp_payload;
8426 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308427 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008428 append_qp_extradata(p_extra, qp_payload);
8429 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8430 }
8431 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008432 case EXTRADATA_FRAME_BITS_INFO:
8433 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8434 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308435 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008436 append_bitsinfo_extradata(p_extra, bits_info_payload);
8437 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8438 }
8439 break;
Arun Menon906de572013-06-18 17:01:40 -07008440 default:
8441 goto unrecognized_extradata;
8442 }
8443 consumed_len += data->nSize;
8444 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8445 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308446 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008447 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8448 append_frame_info_extradata(p_extra,
8449 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308450 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008451 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008452 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008453 }
8454 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008455unrecognized_extradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308456 if (client_extradata)
Arun Menon906de572013-06-18 17:01:40 -07008457 append_terminator_extradata(p_extra);
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308458 if (secure_mode) {
8459 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8460 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8461 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8462 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8463 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8464 }
Arun Menon906de572013-06-18 17:01:40 -07008465 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008466}
8467
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008468OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008469 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470{
Arun Menon906de572013-06-18 17:01:40 -07008471 OMX_ERRORTYPE ret = OMX_ErrorNone;
8472 struct v4l2_control control;
8473 if (m_state != OMX_StateLoaded) {
8474 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8475 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008476 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008477 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008478 client_extradata, requested_extradata, enable, is_internal);
8479
8480 if (!is_internal) {
8481 if (enable)
8482 client_extradata |= requested_extradata;
8483 else
8484 client_extradata = client_extradata & ~requested_extradata;
8485 }
8486
8487 if (enable) {
8488 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8489 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8490 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8491 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8492 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008493 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008494 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308495 }
8496 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008497 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8498 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8499 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008500 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008501 }
8502 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8503 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8504 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008505 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008506 }
8507 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8508 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8509 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008510 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008511 }
8512 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8513 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8514 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008515 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008516 }
8517 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8518 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8519 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008520 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008521 }
8522 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8523 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8524 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8525 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008526 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008527 }
8528 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308529 }
8530 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008531 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8532 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8533 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008534 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008535 }
8536 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308537 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8538 if (output_capability == V4L2_PIX_FMT_H264) {
8539 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8540 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8541 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8542 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8543 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8544 }
8545 } else {
8546 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8547 }
8548 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008549 if (requested_extradata & OMX_QP_EXTRADATA) {
8550 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8551 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8552 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8553 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8554 }
8555 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008556 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8557 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8558 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8559 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8560 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8561 }
8562 }
Arun Menon906de572013-06-18 17:01:40 -07008563 }
8564 ret = get_buffer_req(&drv_ctx.op_buf);
8565 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008566}
8567
8568OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8569{
Arun Menon906de572013-06-18 17:01:40 -07008570 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8571 OMX_U8 *data_ptr = extra->data, data = 0;
8572 while (byte_count < extra->nDataSize) {
8573 data = *data_ptr;
8574 while (data) {
8575 num_MB += (data&0x01);
8576 data >>= 1;
8577 }
8578 data_ptr++;
8579 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008580 }
Arun Menon906de572013-06-18 17:01:40 -07008581 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8582 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8583 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008584}
8585
8586void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8587{
Arun Menon906de572013-06-18 17:01:40 -07008588 if (!m_debug_extradata)
8589 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008590
8591 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308592 "============== Extra Data ==============\n"
8593 " Size: %lu\n"
8594 " Version: %lu\n"
8595 " PortIndex: %lu\n"
8596 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008597 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008598 extra->nSize, extra->nVersion.nVersion,
8599 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008600
Arun Menon906de572013-06-18 17:01:40 -07008601 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8602 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8603 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308604 "------ Interlace Format ------\n"
8605 " Size: %lu\n"
8606 " Version: %lu\n"
8607 " PortIndex: %lu\n"
8608 " Is Interlace Format: %d\n"
8609 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008610 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008611 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8612 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8613 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8614 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8615
8616 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308617 "-------- Frame Format --------\n"
8618 " Picture Type: %d\n"
8619 " Interlace Type: %d\n"
8620 " Pan Scan Total Frame Num: %lu\n"
8621 " Concealed Macro Blocks: %lu\n"
8622 " frame rate: %lu\n"
8623 " Time Stamp: %llu\n"
8624 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008625 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008626 fminfo->ePicType,
8627 fminfo->interlaceType,
8628 fminfo->panScan.numWindows,
8629 fminfo->nConcealedMacroblocks,
8630 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308631 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008632 fminfo->aspectRatio.aspectRatioX,
8633 fminfo->aspectRatio.aspectRatioY);
8634
8635 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8636 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008637 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308638 " Pan Scan Frame Num: %lu\n"
8639 " Rectangle x: %ld\n"
8640 " Rectangle y: %ld\n"
8641 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008642 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008643 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8644 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8645 }
8646
8647 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308648 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8649 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8650 DEBUG_PRINT_HIGH(
8651 "------------------ Framepack Format ----------\n"
8652 " id: %lu \n"
8653 " cancel_flag: %lu \n"
8654 " type: %lu \n"
8655 " quincunx_sampling_flagFormat: %lu \n"
8656 " content_interpretation_type: %lu \n"
8657 " content_interpretation_type: %lu \n"
8658 " spatial_flipping_flag: %lu \n"
8659 " frame0_flipped_flag: %lu \n"
8660 " field_views_flag: %lu \n"
8661 " current_frame_is_frame0_flag: %lu \n"
8662 " frame0_self_contained_flag: %lu \n"
8663 " frame1_self_contained_flag: %lu \n"
8664 " frame0_grid_position_x: %lu \n"
8665 " frame0_grid_position_y: %lu \n"
8666 " frame1_grid_position_x: %lu \n"
8667 " frame1_grid_position_y: %lu \n"
8668 " reserved_byte: %lu \n"
8669 " repetition_period: %lu \n"
8670 " extension_flag: %lu \n"
8671 "================== End of Framepack ===========",
8672 framepack->id,
8673 framepack->cancel_flag,
8674 framepack->type,
8675 framepack->quincunx_sampling_flag,
8676 framepack->content_interpretation_type,
8677 framepack->spatial_flipping_flag,
8678 framepack->frame0_flipped_flag,
8679 framepack->field_views_flag,
8680 framepack->current_frame_is_frame0_flag,
8681 framepack->frame0_self_contained_flag,
8682 framepack->frame1_self_contained_flag,
8683 framepack->frame0_grid_position_x,
8684 framepack->frame0_grid_position_y,
8685 framepack->frame1_grid_position_x,
8686 framepack->frame1_grid_position_y,
8687 framepack->reserved_byte,
8688 framepack->repetition_period,
8689 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008690 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8691 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8692 DEBUG_PRINT_HIGH(
8693 "---- QP (Frame quantization parameter) ----\n"
8694 " Frame QP: %lu \n"
8695 "================ End of QP ================\n",
8696 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008697 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8698 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8699 DEBUG_PRINT_HIGH(
8700 "--------- Input bits information --------\n"
8701 " Header bits: %lu \n"
8702 " Frame bits: %lu \n"
8703 "===== End of Input bits information =====\n",
8704 bits->header_bits, bits->frame_bits);
Arun Menon906de572013-06-18 17:01:40 -07008705 } else if (extra->eType == OMX_ExtraDataNone) {
8706 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8707 } else {
8708 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008710}
8711
8712void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08008713 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008714{
Arun Menon906de572013-06-18 17:01:40 -07008715 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08008716
Arun Menon906de572013-06-18 17:01:40 -07008717 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8718 return;
8719 }
8720 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8721 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8722 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8723 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8724 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8725 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8726 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8727 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8728 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08008729
8730 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07008731 interlace_format->bInterlaceFormat = OMX_FALSE;
8732 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8733 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008734 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008735 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008736 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008737 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008738 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008739 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008740 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008741 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008742 } else {
8743 interlace_format->bInterlaceFormat = OMX_TRUE;
8744 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8745 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8746 }
8747 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008748}
8749
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008750void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008751 struct vdec_aspectratioinfo *aspect_ratio_info,
8752 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008753{
Arun Menon906de572013-06-18 17:01:40 -07008754 m_extradata = frame_info;
8755 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8756 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308757 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008758 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008759}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008760
8761void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008762 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308763 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008764 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008765{
Arun Menon906de572013-06-18 17:01:40 -07008766 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8767 struct msm_vidc_panscan_window *panscan_window;
8768 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008769 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008770 }
Arun Menon906de572013-06-18 17:01:40 -07008771 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8772 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8773 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8774 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8775 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8776 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8777 switch (picture_type) {
8778 case PICTURE_TYPE_I:
8779 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8780 break;
8781 case PICTURE_TYPE_P:
8782 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8783 break;
8784 case PICTURE_TYPE_B:
8785 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8786 break;
8787 default:
8788 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8789 }
8790 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8791 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8792 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8793 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8794 else
8795 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8796 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8797 frame_info->nConcealedMacroblocks = num_conceal_mb;
8798 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308799 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008800 frame_info->panScan.numWindows = 0;
8801 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8802 if (m_disp_hor_size && m_disp_vert_size) {
8803 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8804 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05308805 } else {
8806 frame_info->displayAspectRatio.displayHorizontalSize = 0;
8807 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07008808 }
8809 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008810
Arun Menon906de572013-06-18 17:01:40 -07008811 if (panscan_payload) {
8812 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8813 panscan_window = &panscan_payload->wnd[0];
8814 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8815 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8816 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8817 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8818 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8819 panscan_window++;
8820 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008821 }
Arun Menon906de572013-06-18 17:01:40 -07008822 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8823 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008824}
8825
8826void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8827{
Arun Menon906de572013-06-18 17:01:40 -07008828 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8829 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8830 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8831 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8832 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8833 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8834 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8835 *portDefn = m_port_def;
8836 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008837 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008838 portDefn->format.video.nFrameWidth,
8839 portDefn->format.video.nStride,
8840 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008841}
8842
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308843void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8844 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8845{
8846 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8847 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8848 DEBUG_PRINT_ERROR("frame packing size mismatch");
8849 return;
8850 }
8851 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8852 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8853 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8854 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8855 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8856 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8857 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8858 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8859 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8860 memcpy(&framepack->id, s3d_frame_packing_payload,
8861 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8862 memcpy(&m_frame_pack_arrangement, framepack,
8863 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8864 print_debug_extradata(extra);
8865}
8866
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008867void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8868 struct msm_vidc_frame_qp_payload *qp_payload)
8869{
8870 OMX_QCOM_EXTRADATA_QP * qp = NULL;
8871 if (!qp_payload) {
8872 DEBUG_PRINT_ERROR("QP payload is NULL");
8873 return;
8874 }
8875 extra->nSize = OMX_QP_EXTRADATA_SIZE;
8876 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8877 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8878 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
8879 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
8880 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8881 qp->nQP = qp_payload->frame_qp;
8882 print_debug_extradata(extra);
8883}
8884
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008885void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8886 struct msm_vidc_frame_bits_info_payload *bits_payload)
8887{
8888 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
8889 if (!bits_payload) {
8890 DEBUG_PRINT_ERROR("bits info payload is NULL");
8891 return;
8892 }
8893 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
8894 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8895 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8896 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
8897 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
8898 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
8899 bits->frame_bits = bits_payload->frame_bits;
8900 bits->header_bits = bits_payload->header_bits;
8901 print_debug_extradata(extra);
8902}
8903
Shalaj Jain273b3e02012-06-22 19:08:03 -07008904void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8905{
Arun Menon906de572013-06-18 17:01:40 -07008906 if (!client_extradata) {
8907 return;
8908 }
8909 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8910 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8911 extra->eType = OMX_ExtraDataNone;
8912 extra->nDataSize = 0;
8913 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008914
Arun Menon906de572013-06-18 17:01:40 -07008915 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008916}
8917
8918OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8919{
Arun Menon906de572013-06-18 17:01:40 -07008920 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8921 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008922 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008923 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008924 }
Arun Menon906de572013-06-18 17:01:40 -07008925 if (m_desc_buffer_ptr == NULL) {
8926 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8927 calloc( (sizeof(desc_buffer_hdr)),
8928 drv_ctx.ip_buf.actualcount);
8929 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008930 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008931 return OMX_ErrorInsufficientResources;
8932 }
8933 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008934
Arun Menon906de572013-06-18 17:01:40 -07008935 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8936 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008937 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008938 return OMX_ErrorInsufficientResources;
8939 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008940
Arun Menon906de572013-06-18 17:01:40 -07008941 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008942}
8943
8944void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8945{
Arun Menon906de572013-06-18 17:01:40 -07008946 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8947 if (m_demux_entries < 8192) {
8948 m_demux_offsets[m_demux_entries++] = address_offset;
8949 }
8950 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008951}
8952
8953void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8954{
Arun Menon906de572013-06-18 17:01:40 -07008955 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8956 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8957 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008958
Arun Menon906de572013-06-18 17:01:40 -07008959 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008960
Arun Menon906de572013-06-18 17:01:40 -07008961 while (index < bytes_to_parse) {
8962 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8963 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8964 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8965 (buf[index+2] == 0x01)) ) {
8966 //Found start code, insert address offset
8967 insert_demux_addr_offset(index);
8968 if (buf[index+2] == 0x01) // 3 byte start code
8969 index += 3;
8970 else //4 byte start code
8971 index += 4;
8972 } else
8973 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008974 }
Arun Menon906de572013-06-18 17:01:40 -07008975 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8976 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008977}
8978
8979OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8980{
Arun Menon906de572013-06-18 17:01:40 -07008981 //fix this, handle 3 byte start code, vc1 terminator entry
8982 OMX_U8 *p_demux_data = NULL;
8983 OMX_U32 desc_data = 0;
8984 OMX_U32 start_addr = 0;
8985 OMX_U32 nal_size = 0;
8986 OMX_U32 suffix_byte = 0;
8987 OMX_U32 demux_index = 0;
8988 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008989
Arun Menon906de572013-06-18 17:01:40 -07008990 if (m_desc_buffer_ptr == NULL) {
8991 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8992 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008994
Arun Menon906de572013-06-18 17:01:40 -07008995 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8996 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8997 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8998 return OMX_ErrorBadParameter;
8999 }
9000
9001 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9002
9003 if ( ((OMX_U8*)p_demux_data == NULL) ||
9004 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9005 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9006 return OMX_ErrorBadParameter;
9007 } else {
9008 for (; demux_index < m_demux_entries; demux_index++) {
9009 desc_data = 0;
9010 start_addr = m_demux_offsets[demux_index];
9011 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9012 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9013 } else {
9014 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9015 }
9016 if (demux_index < (m_demux_entries - 1)) {
9017 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9018 } else {
9019 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9020 }
9021 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9022 (void *)start_addr,
9023 suffix_byte,
9024 nal_size,
9025 demux_index);
9026 desc_data = (start_addr >> 3) << 1;
9027 desc_data |= (start_addr & 7) << 21;
9028 desc_data |= suffix_byte << 24;
9029
9030 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9031 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9032 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9033 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9034
9035 p_demux_data += 16;
9036 }
9037 if (codec_type_parse == CODEC_TYPE_VC1) {
9038 DEBUG_PRINT_LOW("VC1 terminator entry");
9039 desc_data = 0;
9040 desc_data = 0x82 << 24;
9041 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9042 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9043 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9044 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9045 p_demux_data += 16;
9046 m_demux_entries++;
9047 }
9048 //Add zero word to indicate end of descriptors
9049 memset(p_demux_data, 0, sizeof(OMX_U32));
9050
9051 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9052 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9053 }
9054 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9055 m_demux_entries = 0;
9056 DEBUG_PRINT_LOW("Demux table complete!");
9057 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009058}
9059
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009060OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009061{
Arun Menon906de572013-06-18 17:01:40 -07009062 OMX_ERRORTYPE err = OMX_ErrorNone;
9063 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9064 if (iDivXDrmDecrypt) {
9065 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9066 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009067 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009068 delete iDivXDrmDecrypt;
9069 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009070 }
9071 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009072 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009073 err = OMX_ErrorUndefined;
9074 }
9075 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009076}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009077
Vinay Kaliada4f4422013-01-09 10:45:03 -08009078omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9079{
Arun Menon906de572013-06-18 17:01:40 -07009080 enabled = false;
9081 omx = NULL;
9082 init_members();
9083 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009084 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009085}
9086
9087void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9088{
Arun Menon906de572013-06-18 17:01:40 -07009089 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009090}
9091
Arun Menon906de572013-06-18 17:01:40 -07009092void omx_vdec::allocate_color_convert_buf::init_members()
9093{
9094 allocated_count = 0;
9095 buffer_size_req = 0;
9096 buffer_alignment_req = 0;
9097 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9098 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9099 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9100 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009101#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009102 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009103#endif
Arun Menon906de572013-06-18 17:01:40 -07009104 for (int i = 0; i < MAX_COUNT; i++)
9105 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009106}
9107
Arun Menon906de572013-06-18 17:01:40 -07009108omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9109{
9110 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009111}
9112
9113bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9114{
Arun Menon906de572013-06-18 17:01:40 -07009115 bool status = true;
9116 unsigned int src_size = 0, destination_size = 0;
9117 OMX_COLOR_FORMATTYPE drv_color_format;
9118 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009119 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009120 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009121 }
Arun Menon906de572013-06-18 17:01:40 -07009122 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009123 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009124 return status;
9125 }
9126 pthread_mutex_lock(&omx->c_lock);
9127 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9128 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009129 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009130 status = false;
9131 goto fail_update_buf_req;
9132 }
9133 c2d.close();
9134 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9135 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009136 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009137 if (status) {
9138 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9139 if (status)
9140 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9141 }
9142 if (status) {
9143 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9144 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009145 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009146 "driver size %d destination size %d",
9147 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9148 status = false;
9149 c2d.close();
9150 buffer_size_req = 0;
9151 } else {
9152 buffer_size_req = destination_size;
9153 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9154 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9155 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9156 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9157 }
9158 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009159fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009160 pthread_mutex_unlock(&omx->c_lock);
9161 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009162}
9163
9164bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009165 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009166{
Arun Menon906de572013-06-18 17:01:40 -07009167 bool status = true;
9168 OMX_COLOR_FORMATTYPE drv_color_format;
9169 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009170 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009171 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009172 }
Arun Menon906de572013-06-18 17:01:40 -07009173 pthread_mutex_lock(&omx->c_lock);
9174 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9175 drv_color_format = (OMX_COLOR_FORMATTYPE)
9176 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9177 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009178 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009179 status = false;
9180 }
9181 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009182 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009183 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9184 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009185 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009186 status = false;
9187 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009188 ColorFormat = dest_color_format;
9189 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9190 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009191 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 {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009432 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9433 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9434 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009435 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009436 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009437 }
9438 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009439}
Arun Menonbdb80b02013-08-12 17:45:54 -07009440
Arun Menonbdb80b02013-08-12 17:45:54 -07009441void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9442{
9443 int i = 0;
9444 bool buf_present = false;
9445 pthread_mutex_lock(&m_lock);
9446 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9447 //check the buffer fd, offset, uv addr with list contents
9448 //If present increment reference.
9449 if ((out_dynamic_list[i].fd == fd) &&
9450 (out_dynamic_list[i].offset == offset)) {
9451 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009452 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009453 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9454 buf_present = true;
9455 break;
9456 }
9457 }
9458 if (!buf_present) {
9459 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9460 //search for a entry to insert details of the new buffer
9461 if (out_dynamic_list[i].dup_fd == 0) {
9462 out_dynamic_list[i].fd = fd;
9463 out_dynamic_list[i].offset = offset;
9464 out_dynamic_list[i].dup_fd = dup(fd);
9465 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009466 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009467 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9468 break;
9469 }
9470 }
9471 }
9472 pthread_mutex_unlock(&m_lock);
9473}
9474
9475void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9476{
9477 int i = 0;
9478 pthread_mutex_lock(&m_lock);
9479 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9480 //check the buffer fd, offset, uv addr with list contents
9481 //If present decrement reference.
9482 if ((out_dynamic_list[i].fd == fd) &&
9483 (out_dynamic_list[i].offset == offset)) {
9484 out_dynamic_list[i].ref_count--;
9485 if (out_dynamic_list[i].ref_count == 0) {
9486 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009487 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009488 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9489 out_dynamic_list[i].dup_fd = 0;
9490 out_dynamic_list[i].fd = 0;
9491 out_dynamic_list[i].offset = 0;
9492 }
9493 break;
9494 }
9495 }
9496 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009497 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009498 }
9499 pthread_mutex_unlock(&m_lock);
9500}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009501
9502#ifdef _MSM8974_
9503void omx_vdec::send_codec_config() {
9504 if (codec_config_flag) {
9505 unsigned p1 = 0; // Parameter - 1
9506 unsigned p2 = 0; // Parameter - 2
9507 unsigned ident = 0;
9508 pthread_mutex_lock(&m_lock);
9509 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9510 while (m_etb_q.m_size) {
9511 m_etb_q.pop_entry(&p1,&p2,&ident);
9512 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9513 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9514 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9515 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9516 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9517 omx_report_error();
9518 }
9519 } else {
9520 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9521 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9522 }
9523 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9524 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9525 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9526 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9527 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9528 omx_report_error ();
9529 }
9530 } else {
9531 pending_input_buffers++;
9532 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9533 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9534 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9535 }
9536 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9537 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9538 (OMX_BUFFERHEADERTYPE *)p1);
9539 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9540 }
9541 }
9542 pthread_mutex_unlock(&m_lock);
9543 }
9544}
9545#endif