blob: bcaa36c2c195490fedfb6211edc493f4c8471754 [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 }
Arun Menon8544ead2014-05-08 17:42:29 -07004205 if (!handle) {
4206 DEBUG_PRINT_ERROR("handle is invalid");
4207 return OMX_ErrorBadParameter;
4208 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004209
Arun Menon906de572013-06-18 17:01:40 -07004210 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4211 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4212 " expected %u, got %lu",
4213 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4214 return OMX_ErrorBadParameter;
4215 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004216
Arun Menon906de572013-06-18 17:01:40 -07004217 if (!m_use_android_native_buffers) {
4218 if (!secure_mode) {
4219 buff = (OMX_U8*)mmap(0, handle->size,
4220 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4221 if (buff == MAP_FAILED) {
4222 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4223 return OMX_ErrorInsufficientResources;
4224 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004225 }
4226 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004227#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004228 native_buffer[i].nativehandle = handle;
4229 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004230#endif
Arun Menon906de572013-06-18 17:01:40 -07004231 if (!handle) {
4232 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4233 return OMX_ErrorBadParameter;
4234 }
4235 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4236 drv_ctx.ptr_outputbuffer[i].offset = 0;
4237 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4238 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4239 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4240 } else
4241#endif
4242
4243 if (!ouput_egl_buffers && !m_use_output_pmem) {
4244#ifdef USE_ION
4245 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4246 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4247 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4248 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4249 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004250 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 -07004251 return OMX_ErrorInsufficientResources;
4252 }
4253 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4254 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4255#else
4256 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4257 open (MEM_DEVICE,O_RDWR);
4258
4259 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004260 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004261 return OMX_ErrorInsufficientResources;
4262 }
4263
4264 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4265 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4266 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4267 open (MEM_DEVICE,O_RDWR);
4268 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004269 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004270 return OMX_ErrorInsufficientResources;
4271 }
4272 }
4273
4274 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4275 drv_ctx.op_buf.buffer_size,
4276 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004277 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004278 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4279 return OMX_ErrorInsufficientResources;
4280 }
4281#endif
4282 if (!secure_mode) {
4283 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4284 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4285 PROT_READ|PROT_WRITE, MAP_SHARED,
4286 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4287 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4288 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4289#ifdef USE_ION
4290 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4291#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004292 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004293 return OMX_ErrorInsufficientResources;
4294 }
4295 }
4296 drv_ctx.ptr_outputbuffer[i].offset = 0;
4297 privateAppData = appData;
4298 } else {
4299
4300 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4301 if (!appData || !bytes ) {
4302 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004303 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004304 return OMX_ErrorBadParameter;
4305 }
4306 }
4307
4308 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4309 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4310 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004311 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004312 !pmem_list->nEntries ||
4313 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004314 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004315 return OMX_ErrorBadParameter;
4316 }
4317 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4318 pmem_list->entryList->entry;
4319 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4320 pmem_info->pmem_fd);
4321 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4322 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4323 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4324 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4325 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4326 privateAppData = appData;
4327 }
4328 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4329 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304330 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4331 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4332 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004333
4334 *bufferHdr = (m_out_mem_ptr + i );
4335 if (secure_mode)
4336 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4337 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4338 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4339 sizeof (vdec_bufferpayload));
4340
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004341 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004342 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4343 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4344
4345 buf.index = i;
4346 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4347 buf.memory = V4L2_MEMORY_USERPTR;
4348 plane[0].length = drv_ctx.op_buf.buffer_size;
4349 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4350 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4351 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4352 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4353 plane[0].data_offset = 0;
4354 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4355 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4356 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4357 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4358#ifdef USE_ION
4359 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4360#endif
4361 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4362 plane[extra_idx].data_offset = 0;
4363 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004364 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004365 return OMX_ErrorBadParameter;
4366 }
Arun Menon906de572013-06-18 17:01:40 -07004367 buf.m.planes = plane;
4368 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369
Arun Menon906de572013-06-18 17:01:40 -07004370 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004371 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004372 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004373 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004374 }
4375
Arun Menon906de572013-06-18 17:01:40 -07004376 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4377 enum v4l2_buf_type buf_type;
4378 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4379 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4380 return OMX_ErrorInsufficientResources;
4381 } else {
4382 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004383 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004384 }
4385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004386
Arun Menon906de572013-06-18 17:01:40 -07004387 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4388 if (m_enable_android_native_buffers) {
4389 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4390 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4391 } else {
4392 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004393 }
Arun Menon906de572013-06-18 17:01:40 -07004394 (*bufferHdr)->pAppPrivate = privateAppData;
4395 BITMASK_SET(&m_out_bm_count,i);
4396 }
4397 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004398}
4399
4400/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004401 FUNCTION
4402 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004403
Arun Menon906de572013-06-18 17:01:40 -07004404 DESCRIPTION
4405 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004406
Arun Menon906de572013-06-18 17:01:40 -07004407 PARAMETERS
4408 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004409
Arun Menon906de572013-06-18 17:01:40 -07004410 RETURN VALUE
4411 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004412
Arun Menon906de572013-06-18 17:01:40 -07004413 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004414OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004415 OMX_IN OMX_HANDLETYPE hComp,
4416 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4417 OMX_IN OMX_U32 port,
4418 OMX_IN OMX_PTR appData,
4419 OMX_IN OMX_U32 bytes,
4420 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004421{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004422 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004423 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4424 if (!m_inp_heap_ptr)
4425 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4426 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4427 drv_ctx.ip_buf.actualcount);
4428 if (!m_phdr_pmem_ptr)
4429 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4430 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4431 drv_ctx.ip_buf.actualcount);
4432 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4433 DEBUG_PRINT_ERROR("Insufficent memory");
4434 eRet = OMX_ErrorInsufficientResources;
4435 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4436 input_use_buffer = true;
4437 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4438 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4439 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4440 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4441 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4442 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4443 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4444 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004445 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 -07004446 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4447 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004448 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004449 return OMX_ErrorInsufficientResources;
4450 }
4451 m_in_alloc_cnt++;
4452 } else {
4453 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4454 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004455 }
Arun Menon906de572013-06-18 17:01:40 -07004456 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004457}
4458
4459/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004460 FUNCTION
4461 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004462
Arun Menon906de572013-06-18 17:01:40 -07004463 DESCRIPTION
4464 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004465
Arun Menon906de572013-06-18 17:01:40 -07004466 PARAMETERS
4467 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004468
Arun Menon906de572013-06-18 17:01:40 -07004469 RETURN VALUE
4470 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004471
Arun Menon906de572013-06-18 17:01:40 -07004472 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004473OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004474 OMX_IN OMX_HANDLETYPE hComp,
4475 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4476 OMX_IN OMX_U32 port,
4477 OMX_IN OMX_PTR appData,
4478 OMX_IN OMX_U32 bytes,
4479 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004480{
Arun Menon906de572013-06-18 17:01:40 -07004481 OMX_ERRORTYPE error = OMX_ErrorNone;
4482 struct vdec_setbuffer_cmd setbuffers;
4483
Arun Menon8544ead2014-05-08 17:42:29 -07004484 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4485 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4486 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004487 }
Arun Menon906de572013-06-18 17:01:40 -07004488 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004489 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004490 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004491 }
Arun Menon906de572013-06-18 17:01:40 -07004492 if (port == OMX_CORE_INPUT_PORT_INDEX)
4493 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4494 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4495 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4496 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004497 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004498 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004499 }
Arun Menon906de572013-06-18 17:01:40 -07004500 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4501 if (error == OMX_ErrorNone) {
4502 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4503 // Send the callback now
4504 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4505 post_event(OMX_CommandStateSet,OMX_StateIdle,
4506 OMX_COMPONENT_GENERATE_EVENT);
4507 }
4508 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4509 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4510 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4511 post_event(OMX_CommandPortEnable,
4512 OMX_CORE_INPUT_PORT_INDEX,
4513 OMX_COMPONENT_GENERATE_EVENT);
4514 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4515 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4516 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4517 post_event(OMX_CommandPortEnable,
4518 OMX_CORE_OUTPUT_PORT_INDEX,
4519 OMX_COMPONENT_GENERATE_EVENT);
4520 }
4521 }
4522 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004523}
4524
4525OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004526 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004527{
Arun Menon906de572013-06-18 17:01:40 -07004528 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4529 if (m_inp_heap_ptr[bufferindex].pBuffer)
4530 free(m_inp_heap_ptr[bufferindex].pBuffer);
4531 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4532 }
4533 if (pmem_bufferHdr)
4534 free_input_buffer(pmem_bufferHdr);
4535 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004536}
4537
4538OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4539{
Arun Menon906de572013-06-18 17:01:40 -07004540 unsigned int index = 0;
4541 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4542 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004544
Arun Menon906de572013-06-18 17:01:40 -07004545 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004546 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004547
4548 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004549 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004550 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4551 struct vdec_setbuffer_cmd setbuffers;
4552 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4553 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4554 sizeof (vdec_bufferpayload));
4555 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004556 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004557 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004558 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004559 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4560 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4561 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4562 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4563 }
4564 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4565 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4566 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4567 free(m_desc_buffer_ptr[index].buf_addr);
4568 m_desc_buffer_ptr[index].buf_addr = NULL;
4569 m_desc_buffer_ptr[index].desc_data_size = 0;
4570 }
4571#ifdef USE_ION
4572 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4573#endif
4574 }
4575 }
4576
4577 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004578}
4579
4580OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4581{
Arun Menon906de572013-06-18 17:01:40 -07004582 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004583
Arun Menon906de572013-06-18 17:01:40 -07004584 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4585 return OMX_ErrorBadParameter;
4586 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587
Arun Menon906de572013-06-18 17:01:40 -07004588 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004589 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590
Arun Menon906de572013-06-18 17:01:40 -07004591 if (index < drv_ctx.op_buf.actualcount
4592 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004593 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004594 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595
Arun Menon906de572013-06-18 17:01:40 -07004596 struct vdec_setbuffer_cmd setbuffers;
4597 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4598 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4599 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004600
4601 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004602#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004603 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004604 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004605 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4606 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4607 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4608 }
Arun Menon906de572013-06-18 17:01:40 -07004609 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004610 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4611 } else {
4612#endif
4613 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4614 if (!secure_mode) {
4615 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4616 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4617 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4618 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4619 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4620 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4621 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4622 }
4623 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4624 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004625#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004626 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004627#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004628 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004629#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004630 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004631#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004632 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004633 if (release_output_done()) {
4634 free_extradata();
4635 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004636 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004637
Arun Menon906de572013-06-18 17:01:40 -07004638 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004639
4640}
4641
4642OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004643 OMX_BUFFERHEADERTYPE **bufferHdr,
4644 OMX_U32 port,
4645 OMX_PTR appData,
4646 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004647{
Arun Menon906de572013-06-18 17:01:40 -07004648 OMX_BUFFERHEADERTYPE *input = NULL;
4649 unsigned char *buf_addr = NULL;
4650 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4651 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004652
Arun Menon906de572013-06-18 17:01:40 -07004653 /* Sanity Check*/
4654 if (bufferHdr == NULL) {
4655 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004656 }
4657
Arun Menon906de572013-06-18 17:01:40 -07004658 if (m_inp_heap_ptr == NULL) {
4659 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4660 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4661 drv_ctx.ip_buf.actualcount);
4662 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4663 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4664 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004665
Arun Menon8544ead2014-05-08 17:42:29 -07004666 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4667 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004668 return OMX_ErrorInsufficientResources;
4669 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671
Arun Menon906de572013-06-18 17:01:40 -07004672 /*Find a Free index*/
4673 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4674 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004675 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004676 break;
4677 }
4678 }
4679
4680 if (i < drv_ctx.ip_buf.actualcount) {
4681 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4682
4683 if (buf_addr == NULL) {
4684 return OMX_ErrorInsufficientResources;
4685 }
4686
4687 *bufferHdr = (m_inp_heap_ptr + i);
4688 input = *bufferHdr;
4689 BITMASK_SET(&m_heap_inp_bm_count,i);
4690
4691 input->pBuffer = (OMX_U8 *)buf_addr;
4692 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4693 input->nVersion.nVersion = OMX_SPEC_VERSION;
4694 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4695 input->pAppPrivate = appData;
4696 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004697 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004698 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004699 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004700 /*Add the Buffers to freeq*/
4701 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4702 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004703 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004704 return OMX_ErrorInsufficientResources;
4705 }
4706 } else {
4707 return OMX_ErrorBadParameter;
4708 }
4709
4710 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004711
4712}
4713
4714
4715/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004716 FUNCTION
4717 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004718
Arun Menon906de572013-06-18 17:01:40 -07004719 DESCRIPTION
4720 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004721
Arun Menon906de572013-06-18 17:01:40 -07004722 PARAMETERS
4723 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004724
Arun Menon906de572013-06-18 17:01:40 -07004725 RETURN VALUE
4726 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004727
Arun Menon906de572013-06-18 17:01:40 -07004728 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004729OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004730 OMX_IN OMX_HANDLETYPE hComp,
4731 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4732 OMX_IN OMX_U32 port,
4733 OMX_IN OMX_PTR appData,
4734 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004735{
4736
Arun Menon906de572013-06-18 17:01:40 -07004737 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4738 struct vdec_setbuffer_cmd setbuffers;
4739 OMX_BUFFERHEADERTYPE *input = NULL;
4740 unsigned i = 0;
4741 unsigned char *buf_addr = NULL;
4742 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004743
Arun Menon906de572013-06-18 17:01:40 -07004744 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004745 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004746 bytes, drv_ctx.ip_buf.buffer_size);
4747 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004748 }
4749
Arun Menon906de572013-06-18 17:01:40 -07004750 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004751 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004752 drv_ctx.ip_buf.actualcount,
4753 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004754
Arun Menon906de572013-06-18 17:01:40 -07004755 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4756 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4757
4758 if (m_inp_mem_ptr == NULL) {
4759 return OMX_ErrorInsufficientResources;
4760 }
4761
4762 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4763 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4764
4765 if (drv_ctx.ptr_inputbuffer == NULL) {
4766 return OMX_ErrorInsufficientResources;
4767 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004768#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004769 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4770 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004771
Arun Menon906de572013-06-18 17:01:40 -07004772 if (drv_ctx.ip_buf_ion_info == NULL) {
4773 return OMX_ErrorInsufficientResources;
4774 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004775#endif
4776
Arun Menon906de572013-06-18 17:01:40 -07004777 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4778 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004779#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004780 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004781#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782 }
4783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004784
Arun Menon906de572013-06-18 17:01:40 -07004785 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4786 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004787 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004788 break;
4789 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004790 }
Arun Menon906de572013-06-18 17:01:40 -07004791
4792 if (i < drv_ctx.ip_buf.actualcount) {
4793 struct v4l2_buffer buf;
4794 struct v4l2_plane plane;
4795 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004796 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004797#ifdef USE_ION
4798 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4799 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4800 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4801 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4802 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4803 return OMX_ErrorInsufficientResources;
4804 }
4805 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4806#else
4807 pmem_fd = open (MEM_DEVICE,O_RDWR);
4808
4809 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004810 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004811 return OMX_ErrorInsufficientResources;
4812 }
4813
4814 if (pmem_fd == 0) {
4815 pmem_fd = open (MEM_DEVICE,O_RDWR);
4816
4817 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004818 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004819 return OMX_ErrorInsufficientResources;
4820 }
4821 }
4822
4823 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4824 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004825 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004826 close(pmem_fd);
4827 return OMX_ErrorInsufficientResources;
4828 }
4829#endif
4830 if (!secure_mode) {
4831 buf_addr = (unsigned char *)mmap(NULL,
4832 drv_ctx.ip_buf.buffer_size,
4833 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4834
4835 if (buf_addr == MAP_FAILED) {
4836 close(pmem_fd);
4837#ifdef USE_ION
4838 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4839#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004840 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004841 return OMX_ErrorInsufficientResources;
4842 }
4843 }
4844 *bufferHdr = (m_inp_mem_ptr + i);
4845 if (secure_mode)
4846 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4847 else
4848 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4849 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4850 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4851 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4852 drv_ctx.ptr_inputbuffer [i].offset = 0;
4853
4854
4855 buf.index = i;
4856 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4857 buf.memory = V4L2_MEMORY_USERPTR;
4858 plane.bytesused = 0;
4859 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4860 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4861 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4862 plane.reserved[1] = 0;
4863 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4864 buf.m.planes = &plane;
4865 buf.length = 1;
4866
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004867 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004868 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4869
4870 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4871
4872 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004873 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004874 /*TODO: How to handle this case */
4875 return OMX_ErrorInsufficientResources;
4876 }
4877
4878 input = *bufferHdr;
4879 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004880 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004881 if (secure_mode)
4882 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4883 else
4884 input->pBuffer = (OMX_U8 *)buf_addr;
4885 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4886 input->nVersion.nVersion = OMX_SPEC_VERSION;
4887 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4888 input->pAppPrivate = appData;
4889 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4890 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4891
4892 if (drv_ctx.disable_dmx) {
4893 eRet = allocate_desc_buffer(i);
4894 }
4895 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004896 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004897 eRet = OMX_ErrorInsufficientResources;
4898 }
4899 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004900}
4901
4902
4903/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004904 FUNCTION
4905 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004906
Arun Menon906de572013-06-18 17:01:40 -07004907 DESCRIPTION
4908 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004909
Arun Menon906de572013-06-18 17:01:40 -07004910 PARAMETERS
4911 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004912
Arun Menon906de572013-06-18 17:01:40 -07004913 RETURN VALUE
4914 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915
Arun Menon906de572013-06-18 17:01:40 -07004916 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004917OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004918 OMX_IN OMX_HANDLETYPE hComp,
4919 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4920 OMX_IN OMX_U32 port,
4921 OMX_IN OMX_PTR appData,
4922 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004923{
Arun Menon906de572013-06-18 17:01:40 -07004924 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4925 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4926 unsigned i= 0; // Temporary counter
4927 struct vdec_setbuffer_cmd setbuffers;
4928 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004929#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004930 int ion_device_fd =-1;
4931 struct ion_allocation_data ion_alloc_data;
4932 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004933#endif
Arun Menon906de572013-06-18 17:01:40 -07004934 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004935 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004936 drv_ctx.op_buf.actualcount,
4937 drv_ctx.op_buf.buffer_size);
4938 int nBufHdrSize = 0;
4939 int nPlatformEntrySize = 0;
4940 int nPlatformListSize = 0;
4941 int nPMEMInfoSize = 0;
4942 int pmem_fd = -1;
4943 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004944
Arun Menon906de572013-06-18 17:01:40 -07004945 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4946 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4947 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004948
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004949 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004950 drv_ctx.op_buf.actualcount);
4951 nBufHdrSize = drv_ctx.op_buf.actualcount *
4952 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004953
Arun Menon906de572013-06-18 17:01:40 -07004954 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4955 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4956 nPlatformListSize = drv_ctx.op_buf.actualcount *
4957 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4958 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4959 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004960
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004961 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004962 sizeof(OMX_BUFFERHEADERTYPE),
4963 nPMEMInfoSize,
4964 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004965 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004966 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004967#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004968 ion_device_fd = alloc_map_ion_memory(
4969 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4970 drv_ctx.op_buf.alignment,
4971 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4972 if (ion_device_fd < 0) {
4973 return OMX_ErrorInsufficientResources;
4974 }
4975 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976#else
Arun Menon906de572013-06-18 17:01:40 -07004977 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004978
Arun Menon906de572013-06-18 17:01:40 -07004979 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004980 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004981 drv_ctx.op_buf.buffer_size);
4982 return OMX_ErrorInsufficientResources;
4983 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004984
Arun Menon906de572013-06-18 17:01:40 -07004985 if (pmem_fd == 0) {
4986 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987
Arun Menon906de572013-06-18 17:01:40 -07004988 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004989 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004990 drv_ctx.op_buf.buffer_size);
4991 return OMX_ErrorInsufficientResources;
4992 }
4993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004994
Arun Menon906de572013-06-18 17:01:40 -07004995 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4996 drv_ctx.op_buf.actualcount,
4997 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004998 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004999 close(pmem_fd);
5000 return OMX_ErrorInsufficientResources;
5001 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005002#endif
Arun Menon906de572013-06-18 17:01:40 -07005003 if (!secure_mode) {
5004 pmem_baseaddress = (unsigned char *)mmap(NULL,
5005 (drv_ctx.op_buf.buffer_size *
5006 drv_ctx.op_buf.actualcount),
5007 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5008 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005009 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005010 drv_ctx.op_buf.buffer_size);
5011 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005012#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005013 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005014#endif
Arun Menon906de572013-06-18 17:01:40 -07005015 return OMX_ErrorInsufficientResources;
5016 }
5017 }
5018 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5019 // Alloc mem for platform specific info
5020 char *pPtr=NULL;
5021 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5022 nPMEMInfoSize,1);
5023 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5024 calloc (sizeof(struct vdec_bufferpayload),
5025 drv_ctx.op_buf.actualcount);
5026 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5027 calloc (sizeof (struct vdec_output_frameinfo),
5028 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005029 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5030 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5031 return OMX_ErrorInsufficientResources;
5032 }
5033
Arun Menon906de572013-06-18 17:01:40 -07005034#ifdef USE_ION
5035 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5036 calloc (sizeof(struct vdec_ion),
5037 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005038 if (!drv_ctx.op_buf_ion_info) {
5039 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5040 return OMX_ErrorInsufficientResources;
5041 }
Arun Menon906de572013-06-18 17:01:40 -07005042#endif
5043
5044 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5045 && drv_ctx.ptr_respbuffer) {
5046 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5047 (drv_ctx.op_buf.buffer_size *
5048 drv_ctx.op_buf.actualcount);
5049 bufHdr = m_out_mem_ptr;
5050 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5051 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5052 (((char *) m_platform_list) + nPlatformListSize);
5053 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5054 (((char *) m_platform_entry) + nPlatformEntrySize);
5055 pPlatformList = m_platform_list;
5056 pPlatformEntry = m_platform_entry;
5057 pPMEMInfo = m_pmem_info;
5058
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005059 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005060
5061 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005062 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5063 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005064 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5065 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5066 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5067 // Set the values when we determine the right HxW param
5068 bufHdr->nAllocLen = bytes;
5069 bufHdr->nFilledLen = 0;
5070 bufHdr->pAppPrivate = appData;
5071 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5072 // Platform specific PMEM Information
5073 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005074 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005075 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5076 pPlatformEntry->entry = pPMEMInfo;
5077 // Initialize the Platform List
5078 pPlatformList->nEntries = 1;
5079 pPlatformList->entryList = pPlatformEntry;
5080 // Keep pBuffer NULL till vdec is opened
5081 bufHdr->pBuffer = NULL;
5082 bufHdr->nOffset = 0;
5083
5084 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5085 pPMEMInfo->pmem_fd = 0;
5086 bufHdr->pPlatformPrivate = pPlatformList;
5087
5088 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5089 m_pmem_info[i].pmem_fd = pmem_fd;
5090#ifdef USE_ION
5091 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5092 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5093 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5094#endif
5095
5096 /*Create a mapping between buffers*/
5097 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5098 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5099 &drv_ctx.ptr_outputbuffer[i];
5100 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5101 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5102 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305103 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5104 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5105 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005106
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005107 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005108 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5109 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5110 // Move the buffer and buffer header pointers
5111 bufHdr++;
5112 pPMEMInfo++;
5113 pPlatformEntry++;
5114 pPlatformList++;
5115 }
5116 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005117 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005118 m_out_mem_ptr, pPtr);
5119 if (m_out_mem_ptr) {
5120 free(m_out_mem_ptr);
5121 m_out_mem_ptr = NULL;
5122 }
5123 if (pPtr) {
5124 free(pPtr);
5125 pPtr = NULL;
5126 }
5127 if (drv_ctx.ptr_outputbuffer) {
5128 free(drv_ctx.ptr_outputbuffer);
5129 drv_ctx.ptr_outputbuffer = NULL;
5130 }
5131 if (drv_ctx.ptr_respbuffer) {
5132 free(drv_ctx.ptr_respbuffer);
5133 drv_ctx.ptr_respbuffer = NULL;
5134 }
5135#ifdef USE_ION
5136 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005137 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005138 free(drv_ctx.op_buf_ion_info);
5139 drv_ctx.op_buf_ion_info = NULL;
5140 }
5141#endif
5142 eRet = OMX_ErrorInsufficientResources;
5143 }
5144 if (eRet == OMX_ErrorNone)
5145 eRet = allocate_extradata();
5146 }
5147
5148 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5149 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005150 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005151 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005152 }
5153 }
Arun Menon906de572013-06-18 17:01:40 -07005154
5155 if (eRet == OMX_ErrorNone) {
5156 if (i < drv_ctx.op_buf.actualcount) {
5157 struct v4l2_buffer buf;
5158 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5159 int rc;
5160 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5161
5162 drv_ctx.ptr_outputbuffer[i].buffer_len =
5163 drv_ctx.op_buf.buffer_size;
5164
5165 *bufferHdr = (m_out_mem_ptr + i );
5166 if (secure_mode) {
5167 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5168 }
5169 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5170
5171 buf.index = i;
5172 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5173 buf.memory = V4L2_MEMORY_USERPTR;
5174 plane[0].length = drv_ctx.op_buf.buffer_size;
5175 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5176 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005177#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005178 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005179#endif
Arun Menon906de572013-06-18 17:01:40 -07005180 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5181 plane[0].data_offset = 0;
5182 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5183 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5184 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5185 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 -07005186#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005187 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005188#endif
Arun Menon906de572013-06-18 17:01:40 -07005189 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5190 plane[extra_idx].data_offset = 0;
5191 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005192 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005193 return OMX_ErrorBadParameter;
5194 }
5195 buf.m.planes = plane;
5196 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005197 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 -07005198 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5199 if (rc) {
5200 /*TODO: How to handle this case */
5201 return OMX_ErrorInsufficientResources;
5202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005203
Arun Menon906de572013-06-18 17:01:40 -07005204 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5205 enum v4l2_buf_type buf_type;
5206 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5207 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5208 if (rc) {
5209 return OMX_ErrorInsufficientResources;
5210 } else {
5211 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005212 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005213 }
5214 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005215
Arun Menon906de572013-06-18 17:01:40 -07005216 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5217 (*bufferHdr)->pAppPrivate = appData;
5218 BITMASK_SET(&m_out_bm_count,i);
5219 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005220 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005221 eRet = OMX_ErrorInsufficientResources;
5222 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005223 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224
Arun Menon906de572013-06-18 17:01:40 -07005225 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005226}
5227
5228
5229// AllocateBuffer -- API Call
5230/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005231 FUNCTION
5232 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233
Arun Menon906de572013-06-18 17:01:40 -07005234 DESCRIPTION
5235 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005236
Arun Menon906de572013-06-18 17:01:40 -07005237 PARAMETERS
5238 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005239
Arun Menon906de572013-06-18 17:01:40 -07005240 RETURN VALUE
5241 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005242
Arun Menon906de572013-06-18 17:01:40 -07005243 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005244OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005245 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5246 OMX_IN OMX_U32 port,
5247 OMX_IN OMX_PTR appData,
5248 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249{
5250 unsigned i = 0;
5251 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5252
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005253 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005254 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005255 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005256 return OMX_ErrorInvalidState;
5257 }
5258
Arun Menon906de572013-06-18 17:01:40 -07005259 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5260 if (arbitrary_bytes) {
5261 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5262 } else {
5263 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5264 }
5265 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005266 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5267 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005268 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005269 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005270 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005271 }
5272 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005273 if (eRet == OMX_ErrorNone) {
5274 if (allocate_done()) {
5275 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005276 // Send the callback now
5277 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5278 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005279 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005280 }
5281 }
Arun Menon906de572013-06-18 17:01:40 -07005282 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5283 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5284 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5285 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005286 OMX_CORE_INPUT_PORT_INDEX,
5287 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005288 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005289 }
Arun Menon906de572013-06-18 17:01:40 -07005290 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5291 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5292 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005293 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005294 OMX_CORE_OUTPUT_PORT_INDEX,
5295 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005296 }
5297 }
5298 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005299 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005300 return eRet;
5301}
5302
5303// Free Buffer - API call
5304/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005305 FUNCTION
5306 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005307
Arun Menon906de572013-06-18 17:01:40 -07005308 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005309
Arun Menon906de572013-06-18 17:01:40 -07005310 PARAMETERS
5311 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005312
Arun Menon906de572013-06-18 17:01:40 -07005313 RETURN VALUE
5314 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005315
Arun Menon906de572013-06-18 17:01:40 -07005316 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005317OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005318 OMX_IN OMX_U32 port,
5319 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005320{
5321 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5322 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005323 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324
Arun Menon906de572013-06-18 17:01:40 -07005325 if (m_state == OMX_StateIdle &&
5326 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005327 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005328 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5329 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005330 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005331 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5332 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5333 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5334 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005335 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005336 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005337 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005338 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005339 OMX_ErrorPortUnpopulated,
5340 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005341
5342 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005343 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005344 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005346 OMX_ErrorPortUnpopulated,
5347 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005348 }
5349
Arun Menon906de572013-06-18 17:01:40 -07005350 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5351 /*Check if arbitrary bytes*/
5352 if (!arbitrary_bytes && !input_use_buffer)
5353 nPortIndex = buffer - m_inp_mem_ptr;
5354 else
5355 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005356
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005357 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005358 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5359 // Clear the bit associated with it.
5360 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5361 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5362 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005363
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005364 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005365 if (m_phdr_pmem_ptr)
5366 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5367 } else {
5368 if (arbitrary_bytes) {
5369 if (m_phdr_pmem_ptr)
5370 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5371 else
5372 free_input_buffer(nPortIndex,NULL);
5373 } else
5374 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005375 }
Arun Menon906de572013-06-18 17:01:40 -07005376 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305377 if(release_input_done())
5378 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005379 /*Free the Buffer Header*/
5380 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005381 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005382 free_input_buffer_header();
5383 }
5384 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005385 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005386 eRet = OMX_ErrorBadPortIndex;
5387 }
5388
Arun Menon906de572013-06-18 17:01:40 -07005389 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5390 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005391 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005392 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5393 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005394 OMX_CORE_INPUT_PORT_INDEX,
5395 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005396 }
Arun Menon906de572013-06-18 17:01:40 -07005397 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005398 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005399 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005400 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005401 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005402 // Clear the bit associated with it.
5403 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5404 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005405 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005406
Surajit Podder12aefac2013-08-06 18:43:32 +05305407 if(release_output_done()) {
5408 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5409 }
Arun Menon906de572013-06-18 17:01:40 -07005410 if (release_output_done()) {
5411 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005412 }
Arun Menon906de572013-06-18 17:01:40 -07005413 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005414 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005415 eRet = OMX_ErrorBadPortIndex;
5416 }
Arun Menon906de572013-06-18 17:01:40 -07005417 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5418 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005419 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005420
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005421 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005422 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005423#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005424 if (m_enable_android_native_buffers) {
5425 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5426 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5427 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005428#endif
5429
Arun Menon906de572013-06-18 17:01:40 -07005430 post_event(OMX_CommandPortDisable,
5431 OMX_CORE_OUTPUT_PORT_INDEX,
5432 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005433 }
Arun Menon906de572013-06-18 17:01:40 -07005434 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005435 eRet = OMX_ErrorBadPortIndex;
5436 }
Arun Menon906de572013-06-18 17:01:40 -07005437 if ((eRet == OMX_ErrorNone) &&
5438 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5439 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005440 // Send the callback now
5441 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5442 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005443 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005444 }
5445 }
5446 return eRet;
5447}
5448
5449
5450/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005451 FUNCTION
5452 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453
Arun Menon906de572013-06-18 17:01:40 -07005454 DESCRIPTION
5455 This routine is used to push the encoded video frames to
5456 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005457
Arun Menon906de572013-06-18 17:01:40 -07005458 PARAMETERS
5459 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460
Arun Menon906de572013-06-18 17:01:40 -07005461 RETURN VALUE
5462 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463
Arun Menon906de572013-06-18 17:01:40 -07005464 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005466 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467{
Arun Menon906de572013-06-18 17:01:40 -07005468 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5469 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470
Arun Menon906de572013-06-18 17:01:40 -07005471 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005472 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005473 return OMX_ErrorInvalidState;
5474 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005475
Arun Menon906de572013-06-18 17:01:40 -07005476 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005477 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005478 return OMX_ErrorBadParameter;
5479 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005480
Arun Menon906de572013-06-18 17:01:40 -07005481 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005482 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005483 return OMX_ErrorIncorrectStateOperation;
5484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005487 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005488 return OMX_ErrorBadPortIndex;
5489 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005490
5491#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005492 if (iDivXDrmDecrypt) {
5493 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5494 if (drmErr != OMX_ErrorNone) {
5495 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005496 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005497 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005498 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005499#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005500 if (perf_flag) {
5501 if (!latency) {
5502 dec_time.stop();
5503 latency = dec_time.processing_time_us();
5504 dec_time.start();
5505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005506 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005507
Arun Menon906de572013-06-18 17:01:40 -07005508 if (arbitrary_bytes) {
5509 nBufferIndex = buffer - m_inp_heap_ptr;
5510 } else {
5511 if (input_use_buffer == true) {
5512 nBufferIndex = buffer - m_inp_heap_ptr;
5513 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5514 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5515 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5516 buffer = &m_inp_mem_ptr[nBufferIndex];
5517 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5518 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5519 } else {
5520 nBufferIndex = buffer - m_inp_mem_ptr;
5521 }
5522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523
Arun Menon906de572013-06-18 17:01:40 -07005524 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005525 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005526 return OMX_ErrorBadParameter;
5527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005529 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5530 codec_config_flag = true;
5531 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5532 }
5533
Arun Menon906de572013-06-18 17:01:40 -07005534 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5535 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5536 if (arbitrary_bytes) {
5537 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005538 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005539 } else {
Arun Menon906de572013-06-18 17:01:40 -07005540 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5541 }
5542 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005543}
5544
5545/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005546 FUNCTION
5547 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005548
Arun Menon906de572013-06-18 17:01:40 -07005549 DESCRIPTION
5550 This routine is used to push the encoded video frames to
5551 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005552
Arun Menon906de572013-06-18 17:01:40 -07005553 PARAMETERS
5554 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005555
Arun Menon906de572013-06-18 17:01:40 -07005556 RETURN VALUE
5557 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005558
Arun Menon906de572013-06-18 17:01:40 -07005559 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005560OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005561 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005562{
Arun Menon906de572013-06-18 17:01:40 -07005563 int push_cnt = 0,i=0;
5564 unsigned nPortIndex = 0;
5565 OMX_ERRORTYPE ret = OMX_ErrorNone;
5566 struct vdec_input_frameinfo frameinfo;
5567 struct vdec_bufferpayload *temp_buffer;
5568 struct vdec_seqheader seq_header;
5569 bool port_setting_changed = true;
5570 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005571
Arun Menon906de572013-06-18 17:01:40 -07005572 /*Should we generate a Aync error event*/
5573 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005574 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005575 return OMX_ErrorBadParameter;
5576 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577
Arun Menon906de572013-06-18 17:01:40 -07005578 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579
Arun Menon906de572013-06-18 17:01:40 -07005580 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005581 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005582 nPortIndex);
5583 return OMX_ErrorBadParameter;
5584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585
Arun Menon906de572013-06-18 17:01:40 -07005586 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005587
Arun Menon906de572013-06-18 17:01:40 -07005588 /* return zero length and not an EOS buffer */
5589 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5590 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005591 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005592 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5593 OMX_COMPONENT_GENERATE_EBD);
5594 return OMX_ErrorNone;
5595 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005596
5597
Arun Menon906de572013-06-18 17:01:40 -07005598 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5599 mp4StreamType psBits;
5600 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5601 psBits.numBytes = buffer->nFilledLen;
5602 mp4_headerparser.parseHeader(&psBits);
5603 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5604 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5605 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005606 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005607 buffer->nFilledLen,frame_count);
5608 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005609 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005610 not_coded_vop = false;
5611 buffer->nFilledLen = 0;
5612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005613 }
5614 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615
Arun Menon906de572013-06-18 17:01:40 -07005616 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005617
Arun Menon906de572013-06-18 17:01:40 -07005618 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005619
Arun Menon906de572013-06-18 17:01:40 -07005620 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005621 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005622 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5623 OMX_COMPONENT_GENERATE_EBD);
5624 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005625 }
5626
Arun Menon906de572013-06-18 17:01:40 -07005627 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628
Surajit Podderd2644d52013-08-28 17:59:06 +05305629 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005630 return OMX_ErrorBadParameter;
5631 }
5632 /* If its first frame, H264 codec and reject is true, then parse the nal
5633 and get the profile. Based on this, reject the clip playback */
5634 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5635 m_reject_avc_1080p_mp) {
5636 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005637 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005638 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5639 NALU_TYPE_SPS);
5640 m_profile = h264_parser->get_profile();
5641 ret = is_video_session_supported();
5642 if (ret) {
5643 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5644 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5645 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5646 m_state = OMX_StateInvalid;
5647 return OMX_ErrorNone;
5648 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649 }
5650
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005651 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005652 /*for use buffer we need to memcpy the data*/
5653 temp_buffer->buffer_len = buffer->nFilledLen;
5654
5655 if (input_use_buffer) {
5656 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5657 if (arbitrary_bytes) {
5658 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5659 } else {
5660 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5661 buffer->nFilledLen);
5662 }
5663 } else {
5664 return OMX_ErrorBadParameter;
5665 }
5666
5667 }
5668
5669 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5670 frameinfo.client_data = (void *) buffer;
5671 frameinfo.datalen = temp_buffer->buffer_len;
5672 frameinfo.flags = 0;
5673 frameinfo.offset = buffer->nOffset;
5674 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5675 frameinfo.pmem_offset = temp_buffer->offset;
5676 frameinfo.timestamp = buffer->nTimeStamp;
5677 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5678 DEBUG_PRINT_LOW("ETB: dmx enabled");
5679 if (m_demux_entries == 0) {
5680 extract_demux_addr_offsets(buffer);
5681 }
5682
5683 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5684 handle_demux_data(buffer);
5685 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5686 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5687 } else {
5688 frameinfo.desc_addr = NULL;
5689 frameinfo.desc_size = 0;
5690 }
5691 if (!arbitrary_bytes) {
5692 frameinfo.flags |= buffer->nFlags;
5693 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694
5695#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005696 if (m_debug_timestamp) {
5697 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005698 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005699 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5700 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005701 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005702 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5703 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005704 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005705#endif
5706
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005707log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005708
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005709if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005710 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5711 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5712 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005713
Arun Menon906de572013-06-18 17:01:40 -07005714 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005715 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005716 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5717 h264_scratch.nFilledLen = 0;
5718 nal_count = 0;
5719 look_ahead_nal = false;
5720 frame_count = 0;
5721 if (m_frame_parser.mutils)
5722 m_frame_parser.mutils->initialize_frame_checking_environment();
5723 m_frame_parser.flush();
5724 h264_last_au_ts = LLONG_MAX;
5725 h264_last_au_flags = 0;
5726 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5727 m_demux_entries = 0;
5728 }
5729 struct v4l2_buffer buf;
5730 struct v4l2_plane plane;
5731 memset( (void *)&buf, 0, sizeof(buf));
5732 memset( (void *)&plane, 0, sizeof(plane));
5733 int rc;
5734 unsigned long print_count;
5735 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005736 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005737 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005738 }
5739 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5740 buf.index = nPortIndex;
5741 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5742 buf.memory = V4L2_MEMORY_USERPTR;
5743 plane.bytesused = temp_buffer->buffer_len;
5744 plane.length = drv_ctx.ip_buf.buffer_size;
5745 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5746 (unsigned long)temp_buffer->offset;
5747 plane.reserved[0] = temp_buffer->pmem_fd;
5748 plane.reserved[1] = temp_buffer->offset;
5749 plane.data_offset = 0;
5750 buf.m.planes = &plane;
5751 buf.length = 1;
5752 if (frameinfo.timestamp >= LLONG_MAX) {
5753 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5754 }
5755 //assumption is that timestamp is in milliseconds
5756 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5757 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5758 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5759 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005760
Arun Menon906de572013-06-18 17:01:40 -07005761 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5762 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005763 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005764 return OMX_ErrorHardware;
5765 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005766 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5767 codec_config_flag = false;
5768 }
Arun Menon906de572013-06-18 17:01:40 -07005769 if (!streaming[OUTPUT_PORT]) {
5770 enum v4l2_buf_type buf_type;
5771 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005772
Arun Menon906de572013-06-18 17:01:40 -07005773 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005774 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005775 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5776 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005777 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005778 streaming[OUTPUT_PORT] = true;
5779 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005780 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005781 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5782 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5783 OMX_COMPONENT_GENERATE_EBD);
5784 return OMX_ErrorBadParameter;
5785 }
5786 }
5787 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5788 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5789 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792}
5793
5794/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005795 FUNCTION
5796 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005797
Arun Menon906de572013-06-18 17:01:40 -07005798 DESCRIPTION
5799 IL client uses this method to release the frame buffer
5800 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005801
Arun Menon906de572013-06-18 17:01:40 -07005802 PARAMETERS
5803 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005804
Arun Menon906de572013-06-18 17:01:40 -07005805 RETURN VALUE
5806 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807
Arun Menon906de572013-06-18 17:01:40 -07005808 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005810 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811{
Arun Menonbdb80b02013-08-12 17:45:54 -07005812 if (dynamic_buf_mode) {
5813 private_handle_t *handle = NULL;
5814 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005815 unsigned int nPortIndex = 0;
5816
5817 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07005818 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07005819 return OMX_ErrorBadParameter;
5820 }
5821
5822 //get the buffer type and fd info
5823 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5824 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005825 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5826
5827 if (!handle) {
5828 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5829 return OMX_ErrorBadParameter;
5830 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005831 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5832 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5833 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005834 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005835
5836 //Store private handle from GraphicBuffer
5837 native_buffer[nPortIndex].privatehandle = handle;
5838 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005839 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005840
Arun Menon906de572013-06-18 17:01:40 -07005841 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005842 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005843 return OMX_ErrorInvalidState;
5844 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005845
Arun Menon906de572013-06-18 17:01:40 -07005846 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005847 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005848 return OMX_ErrorIncorrectStateOperation;
5849 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005850
Arun Menon906de572013-06-18 17:01:40 -07005851 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305852 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005853 return OMX_ErrorBadParameter;
5854 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855
Arun Menon906de572013-06-18 17:01:40 -07005856 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005857 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005858 return OMX_ErrorBadPortIndex;
5859 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005860
Arun Menon906de572013-06-18 17:01:40 -07005861 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5862 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5863 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005864}
5865/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005866 FUNCTION
5867 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005868
Arun Menon906de572013-06-18 17:01:40 -07005869 DESCRIPTION
5870 IL client uses this method to release the frame buffer
5871 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005872
Arun Menon906de572013-06-18 17:01:40 -07005873 PARAMETERS
5874 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005875
Arun Menon906de572013-06-18 17:01:40 -07005876 RETURN VALUE
5877 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005878
Arun Menon906de572013-06-18 17:01:40 -07005879 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005880OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005881 OMX_IN OMX_HANDLETYPE hComp,
5882 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005883{
Arun Menon906de572013-06-18 17:01:40 -07005884 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5885 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5886 unsigned nPortIndex = 0;
5887 struct vdec_fillbuffer_cmd fillbuffer;
5888 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5889 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005890
Arun Menon906de572013-06-18 17:01:40 -07005891 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005892
Arun Menon906de572013-06-18 17:01:40 -07005893 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5894 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005895
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005896 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005897 bufferAdd, bufferAdd->pBuffer);
5898 /*Return back the output buffer to client*/
5899 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005900 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005901 buffer->nFilledLen = 0;
5902 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5903 return OMX_ErrorNone;
5904 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005905
5906 if (dynamic_buf_mode) {
5907 //map the buffer handle based on the size set on output port definition.
5908 if (!secure_mode) {
5909 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5910 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5911 PROT_READ|PROT_WRITE, MAP_SHARED,
5912 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5913 }
5914 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5915 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5916 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5917 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5918 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5919 }
5920
Arun Menon906de572013-06-18 17:01:40 -07005921 pending_output_buffers++;
5922 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5923 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5924 if (ptr_respbuffer) {
5925 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5926 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005927
Arun Menon906de572013-06-18 17:01:40 -07005928 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5929 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5930 buffer->nFilledLen = 0;
5931 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5932 pending_output_buffers--;
5933 return OMX_ErrorBadParameter;
5934 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005935
Arun Menon906de572013-06-18 17:01:40 -07005936 int rc = 0;
5937 struct v4l2_buffer buf;
5938 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5939 memset( (void *)&buf, 0, sizeof(buf));
5940 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07005941 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005942
Arun Menon906de572013-06-18 17:01:40 -07005943 buf.index = nPortIndex;
5944 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5945 buf.memory = V4L2_MEMORY_USERPTR;
5946 plane[0].bytesused = buffer->nFilledLen;
5947 plane[0].length = drv_ctx.op_buf.buffer_size;
5948 plane[0].m.userptr =
5949 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5950 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5951 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5952 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5953 plane[0].data_offset = 0;
5954 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5955 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5956 plane[extra_idx].bytesused = 0;
5957 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5958 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 -07005959#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005960 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005961#endif
Arun Menon906de572013-06-18 17:01:40 -07005962 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5963 plane[extra_idx].data_offset = 0;
5964 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07005965 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005966 return OMX_ErrorBadParameter;
5967 }
5968 buf.m.planes = plane;
5969 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005970 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005971 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5972
Arun Menon906de572013-06-18 17:01:40 -07005973 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5974 if (rc) {
5975 /*TODO: How to handle this case */
5976 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5977 }
Arun Menon906de572013-06-18 17:01:40 -07005978return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005979}
5980
5981/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005982 FUNCTION
5983 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005984
Arun Menon906de572013-06-18 17:01:40 -07005985 DESCRIPTION
5986 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005987
Arun Menon906de572013-06-18 17:01:40 -07005988 PARAMETERS
5989 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005990
Arun Menon906de572013-06-18 17:01:40 -07005991 RETURN VALUE
5992 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005993
Arun Menon906de572013-06-18 17:01:40 -07005994 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005995OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005996 OMX_IN OMX_CALLBACKTYPE* callbacks,
5997 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005998{
5999
Arun Menon906de572013-06-18 17:01:40 -07006000 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006001 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006002 m_cb.EventHandler,m_cb.FillBufferDone);
6003 m_app_data = appData;
6004 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006005}
6006
6007/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006008 FUNCTION
6009 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010
Arun Menon906de572013-06-18 17:01:40 -07006011 DESCRIPTION
6012 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006013
Arun Menon906de572013-06-18 17:01:40 -07006014 PARAMETERS
6015 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006016
Arun Menon906de572013-06-18 17:01:40 -07006017 RETURN VALUE
6018 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006019
Arun Menon906de572013-06-18 17:01:40 -07006020 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006021OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6022{
6023#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006024 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025 delete iDivXDrmDecrypt;
6026 iDivXDrmDecrypt=NULL;
6027 }
6028#endif //_ANDROID_
6029
Shalaj Jain286b0062013-02-21 20:35:48 -08006030 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006031 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006032 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006033 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006034 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006035 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006036 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006037 }
6038
6039 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006040 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006041 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006042 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6043 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044 }
6045#ifdef _ANDROID_ICS_
6046 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6047#endif
6048 }
6049
6050 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006051 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006052 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006053 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6054 if (m_inp_mem_ptr)
6055 free_input_buffer (i,&m_inp_mem_ptr[i]);
6056 else
6057 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006058 }
6059 }
6060 free_input_buffer_header();
6061 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006062 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006063 free(h264_scratch.pBuffer);
6064 h264_scratch.pBuffer = NULL;
6065 }
6066
Arun Menon906de572013-06-18 17:01:40 -07006067 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006068 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006069 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006070 }
6071
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006072 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006073 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006074 delete (m_frame_parser.mutils);
6075 m_frame_parser.mutils = NULL;
6076 }
6077
Arun Menon906de572013-06-18 17:01:40 -07006078 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079 free(m_platform_list);
6080 m_platform_list = NULL;
6081 }
Arun Menon906de572013-06-18 17:01:40 -07006082 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083 free(m_vendor_config.pData);
6084 m_vendor_config.pData = NULL;
6085 }
6086
6087 // Reset counters in mesg queues
6088 m_ftb_q.m_size=0;
6089 m_cmd_q.m_size=0;
6090 m_etb_q.m_size=0;
6091 m_ftb_q.m_read = m_ftb_q.m_write =0;
6092 m_cmd_q.m_read = m_cmd_q.m_write =0;
6093 m_etb_q.m_read = m_etb_q.m_write =0;
6094#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006095 if (m_debug_timestamp) {
6096 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006097 }
6098#endif
6099
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006100 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006101 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006102 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006103 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006104
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006105 if (m_debug.infile) {
6106 fclose(m_debug.infile);
6107 m_debug.infile = NULL;
6108 }
6109 if (m_debug.outfile) {
6110 fclose(m_debug.outfile);
6111 m_debug.outfile = NULL;
6112 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006114 if (outputExtradataFile)
6115 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006116#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006117 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006118 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006119}
6120
6121/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006122 FUNCTION
6123 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124
Arun Menon906de572013-06-18 17:01:40 -07006125 DESCRIPTION
6126 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006127
Arun Menon906de572013-06-18 17:01:40 -07006128 PARAMETERS
6129 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006130
Arun Menon906de572013-06-18 17:01:40 -07006131 RETURN VALUE
6132 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006133
Arun Menon906de572013-06-18 17:01:40 -07006134 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006135OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006136 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6137 OMX_IN OMX_U32 port,
6138 OMX_IN OMX_PTR appData,
6139 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006140{
Arun Menon906de572013-06-18 17:01:40 -07006141 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6142 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6143 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
6145#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006146 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6147 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006148#else
Arun Menon906de572013-06-18 17:01:40 -07006149 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006150#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006151 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006152 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006153 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006155#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006156 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006157 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006158 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006159 }
6160 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6161 eglGetProcAddress("eglQueryImageKHR");
6162 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6163 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6164 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165#else //with OMX test app
6166 struct temp_egl {
6167 int pmem_fd;
6168 int offset;
6169 };
6170 struct temp_egl *temp_egl_id = NULL;
6171 void * pmemPtr = (void *) eglImage;
6172 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006173 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174 fd = temp_egl_id->pmem_fd;
6175 offset = temp_egl_id->offset;
6176 }
6177#endif
6178 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006179 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006180 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006181 }
6182 pmem_info.pmem_fd = (OMX_U32) fd;
6183 pmem_info.offset = (OMX_U32) offset;
6184 pmem_entry.entry = (void *) &pmem_info;
6185 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6186 pmem_list.entryList = &pmem_entry;
6187 pmem_list.nEntries = 1;
6188 ouput_egl_buffers = true;
6189 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6190 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6191 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006192 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006193 return OMX_ErrorInsufficientResources;
6194 }
6195 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006196}
6197
6198/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006199 FUNCTION
6200 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006201
Arun Menon906de572013-06-18 17:01:40 -07006202 DESCRIPTION
6203 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006204
Arun Menon906de572013-06-18 17:01:40 -07006205 PARAMETERS
6206 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006207
Arun Menon906de572013-06-18 17:01:40 -07006208 RETURN VALUE
6209 OMX Error None if everything is successful.
6210 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006212 OMX_OUT OMX_U8* role,
6213 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214{
Arun Menon906de572013-06-18 17:01:40 -07006215 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006216
Arun Menon906de572013-06-18 17:01:40 -07006217 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6218 if ((0 == index) && role) {
6219 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006220 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006221 } else {
6222 eRet = OMX_ErrorNoMore;
6223 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006224 }
Arun Menon906de572013-06-18 17:01:40 -07006225 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6226 if ((0 == index) && role) {
6227 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006228 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006229 } else {
6230 eRet = OMX_ErrorNoMore;
6231 }
6232 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6233 if ((0 == index) && role) {
6234 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006235 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006236 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006237 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006238 eRet = OMX_ErrorNoMore;
6239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006240 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241
Arun Menon906de572013-06-18 17:01:40 -07006242 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6243 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6244 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006245
Shalaj Jain273b3e02012-06-22 19:08:03 -07006246 {
Arun Menon906de572013-06-18 17:01:40 -07006247 if ((0 == index) && role) {
6248 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006249 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006250 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006251 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006252 eRet = OMX_ErrorNoMore;
6253 }
6254 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6255 if ((0 == index) && role) {
6256 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006257 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006258 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006259 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006260 eRet = OMX_ErrorNoMore;
6261 }
6262 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6263 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6264 ) {
6265 if ((0 == index) && role) {
6266 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006267 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006268 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006269 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006270 eRet = OMX_ErrorNoMore;
6271 }
6272 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6273 if ((0 == index) && role) {
6274 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006275 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006276 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006277 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006278 eRet = OMX_ErrorNoMore;
6279 }
6280 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006281 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006282 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006283 }
Arun Menon906de572013-06-18 17:01:40 -07006284 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006285}
6286
6287
6288
6289
6290/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006291 FUNCTION
6292 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006293
Arun Menon906de572013-06-18 17:01:40 -07006294 DESCRIPTION
6295 Checks if entire buffer pool is allocated by IL Client or not.
6296 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006297
Arun Menon906de572013-06-18 17:01:40 -07006298 PARAMETERS
6299 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006300
Arun Menon906de572013-06-18 17:01:40 -07006301 RETURN VALUE
6302 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006303
Arun Menon906de572013-06-18 17:01:40 -07006304 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006305bool omx_vdec::allocate_done(void)
6306{
Arun Menon906de572013-06-18 17:01:40 -07006307 bool bRet = false;
6308 bool bRet_In = false;
6309 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310
Arun Menon906de572013-06-18 17:01:40 -07006311 bRet_In = allocate_input_done();
6312 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006313
Arun Menon906de572013-06-18 17:01:40 -07006314 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006315 bRet = true;
6316 }
Arun Menon906de572013-06-18 17:01:40 -07006317
6318 return bRet;
6319}
6320/* ======================================================================
6321 FUNCTION
6322 omx_vdec::AllocateInputDone
6323
6324 DESCRIPTION
6325 Checks if I/P buffer pool is allocated by IL Client or not.
6326
6327 PARAMETERS
6328 None.
6329
6330 RETURN VALUE
6331 true/false.
6332
6333 ========================================================================== */
6334bool omx_vdec::allocate_input_done(void)
6335{
6336 bool bRet = false;
6337 unsigned i=0;
6338
6339 if (m_inp_mem_ptr == NULL) {
6340 return bRet;
6341 }
6342 if (m_inp_mem_ptr ) {
6343 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6344 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6345 break;
6346 }
6347 }
6348 }
6349 if (i == drv_ctx.ip_buf.actualcount) {
6350 bRet = true;
6351 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6352 }
6353 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6354 m_inp_bPopulated = OMX_TRUE;
6355 }
6356 return bRet;
6357}
6358/* ======================================================================
6359 FUNCTION
6360 omx_vdec::AllocateOutputDone
6361
6362 DESCRIPTION
6363 Checks if entire O/P buffer pool is allocated by IL Client or not.
6364
6365 PARAMETERS
6366 None.
6367
6368 RETURN VALUE
6369 true/false.
6370
6371 ========================================================================== */
6372bool omx_vdec::allocate_output_done(void)
6373{
6374 bool bRet = false;
6375 unsigned j=0;
6376
6377 if (m_out_mem_ptr == NULL) {
6378 return bRet;
6379 }
6380
6381 if (m_out_mem_ptr) {
6382 for (; j < drv_ctx.op_buf.actualcount; j++) {
6383 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6384 break;
6385 }
6386 }
6387 }
6388
6389 if (j == drv_ctx.op_buf.actualcount) {
6390 bRet = true;
6391 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6392 if (m_out_bEnabled)
6393 m_out_bPopulated = OMX_TRUE;
6394 }
6395
6396 return bRet;
6397}
6398
6399/* ======================================================================
6400 FUNCTION
6401 omx_vdec::ReleaseDone
6402
6403 DESCRIPTION
6404 Checks if IL client has released all the buffers.
6405
6406 PARAMETERS
6407 None.
6408
6409 RETURN VALUE
6410 true/false
6411
6412 ========================================================================== */
6413bool omx_vdec::release_done(void)
6414{
6415 bool bRet = false;
6416
6417 if (release_input_done()) {
6418 if (release_output_done()) {
6419 bRet = true;
6420 }
6421 }
6422 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006423}
6424
6425
6426/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006427 FUNCTION
6428 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006429
Arun Menon906de572013-06-18 17:01:40 -07006430 DESCRIPTION
6431 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006432
Arun Menon906de572013-06-18 17:01:40 -07006433 PARAMETERS
6434 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006435
Arun Menon906de572013-06-18 17:01:40 -07006436 RETURN VALUE
6437 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006438
Arun Menon906de572013-06-18 17:01:40 -07006439 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006440bool omx_vdec::release_output_done(void)
6441{
Arun Menon906de572013-06-18 17:01:40 -07006442 bool bRet = false;
6443 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006444
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006445 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006446 if (m_out_mem_ptr) {
6447 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6448 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6449 break;
6450 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006451 }
Arun Menon906de572013-06-18 17:01:40 -07006452 if (j == drv_ctx.op_buf.actualcount) {
6453 m_out_bm_count = 0;
6454 bRet = true;
6455 }
6456 } else {
6457 m_out_bm_count = 0;
6458 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006459 }
Arun Menon906de572013-06-18 17:01:40 -07006460 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461}
6462/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006463 FUNCTION
6464 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006465
Arun Menon906de572013-06-18 17:01:40 -07006466 DESCRIPTION
6467 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006468
Arun Menon906de572013-06-18 17:01:40 -07006469 PARAMETERS
6470 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006471
Arun Menon906de572013-06-18 17:01:40 -07006472 RETURN VALUE
6473 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006474
Arun Menon906de572013-06-18 17:01:40 -07006475 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006476bool omx_vdec::release_input_done(void)
6477{
Arun Menon906de572013-06-18 17:01:40 -07006478 bool bRet = false;
6479 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006480
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006481 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006482 if (m_inp_mem_ptr) {
6483 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6484 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6485 break;
6486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006487 }
Arun Menon906de572013-06-18 17:01:40 -07006488 if (j==drv_ctx.ip_buf.actualcount) {
6489 bRet = true;
6490 }
6491 } else {
6492 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006493 }
Arun Menon906de572013-06-18 17:01:40 -07006494 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006495}
6496
6497OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006498 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006499{
Arun Menon906de572013-06-18 17:01:40 -07006500 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306501 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006502 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006503 return OMX_ErrorBadParameter;
6504 } else if (output_flush_progress) {
6505 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6506 buffer->nFilledLen = 0;
6507 buffer->nTimeStamp = 0;
6508 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6509 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6510 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006511 }
6512
Arun Menon906de572013-06-18 17:01:40 -07006513 if (m_debug_extradata) {
6514 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006515 DEBUG_PRINT_HIGH("");
6516 DEBUG_PRINT_HIGH("***************************************************");
6517 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6518 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006519 }
6520
6521 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006522 DEBUG_PRINT_HIGH("");
6523 DEBUG_PRINT_HIGH("***************************************************");
6524 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6525 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006526 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006527 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006528
6529
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006530 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006531 buffer, buffer->pBuffer);
6532 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006533
Arun Menon906de572013-06-18 17:01:40 -07006534 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006535 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006536 if (!output_flush_progress)
6537 post_event((unsigned)NULL, (unsigned)NULL,
6538 OMX_COMPONENT_GENERATE_EOS_DONE);
6539
6540 if (psource_frame) {
6541 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6542 psource_frame = NULL;
6543 }
6544 if (pdest_frame) {
6545 pdest_frame->nFilledLen = 0;
6546 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6547 (unsigned)NULL);
6548 pdest_frame = NULL;
6549 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006550 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006551
Shalaj Jain273b3e02012-06-22 19:08:03 -07006552
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006553 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6554 DEBUG_PRINT_LOW("Processing extradata");
6555 handle_extradata(buffer);
6556 }
6557
Arun Menon906de572013-06-18 17:01:40 -07006558 /* For use buffer we need to copy the data */
6559 if (!output_flush_progress) {
6560 /* This is the error check for non-recoverable errros */
6561 bool is_duplicate_ts_valid = true;
6562 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006563
Arun Menon906de572013-06-18 17:01:40 -07006564 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6565 output_capability == V4L2_PIX_FMT_MPEG2 ||
6566 output_capability == V4L2_PIX_FMT_DIVX ||
6567 output_capability == V4L2_PIX_FMT_DIVX_311)
6568 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006569
Arun Menon906de572013-06-18 17:01:40 -07006570 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006571 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006572 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306573 }
Arun Menon906de572013-06-18 17:01:40 -07006574 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306575
Arun Menon906de572013-06-18 17:01:40 -07006576 if (buffer->nFilledLen > 0) {
6577 time_stamp_dts.get_next_timestamp(buffer,
6578 is_interlaced && is_duplicate_ts_valid);
6579 if (m_debug_timestamp) {
6580 {
6581 OMX_TICKS expected_ts = 0;
6582 m_timestamp_list.pop_min_ts(expected_ts);
6583 if (is_interlaced && is_duplicate_ts_valid) {
6584 m_timestamp_list.pop_min_ts(expected_ts);
6585 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006586 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006587 buffer->nTimeStamp, expected_ts);
6588
6589 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006590 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006591 }
6592 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306593 }
Arun Menon906de572013-06-18 17:01:40 -07006594 } else {
Arun Menon906de572013-06-18 17:01:40 -07006595 time_stamp_dts.remove_time_stamp(
6596 buffer->nTimeStamp,
6597 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306598 }
Arun Menon906de572013-06-18 17:01:40 -07006599
6600
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006601 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006602
Arun Menon906de572013-06-18 17:01:40 -07006603 if (m_cb.FillBufferDone) {
6604 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006605 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006606 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006607 else
6608 set_frame_rate(buffer->nTimeStamp);
6609
Arun Menon906de572013-06-18 17:01:40 -07006610 if (perf_flag) {
6611 if (!proc_frms) {
6612 dec_time.stop();
6613 latency = dec_time.processing_time_us() - latency;
6614 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6615 dec_time.start();
6616 fps_metrics.start();
6617 }
6618 proc_frms++;
6619 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6620 OMX_U64 proc_time = 0;
6621 fps_metrics.stop();
6622 proc_time = fps_metrics.processing_time_us();
6623 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006624 proc_frms, (float)proc_time / 1e6,
6625 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006626 proc_frms = 0;
6627 }
6628 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006629
6630#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006631 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632
Arun Menon906de572013-06-18 17:01:40 -07006633 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6634 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6635 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6636 buffer->nFilledLen + 3)&(~3));
6637 while (p_extra &&
6638 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006639 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006640 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6641 if (p_extra->eType == OMX_ExtraDataNone) {
6642 break;
6643 }
6644 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6645 }
6646 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006647#endif
Arun Menon906de572013-06-18 17:01:40 -07006648 }
6649 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6650 prev_ts = LLONG_MAX;
6651 rst_prev_ts = true;
6652 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006653
Arun Menon906de572013-06-18 17:01:40 -07006654 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6655 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6656 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006657 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006658 OMX_BUFFERHEADERTYPE *il_buffer;
6659 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006660
vivek mehta79cff222014-01-22 12:17:07 -08006661 if (il_buffer && m_last_rendered_TS >= 0) {
6662 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306663 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006664
6665 // Current frame can be send for rendering if
6666 // (a) current FPS is <= 60
6667 // (b) is the next frame after the frame with TS 0
6668 // (c) is the first frame after seek
6669 // (d) the delta TS b\w two consecutive frames is > 16 ms
6670 // (e) its TS is equal to previous frame TS
6671 // (f) if marked EOS
6672
6673 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6674 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6675 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006676 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006677 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006678 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006679 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006680 }
6681
6682 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6683 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6684 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006685 }
6686
vivek mehta79cff222014-01-22 12:17:07 -08006687 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006688 log_output_buffers(il_buffer);
6689 if (dynamic_buf_mode) {
6690 unsigned int nPortIndex = 0;
6691 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6692
6693 if (!secure_mode) {
6694 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6695 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6696 }
6697
6698 //Clear graphic buffer handles in dynamic mode
6699 native_buffer[nPortIndex].privatehandle = NULL;
6700 native_buffer[nPortIndex].nativehandle = NULL;
6701 }
Arun Menon906de572013-06-18 17:01:40 -07006702 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006703 } else {
Arun Menon906de572013-06-18 17:01:40 -07006704 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6705 return OMX_ErrorBadParameter;
6706 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006707 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006708 } else {
6709 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006711
Praveen Chavancf924182013-12-06 23:16:23 -08006712#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306713 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006714 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6715 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306716 private_handle_t *private_handle = NULL;
Praveen Chavancf924182013-12-06 23:16:23 -08006717 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6718 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306719 if (native_buffer[buf_index].privatehandle)
6720 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006721 if (private_handle) {
6722 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6723 dim.sliceWidth, dim.sliceHeight);
6724 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6725 }
6726 }
6727#endif
6728
Arun Menon906de572013-06-18 17:01:40 -07006729 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006730}
6731
6732OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006733 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006734{
6735
Surajit Podderd2644d52013-08-28 17:59:06 +05306736 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006737 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006738 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006739 }
6740
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006741 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006742 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006743 pending_input_buffers--;
6744
Arun Menon906de572013-06-18 17:01:40 -07006745 if (arbitrary_bytes) {
6746 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006747 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006748 pdest_frame = buffer;
6749 buffer->nFilledLen = 0;
6750 buffer->nTimeStamp = LLONG_MAX;
6751 push_input_buffer (hComp);
6752 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006753 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006754 buffer->nFilledLen = 0;
6755 if (!m_input_free_q.insert_entry((unsigned)buffer,
6756 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006757 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759 }
Arun Menon906de572013-06-18 17:01:40 -07006760 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006762 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006763 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6764 }
6765 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6766 }
6767 return OMX_ErrorNone;
6768}
6769
Shalaj Jain273b3e02012-06-22 19:08:03 -07006770int omx_vdec::async_message_process (void *context, void* message)
6771{
Arun Menon906de572013-06-18 17:01:40 -07006772 omx_vdec* omx = NULL;
6773 struct vdec_msginfo *vdec_msg = NULL;
6774 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6775 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6776 struct vdec_output_frameinfo *output_respbuf = NULL;
6777 int rc=1;
6778 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006779 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006780 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006781 }
Arun Menon906de572013-06-18 17:01:40 -07006782 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006783
Arun Menon906de572013-06-18 17:01:40 -07006784 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006785
Arun Menon906de572013-06-18 17:01:40 -07006786 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006787
Arun Menon906de572013-06-18 17:01:40 -07006788 case VDEC_MSG_EVT_HW_ERROR:
6789 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6790 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6791 break;
6792
6793 case VDEC_MSG_RESP_START_DONE:
6794 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6795 OMX_COMPONENT_GENERATE_START_DONE);
6796 break;
6797
6798 case VDEC_MSG_RESP_STOP_DONE:
6799 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6800 OMX_COMPONENT_GENERATE_STOP_DONE);
6801 break;
6802
6803 case VDEC_MSG_RESP_RESUME_DONE:
6804 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6805 OMX_COMPONENT_GENERATE_RESUME_DONE);
6806 break;
6807
6808 case VDEC_MSG_RESP_PAUSE_DONE:
6809 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6810 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6811 break;
6812
6813 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6814 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6815 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6816 break;
6817 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6818 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6819 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6820 break;
6821 case VDEC_MSG_RESP_INPUT_FLUSHED:
6822 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6823
6824 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6825 vdec_msg->msgdata.input_frame_clientdata; */
6826
6827 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6828 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6829 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306830 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006831 omxhdr = NULL;
6832 vdec_msg->status_code = VDEC_S_EFATAL;
6833 }
6834 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6835 DEBUG_PRINT_HIGH("Unsupported input");
6836 omx->omx_report_error ();
6837 }
6838 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6839 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6840 }
6841 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6842 OMX_COMPONENT_GENERATE_EBD);
6843 break;
6844 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6845 int64_t *timestamp;
6846 timestamp = (int64_t *) malloc(sizeof(int64_t));
6847 if (timestamp) {
6848 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6849 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6850 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006851 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006852 vdec_msg->msgdata.output_frame.time_stamp);
6853 }
6854 break;
6855 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6856 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6857
6858 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6859 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6860 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6861 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6862 vdec_msg->msgdata.output_frame.pic_type);
6863
6864 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306865 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006866 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306867 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006868 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6869 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6870 }
Arun Menon906de572013-06-18 17:01:40 -07006871 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6872 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6873 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6874 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6875 omxhdr->nFlags = 0;
6876
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006877 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006878 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6879 //rc = -1;
6880 }
6881 if (omxhdr->nFilledLen) {
6882 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6883 }
6884 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6885 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6886 } else {
6887 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6888 }
6889 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6890 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6891 }
6892 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6893 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6894 }
Arun Menon7b6fd642014-02-13 16:48:36 -08006895
6896 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
6897 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
6898 }
6899
Arun Menonbdb80b02013-08-12 17:45:54 -07006900 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006901 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006902 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6903 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6904 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006905 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6906 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6907 omxhdr->nOffset);
6908 }
Arun Menon906de572013-06-18 17:01:40 -07006909 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6910 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006911 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006912 omx->time_stamp_dts.remove_time_stamp(
6913 omxhdr->nTimeStamp,
6914 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6915 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006916 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6917 OMX_COMPONENT_GENERATE_FTB);
6918 break;
6919 }
6920 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6921 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6922 }
6923 vdec_msg->msgdata.output_frame.bufferaddr =
6924 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6925 int format_notably_changed = 0;
6926 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306927 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006928 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6929 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006930 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006931 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6932 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6933 format_notably_changed = 1;
6934 }
6935 }
6936 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6937 vdec_msg->msgdata.output_frame.framesize.left)
6938 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6939 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6940 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6941 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6942 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6943 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6944 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006945 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006946 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6947 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6948 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006949 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006950 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6951 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006952 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6953 omx->drv_ctx.video_resolution.frame_width) {
6954 vdec_msg->msgdata.output_frame.framesize.left = 0;
6955 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6956 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6957 }
6958 }
6959 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6960 omx->drv_ctx.video_resolution.frame_height) {
6961 vdec_msg->msgdata.output_frame.framesize.top = 0;
6962 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6963 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6964 }
6965 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006966 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 -07006967 vdec_msg->msgdata.output_frame.framesize.left,
6968 vdec_msg->msgdata.output_frame.framesize.top,
6969 vdec_msg->msgdata.output_frame.framesize.right,
6970 vdec_msg->msgdata.output_frame.framesize.bottom,
6971 omx->drv_ctx.video_resolution.frame_width,
6972 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006973 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6974 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6975 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6976 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6977 format_notably_changed = 1;
6978 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006979 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006980 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6981 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006982 if (format_notably_changed) {
6983 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306984 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006985 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6986 } else {
6987 if (!omx->client_buffers.update_buffer_req()) {
6988 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6989 }
6990 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6991 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6992 }
6993 }
6994 if (omxhdr->nFilledLen)
6995 omx->prev_n_filled_len = omxhdr->nFilledLen;
6996
6997 output_respbuf = (struct vdec_output_frameinfo *)\
6998 omxhdr->pOutputPortPrivate;
6999 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7000 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
7001 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7002 output_respbuf->pic_type = PICTURE_TYPE_I;
7003 }
7004 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7005 output_respbuf->pic_type = PICTURE_TYPE_P;
7006 }
7007 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7008 output_respbuf->pic_type = PICTURE_TYPE_B;
7009 }
7010
7011 if (omx->output_use_buffer)
7012 memcpy ( omxhdr->pBuffer, (void *)
7013 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7014 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7015 vdec_msg->msgdata.output_frame.len);
7016 } else
7017 omxhdr->nFilledLen = 0;
7018 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7019 OMX_COMPONENT_GENERATE_FBD);
7020 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
7021 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7022 OMX_COMPONENT_GENERATE_EOS_DONE);
7023 else
7024 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7025 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7026 break;
7027 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007028 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007029 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7030 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7031 break;
7032 default:
7033 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007034 }
Arun Menon906de572013-06-18 17:01:40 -07007035 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007036}
7037
7038OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007039 OMX_HANDLETYPE hComp,
7040 OMX_BUFFERHEADERTYPE *buffer
7041 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007042{
Arun Menon906de572013-06-18 17:01:40 -07007043 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007044 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007045
Arun Menon906de572013-06-18 17:01:40 -07007046 if (buffer == NULL) {
7047 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007048 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007049 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7050 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007051 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7052
7053 /* return zero length and not an EOS buffer */
7054 /* return buffer if input flush in progress */
7055 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7056 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007057 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007058 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7059 return OMX_ErrorNone;
7060 }
7061
7062 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007063 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007064 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007065 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007066 push_input_buffer (hComp);
7067 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007068 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007069 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7070 (unsigned)NULL)) {
7071 return OMX_ErrorBadParameter;
7072 }
7073 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007074
7075
Arun Menon906de572013-06-18 17:01:40 -07007076 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007077}
7078
7079OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7080{
Arun Menon906de572013-06-18 17:01:40 -07007081 unsigned address,p2,id;
7082 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007083
Arun Menon906de572013-06-18 17:01:40 -07007084 if (pdest_frame == NULL || psource_frame == NULL) {
7085 /*Check if we have a destination buffer*/
7086 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007087 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007088 if (m_input_free_q.m_size) {
7089 m_input_free_q.pop_entry(&address,&p2,&id);
7090 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7091 pdest_frame->nFilledLen = 0;
7092 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007093 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007094 }
7095 }
7096
7097 /*Check if we have a destination buffer*/
7098 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007099 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007100 if (m_input_pending_q.m_size) {
7101 m_input_pending_q.pop_entry(&address,&p2,&id);
7102 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007103 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007104 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007105 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007106 psource_frame->nFlags,psource_frame->nFilledLen);
7107
7108 }
7109 }
7110
Shalaj Jain273b3e02012-06-22 19:08:03 -07007111 }
7112
Arun Menon906de572013-06-18 17:01:40 -07007113 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7114 switch (codec_type_parse) {
7115 case CODEC_TYPE_MPEG4:
7116 case CODEC_TYPE_H263:
7117 case CODEC_TYPE_MPEG2:
7118 ret = push_input_sc_codec(hComp);
7119 break;
7120 case CODEC_TYPE_H264:
7121 ret = push_input_h264(hComp);
7122 break;
7123 case CODEC_TYPE_VC1:
7124 ret = push_input_vc1(hComp);
7125 break;
7126 default:
7127 break;
7128 }
7129 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007130 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007131 omx_report_error ();
7132 break;
7133 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007134 }
7135
Arun Menon906de572013-06-18 17:01:40 -07007136 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007137}
7138
7139OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7140{
Arun Menon906de572013-06-18 17:01:40 -07007141 OMX_U32 partial_frame = 1;
7142 OMX_BOOL generate_ebd = OMX_TRUE;
7143 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007144
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007145 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007146 psource_frame,psource_frame->nTimeStamp);
7147 if (m_frame_parser.parse_sc_frame(psource_frame,
7148 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007149 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007150 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007151 }
Arun Menon906de572013-06-18 17:01:40 -07007152
7153 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007154 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007155 pdest_frame->nFilledLen,psource_frame,frame_count);
7156
7157
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007158 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007159 /*First Parsed buffer will have only header Hence skip*/
7160 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007161 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007162
7163 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7164 codec_type_parse == CODEC_TYPE_DIVX) {
7165 mp4StreamType psBits;
7166 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7167 psBits.numBytes = pdest_frame->nFilledLen;
7168 mp4_headerparser.parseHeader(&psBits);
7169 }
7170
7171 frame_count++;
7172 } else {
7173 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7174 if (pdest_frame->nFilledLen) {
7175 /*Push the frame to the Decoder*/
7176 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7177 return OMX_ErrorBadParameter;
7178 }
7179 frame_count++;
7180 pdest_frame = NULL;
7181
7182 if (m_input_free_q.m_size) {
7183 m_input_free_q.pop_entry(&address,&p2,&id);
7184 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7185 pdest_frame->nFilledLen = 0;
7186 }
7187 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007188 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007189 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7190 (unsigned)NULL);
7191 pdest_frame = NULL;
7192 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007193 }
Arun Menon906de572013-06-18 17:01:40 -07007194 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007195 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007196 /*Check if Destination Buffer is full*/
7197 if (pdest_frame->nAllocLen ==
7198 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007199 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007200 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203
Arun Menon906de572013-06-18 17:01:40 -07007204 if (psource_frame->nFilledLen == 0) {
7205 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7206 if (pdest_frame) {
7207 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007208 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007209 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007210 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007211 pdest_frame->nFilledLen,frame_count++);
7212 /*Push the frame to the Decoder*/
7213 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7214 return OMX_ErrorBadParameter;
7215 }
7216 frame_count++;
7217 pdest_frame = NULL;
7218 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007219 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007220 generate_ebd = OMX_FALSE;
7221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007222 }
Arun Menon906de572013-06-18 17:01:40 -07007223 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007224 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007225 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7226 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007227
Arun Menon906de572013-06-18 17:01:40 -07007228 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007229 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007230 m_input_pending_q.pop_entry(&address,&p2,&id);
7231 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007232 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007233 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007234 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007235 psource_frame->nFlags,psource_frame->nFilledLen);
7236 }
7237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007238 }
Arun Menon906de572013-06-18 17:01:40 -07007239 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007240}
7241
7242OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7243{
Arun Menon906de572013-06-18 17:01:40 -07007244 OMX_U32 partial_frame = 1;
7245 unsigned address = 0, p2 = 0, id = 0;
7246 OMX_BOOL isNewFrame = OMX_FALSE;
7247 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007248
Arun Menon906de572013-06-18 17:01:40 -07007249 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007250 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007251 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007252 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007253 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007254 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007255 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007256 if (h264_scratch.nFilledLen && look_ahead_nal) {
7257 look_ahead_nal = false;
7258 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7259 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007260 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7261 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7262 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007263 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007264 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007265 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007266 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007267 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007268 }
Arun Menon906de572013-06-18 17:01:40 -07007269 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007270
7271 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7272 in EOS flag getting associated with the destination
7273 */
7274 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7275 pdest_frame->nFilledLen) {
7276 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7277 generate_ebd = OMX_FALSE;
7278 }
7279
Arun Menon906de572013-06-18 17:01:40 -07007280 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007281 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007282 if (m_frame_parser.parse_sc_frame(psource_frame,
7283 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007284 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007285 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007286 }
Arun Menon906de572013-06-18 17:01:40 -07007287 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007288 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007289 if (m_frame_parser.parse_h264_nallength(psource_frame,
7290 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007291 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007292 return OMX_ErrorBadParameter;
7293 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007294 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007295
Arun Menon906de572013-06-18 17:01:40 -07007296 if (partial_frame == 0) {
7297 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007298 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007299 nal_count++;
7300 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7301 h264_scratch.nFlags = psource_frame->nFlags;
7302 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007303 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007304 if (h264_scratch.nFilledLen) {
7305 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7306 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007307#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007308 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7309 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7310 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7311 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7312 // If timeinfo is present frame info from SEI is already processed
7313 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7314 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007315#endif
Arun Menon906de572013-06-18 17:01:40 -07007316 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7317 nal_count++;
7318 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7319 pdest_frame->nTimeStamp = h264_last_au_ts;
7320 pdest_frame->nFlags = h264_last_au_flags;
7321#ifdef PANSCAN_HDLR
7322 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7323 h264_parser->update_panscan_data(h264_last_au_ts);
7324#endif
7325 }
7326 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7327 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7328 h264_last_au_ts = h264_scratch.nTimeStamp;
7329 h264_last_au_flags = h264_scratch.nFlags;
7330#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7331 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7332 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7333 if (!VALID_TS(h264_last_au_ts))
7334 h264_last_au_ts = ts_in_sei;
7335 }
7336#endif
7337 } else
7338 h264_last_au_ts = LLONG_MAX;
7339 }
7340
7341 if (!isNewFrame) {
7342 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7343 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007344 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007345 h264_scratch.nFilledLen);
7346 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7347 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7348 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7349 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7350 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7351 h264_scratch.nFilledLen = 0;
7352 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007353 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007354 return OMX_ErrorBadParameter;
7355 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007356 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007357 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007358 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007359 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007360 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007361 pdest_frame->nFilledLen,frame_count++);
7362
7363 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007364 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007365 look_ahead_nal = false;
7366 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7367 h264_scratch.nFilledLen) {
7368 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7369 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7370 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7371 h264_scratch.nFilledLen = 0;
7372 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007373 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007374 return OMX_ErrorBadParameter;
7375 }
7376 } else {
7377 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007378 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007379 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7380 }
7381 /*Push the frame to the Decoder*/
7382 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7383 return OMX_ErrorBadParameter;
7384 }
7385 //frame_count++;
7386 pdest_frame = NULL;
7387 if (m_input_free_q.m_size) {
7388 m_input_free_q.pop_entry(&address,&p2,&id);
7389 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007390 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007391 pdest_frame->nFilledLen = 0;
7392 pdest_frame->nFlags = 0;
7393 pdest_frame->nTimeStamp = LLONG_MAX;
7394 }
7395 }
7396 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007397 }
Arun Menon906de572013-06-18 17:01:40 -07007398 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007399 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007400 /*Check if Destination Buffer is full*/
7401 if (h264_scratch.nAllocLen ==
7402 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007403 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007404 return OMX_ErrorStreamCorrupt;
7405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007406 }
Arun Menon906de572013-06-18 17:01:40 -07007407
7408 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007409 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007410
7411 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7412 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007413 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007414 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7415 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007416 if(pdest_frame->nFilledLen == 0) {
7417 /* No residual frame from before, send whatever
7418 * we have left */
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_scratch.nTimeStamp;
7424 } else {
7425 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7426 if(!isNewFrame) {
7427 /* Have a residual frame, but we know that the
7428 * AU in this frame is belonging to whatever
7429 * frame we had left over. So append it */
7430 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7431 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7432 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7433 h264_scratch.nFilledLen = 0;
7434 pdest_frame->nTimeStamp = h264_last_au_ts;
7435 } else {
7436 /* Completely new frame, let's just push what
7437 * we have now. The resulting EBD would trigger
7438 * another push */
7439 generate_ebd = OMX_FALSE;
7440 pdest_frame->nTimeStamp = h264_last_au_ts;
7441 h264_last_au_ts = h264_scratch.nTimeStamp;
7442 }
7443 }
Arun Menon906de572013-06-18 17:01:40 -07007444 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007445 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007446 return OMX_ErrorBadParameter;
7447 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007448
7449 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7450 if(generate_ebd == OMX_TRUE) {
7451 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7452 }
Arun Menon906de572013-06-18 17:01:40 -07007453
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007454 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007455 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007457#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7458 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7459 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7460 if (!VALID_TS(pdest_frame->nTimeStamp))
7461 pdest_frame->nTimeStamp = ts_in_sei;
7462 }
7463#endif
7464 /*Push the frame to the Decoder*/
7465 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7466 return OMX_ErrorBadParameter;
7467 }
7468 frame_count++;
7469 pdest_frame = NULL;
7470 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007471 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007472 pdest_frame,h264_scratch.nFilledLen);
7473 generate_ebd = OMX_FALSE;
7474 }
7475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007476 }
Arun Menon906de572013-06-18 17:01:40 -07007477 if (generate_ebd && !psource_frame->nFilledLen) {
7478 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7479 psource_frame = NULL;
7480 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007481 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007482 m_input_pending_q.pop_entry(&address,&p2,&id);
7483 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007484 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007485 psource_frame->nFlags,psource_frame->nFilledLen);
7486 }
7487 }
7488 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007489}
7490
7491OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7492{
7493 OMX_U8 *buf, *pdest;
7494 OMX_U32 partial_frame = 1;
7495 OMX_U32 buf_len, dest_len;
7496
Arun Menon906de572013-06-18 17:01:40 -07007497 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007498 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007499 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007500 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007501 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007502 buf = psource_frame->pBuffer;
7503 buf_len = psource_frame->nFilledLen;
7504
7505 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007506 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007507 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007508 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007509 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007510 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007511 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007512 return OMX_ErrorStreamCorrupt;
7513 }
Arun Menon906de572013-06-18 17:01:40 -07007514 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7516 pdest_frame->nOffset;
7517 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007518 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007519
Arun Menon906de572013-06-18 17:01:40 -07007520 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007521 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007522 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007523 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007524 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7525 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7526 }
7527 }
7528 }
7529
Arun Menon906de572013-06-18 17:01:40 -07007530 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007531 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007532 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007533 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007534 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007535 return OMX_ErrorBadParameter;
7536 }
Arun Menon906de572013-06-18 17:01:40 -07007537 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007538
7539 case VC1_SP_MP_RCV:
7540 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007541 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007542 return OMX_ErrorBadParameter;
7543 }
7544 return OMX_ErrorNone;
7545}
7546
David Ng38e2d232013-03-15 20:05:58 -07007547#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007548bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007549 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007550{
Arun Menon906de572013-06-18 17:01:40 -07007551 struct pmem_allocation allocation;
7552 allocation.size = buffer_size;
7553 allocation.align = clip2(alignment);
7554 if (allocation.align < 4096) {
7555 allocation.align = 4096;
7556 }
7557 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007558 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007559 allocation.align, allocation.size);
7560 return false;
7561 }
7562 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007563}
David Ng38e2d232013-03-15 20:05:58 -07007564#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565#ifdef USE_ION
7566int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007567 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7568 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007569{
Arun Menon906de572013-06-18 17:01:40 -07007570 int fd = -EINVAL;
7571 int rc = -EINVAL;
7572 int ion_dev_flag;
7573 struct vdec_ion ion_buf_info;
7574 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007575 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007576 return -EINVAL;
7577 }
7578 ion_dev_flag = O_RDONLY;
7579 fd = open (MEM_DEVICE, ion_dev_flag);
7580 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007581 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007582 return fd;
7583 }
7584 alloc_data->flags = 0;
7585 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7586 alloc_data->flags |= ION_FLAG_CACHED;
7587 }
7588 alloc_data->len = buffer_size;
7589 alloc_data->align = clip2(alignment);
7590 if (alloc_data->align < 4096) {
7591 alloc_data->align = 4096;
7592 }
7593 if ((secure_mode) && (flag & ION_SECURE))
7594 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007595
Arun Menon906de572013-06-18 17:01:40 -07007596 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307597 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007598 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7599 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7600 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007601 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007602 alloc_data->handle = NULL;
7603 close(fd);
7604 fd = -ENOMEM;
7605 return fd;
7606 }
7607 fd_data->handle = alloc_data->handle;
7608 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7609 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007610 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007611 ion_buf_info.ion_alloc_data = *alloc_data;
7612 ion_buf_info.ion_device_fd = fd;
7613 ion_buf_info.fd_ion_data = *fd_data;
7614 free_ion_memory(&ion_buf_info);
7615 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007616 fd = -ENOMEM;
7617 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007618
Arun Menon906de572013-06-18 17:01:40 -07007619 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007620}
7621
Arun Menon906de572013-06-18 17:01:40 -07007622void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7623{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007624
Arun Menon906de572013-06-18 17:01:40 -07007625 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007626 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007627 return;
7628 }
7629 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7630 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007631 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007632 }
7633 close(buf_ion_info->ion_device_fd);
7634 buf_ion_info->ion_device_fd = -1;
7635 buf_ion_info->ion_alloc_data.handle = NULL;
7636 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007637}
7638#endif
7639void omx_vdec::free_output_buffer_header()
7640{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007641 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007642 output_use_buffer = false;
7643 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007644
Arun Menon906de572013-06-18 17:01:40 -07007645 if (m_out_mem_ptr) {
7646 free (m_out_mem_ptr);
7647 m_out_mem_ptr = NULL;
7648 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649
Arun Menon906de572013-06-18 17:01:40 -07007650 if (m_platform_list) {
7651 free(m_platform_list);
7652 m_platform_list = NULL;
7653 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007654
Arun Menon906de572013-06-18 17:01:40 -07007655 if (drv_ctx.ptr_respbuffer) {
7656 free (drv_ctx.ptr_respbuffer);
7657 drv_ctx.ptr_respbuffer = NULL;
7658 }
7659 if (drv_ctx.ptr_outputbuffer) {
7660 free (drv_ctx.ptr_outputbuffer);
7661 drv_ctx.ptr_outputbuffer = NULL;
7662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007663#ifdef USE_ION
7664 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007665 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007666 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007667 drv_ctx.op_buf_ion_info = NULL;
7668 }
7669#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007670 if (out_dynamic_list) {
7671 free(out_dynamic_list);
7672 out_dynamic_list = NULL;
7673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007674}
7675
7676void omx_vdec::free_input_buffer_header()
7677{
7678 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007679 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007680 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007681 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007682 free (m_inp_heap_ptr);
7683 m_inp_heap_ptr = NULL;
7684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007685
Arun Menon906de572013-06-18 17:01:40 -07007686 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007687 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007688 free (m_phdr_pmem_ptr);
7689 m_phdr_pmem_ptr = NULL;
7690 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007691 }
Arun Menon906de572013-06-18 17:01:40 -07007692 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007694 free (m_inp_mem_ptr);
7695 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007696 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007697 /* We just freed all the buffer headers, every thing in m_input_free_q,
7698 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007699 while (m_input_free_q.m_size) {
7700 unsigned address, p2, id;
7701 m_input_free_q.pop_entry(&address, &p2, &id);
7702 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007703 while (m_input_pending_q.m_size) {
7704 unsigned address, p2, id;
7705 m_input_pending_q.pop_entry(&address, &p2, &id);
7706 }
7707 pdest_frame = NULL;
7708 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007709 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007710 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007711 free (drv_ctx.ptr_inputbuffer);
7712 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007713 }
7714#ifdef USE_ION
7715 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007716 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007717 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007718 drv_ctx.ip_buf_ion_info = NULL;
7719 }
7720#endif
7721}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007722
7723int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007724{
Arun Menon906de572013-06-18 17:01:40 -07007725 enum v4l2_buf_type btype;
7726 int rc = 0;
7727 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007728
Arun Menon906de572013-06-18 17:01:40 -07007729 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7730 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7731 v4l2_port = OUTPUT_PORT;
7732 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7733 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7734 v4l2_port = CAPTURE_PORT;
7735 } else if (port == OMX_ALL) {
7736 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7737 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007738
Arun Menon906de572013-06-18 17:01:40 -07007739 if (!rc_input)
7740 return rc_input;
7741 else
7742 return rc_output;
7743 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007744
Arun Menon906de572013-06-18 17:01:40 -07007745 if (!streaming[v4l2_port]) {
7746 // already streamed off, warn and move on
7747 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7748 " which is already streamed off", v4l2_port);
7749 return 0;
7750 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007751
Arun Menon906de572013-06-18 17:01:40 -07007752 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007753
Arun Menon906de572013-06-18 17:01:40 -07007754 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7755 if (rc) {
7756 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007757 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007758 } else {
7759 streaming[v4l2_port] = false;
7760 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007761
Arun Menon906de572013-06-18 17:01:40 -07007762 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007763}
7764
7765OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7766{
Arun Menon906de572013-06-18 17:01:40 -07007767 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7768 struct v4l2_requestbuffers bufreq;
7769 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307770 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007771 struct v4l2_format fmt;
7772 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007774 buffer_prop->actualcount, buffer_prop->buffer_size);
7775 bufreq.memory = V4L2_MEMORY_USERPTR;
7776 bufreq.count = 1;
7777 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7778 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7779 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7780 fmt.fmt.pix_mp.pixelformat = output_capability;
7781 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7782 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7783 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7784 fmt.fmt.pix_mp.pixelformat = capture_capability;
7785 } else {
7786 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007787 }
Arun Menon906de572013-06-18 17:01:40 -07007788 if (eRet==OMX_ErrorNone) {
7789 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007790 }
Arun Menon906de572013-06-18 17:01:40 -07007791 if (ret) {
7792 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7793 /*TODO: How to handle this case */
7794 eRet = OMX_ErrorInsufficientResources;
7795 return eRet;
7796 } else {
7797 buffer_prop->actualcount = bufreq.count;
7798 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007799 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007800 }
Arun Menon906de572013-06-18 17:01:40 -07007801 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7802 buffer_prop->actualcount, buffer_prop->buffer_size);
7803
7804 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7805 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7806
7807 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7808
7809 update_resolution(fmt.fmt.pix_mp.width,
7810 fmt.fmt.pix_mp.height,
7811 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7812 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7813 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7814 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007815 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007816
7817 if (ret) {
7818 /*TODO: How to handle this case */
7819 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7820 eRet = OMX_ErrorInsufficientResources;
7821 } else {
7822 int extra_idx = 0;
7823
7824 eRet = is_video_session_supported();
7825 if (eRet)
7826 return eRet;
7827
7828 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7829 buf_size = buffer_prop->buffer_size;
7830 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7831 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7832 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7833 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007834 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007835 return OMX_ErrorBadParameter;
7836 }
7837 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7838 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7839 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7840 }
7841 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7842 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7843 }
7844 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7845 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007846 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007847 client_extra_data_size);
7848 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307849 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7850 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7851 DEBUG_PRINT_HIGH("framepack extradata enabled");
7852 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007853 if (client_extradata & OMX_QP_EXTRADATA) {
7854 client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
7855 DEBUG_PRINT_HIGH("QP extradata enabled");
7856 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08007857 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
7858 client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
7859 DEBUG_PRINT_HIGH("Input bits info extradata enabled");
7860 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007861
Arun Menon906de572013-06-18 17:01:40 -07007862 if (client_extra_data_size) {
7863 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7864 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7865 }
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307866 final_extra_data_size = (extra_data_size > client_extra_data_size ?
7867 extra_data_size : client_extra_data_size);
7868 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007869 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307870 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007871 buf_size += client_extra_data_size;
7872 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7873 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7874 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7875 if (in_reconfig) // BufReq will be set to driver when port is disabled
7876 buffer_prop->buffer_size = buf_size;
7877 else if (buf_size != buffer_prop->buffer_size) {
7878 buffer_prop->buffer_size = buf_size;
7879 eRet = set_buffer_req(buffer_prop);
7880 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007881 }
Arun Menon906de572013-06-18 17:01:40 -07007882 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7883 buffer_prop->actualcount, buffer_prop->buffer_size);
7884 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007885}
7886
7887OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7888{
Arun Menon906de572013-06-18 17:01:40 -07007889 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7890 unsigned buf_size = 0;
7891 struct v4l2_format fmt;
7892 struct v4l2_requestbuffers bufreq;
7893 int ret;
7894 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7895 buffer_prop->actualcount, buffer_prop->buffer_size);
7896 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7897 if (buf_size != buffer_prop->buffer_size) {
7898 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7899 buffer_prop->buffer_size, buf_size);
7900 eRet = OMX_ErrorBadParameter;
7901 } else {
7902 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7903 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007904
Arun Menon906de572013-06-18 17:01:40 -07007905 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7906 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7907 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007908 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007909 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7910 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7911 fmt.fmt.pix_mp.pixelformat = capture_capability;
7912 } else {
7913 eRet = OMX_ErrorBadParameter;
7914 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007915
Arun Menon906de572013-06-18 17:01:40 -07007916 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7917 if (ret) {
7918 /*TODO: How to handle this case */
7919 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7920 eRet = OMX_ErrorInsufficientResources;
7921 }
7922
7923 bufreq.memory = V4L2_MEMORY_USERPTR;
7924 bufreq.count = buffer_prop->actualcount;
7925 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7926 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7927 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7928 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7929 } else {
7930 eRet = OMX_ErrorBadParameter;
7931 }
7932
7933 if (eRet==OMX_ErrorNone) {
7934 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7935 }
7936
7937 if (ret) {
7938 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7939 /*TODO: How to handle this case */
7940 eRet = OMX_ErrorInsufficientResources;
7941 } else if (bufreq.count < buffer_prop->actualcount) {
7942 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7943 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7944 buffer_prop->actualcount, bufreq.count);
7945 eRet = OMX_ErrorInsufficientResources;
7946 } else {
7947 if (!client_buffers.update_buffer_req()) {
7948 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7949 eRet = OMX_ErrorInsufficientResources;
7950 }
7951 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007952 }
Arun Menon906de572013-06-18 17:01:40 -07007953 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007954}
7955
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7957{
Arun Menon906de572013-06-18 17:01:40 -07007958 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7959 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007960}
7961
7962OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7963{
Arun Menon906de572013-06-18 17:01:40 -07007964 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7965 if (!portDefn) {
7966 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007967 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007968 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007969 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7970 portDefn->nSize = sizeof(portDefn);
7971 portDefn->eDomain = OMX_PortDomainVideo;
7972 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08007973 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
7974 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07007975 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007976 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007977 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007978 }
Arun Menon906de572013-06-18 17:01:40 -07007979 if (0 == portDefn->nPortIndex) {
7980 portDefn->eDir = OMX_DirInput;
7981 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7982 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7983 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7984 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7985 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7986 portDefn->bEnabled = m_inp_bEnabled;
7987 portDefn->bPopulated = m_inp_bPopulated;
7988 } else if (1 == portDefn->nPortIndex) {
7989 unsigned int buf_size = 0;
7990 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007991 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007992 return OMX_ErrorHardware;
7993 }
7994 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007995 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007996 return OMX_ErrorHardware;
7997 }
7998 portDefn->nBufferSize = buf_size;
7999 portDefn->eDir = OMX_DirOutput;
8000 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8001 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8002 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8003 portDefn->bEnabled = m_out_bEnabled;
8004 portDefn->bPopulated = m_out_bPopulated;
8005 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008006 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008007 return OMX_ErrorHardware;
8008 }
8009 } else {
8010 portDefn->eDir = OMX_DirMax;
8011 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8012 (int)portDefn->nPortIndex);
8013 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008014 }
Arun Menon906de572013-06-18 17:01:40 -07008015 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8016 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8017 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8018 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praveen Chavandb7776f2014-02-06 18:17:25 -08008019 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8020 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308021 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8022 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8023 }
8024 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8025 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8026 portDefn->nPortIndex,
8027 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008028 portDefn->format.video.nFrameHeight,
8029 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308030 portDefn->format.video.nSliceHeight,
8031 portDefn->format.video.eColorFormat,
8032 portDefn->nBufferSize,
8033 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008034
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308035 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008036}
8037
8038OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8039{
Arun Menon906de572013-06-18 17:01:40 -07008040 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8041 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8042 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008043
Arun Menon906de572013-06-18 17:01:40 -07008044 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008045 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008046 int nBufHdrSize = 0;
8047 int nPlatformEntrySize = 0;
8048 int nPlatformListSize = 0;
8049 int nPMEMInfoSize = 0;
8050 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8051 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8052 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008053
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008054 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008055 drv_ctx.op_buf.actualcount);
8056 nBufHdrSize = drv_ctx.op_buf.actualcount *
8057 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008058
Arun Menon906de572013-06-18 17:01:40 -07008059 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8060 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8061 nPlatformListSize = drv_ctx.op_buf.actualcount *
8062 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8063 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8064 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008065
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008066 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008067 sizeof(OMX_BUFFERHEADERTYPE),
8068 nPMEMInfoSize,
8069 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008070 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008071 m_out_bm_count);
8072 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8073 // Alloc mem for platform specific info
8074 char *pPtr=NULL;
8075 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8076 nPMEMInfoSize,1);
8077 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8078 calloc (sizeof(struct vdec_bufferpayload),
8079 drv_ctx.op_buf.actualcount);
8080 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8081 calloc (sizeof (struct vdec_output_frameinfo),
8082 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008083 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8084 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8085 return OMX_ErrorInsufficientResources;
8086 }
8087
Shalaj Jain273b3e02012-06-22 19:08:03 -07008088#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008089 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8090 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008091 if (!drv_ctx.op_buf_ion_info) {
8092 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8093 return OMX_ErrorInsufficientResources;
8094 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008095#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008096 if (dynamic_buf_mode) {
8097 out_dynamic_list = (struct dynamic_buf_list *) \
8098 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8099 }
Arun Menon906de572013-06-18 17:01:40 -07008100 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8101 && drv_ctx.ptr_respbuffer) {
8102 bufHdr = m_out_mem_ptr;
8103 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8104 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8105 (((char *) m_platform_list) + nPlatformListSize);
8106 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8107 (((char *) m_platform_entry) + nPlatformEntrySize);
8108 pPlatformList = m_platform_list;
8109 pPlatformEntry = m_platform_entry;
8110 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008111
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008112 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008113
Arun Menon906de572013-06-18 17:01:40 -07008114 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008115 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008116 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008117 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008118 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8119 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8120 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8121 // Set the values when we determine the right HxW param
8122 bufHdr->nAllocLen = 0;
8123 bufHdr->nFilledLen = 0;
8124 bufHdr->pAppPrivate = NULL;
8125 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8126 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8127 pPlatformEntry->entry = pPMEMInfo;
8128 // Initialize the Platform List
8129 pPlatformList->nEntries = 1;
8130 pPlatformList->entryList = pPlatformEntry;
8131 // Keep pBuffer NULL till vdec is opened
8132 bufHdr->pBuffer = NULL;
8133 pPMEMInfo->offset = 0;
8134 pPMEMInfo->pmem_fd = 0;
8135 bufHdr->pPlatformPrivate = pPlatformList;
8136 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008137#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008138 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008139#endif
Arun Menon906de572013-06-18 17:01:40 -07008140 /*Create a mapping between buffers*/
8141 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8142 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8143 &drv_ctx.ptr_outputbuffer[i];
8144 // Move the buffer and buffer header pointers
8145 bufHdr++;
8146 pPMEMInfo++;
8147 pPlatformEntry++;
8148 pPlatformList++;
8149 }
8150 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008151 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008152 m_out_mem_ptr, pPtr);
8153 if (m_out_mem_ptr) {
8154 free(m_out_mem_ptr);
8155 m_out_mem_ptr = NULL;
8156 }
8157 if (pPtr) {
8158 free(pPtr);
8159 pPtr = NULL;
8160 }
8161 if (drv_ctx.ptr_outputbuffer) {
8162 free(drv_ctx.ptr_outputbuffer);
8163 drv_ctx.ptr_outputbuffer = NULL;
8164 }
8165 if (drv_ctx.ptr_respbuffer) {
8166 free(drv_ctx.ptr_respbuffer);
8167 drv_ctx.ptr_respbuffer = NULL;
8168 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008169#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008170 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008171 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008172 free(drv_ctx.op_buf_ion_info);
8173 drv_ctx.op_buf_ion_info = NULL;
8174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008175#endif
Arun Menon906de572013-06-18 17:01:40 -07008176 eRet = OMX_ErrorInsufficientResources;
8177 }
8178 } else {
8179 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008180 }
Arun Menon906de572013-06-18 17:01:40 -07008181 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008182}
8183
8184void omx_vdec::complete_pending_buffer_done_cbs()
8185{
Arun Menon906de572013-06-18 17:01:40 -07008186 unsigned p1;
8187 unsigned p2;
8188 unsigned ident;
8189 omx_cmd_queue tmp_q, pending_bd_q;
8190 pthread_mutex_lock(&m_lock);
8191 // pop all pending GENERATE FDB from ftb queue
8192 while (m_ftb_q.m_size) {
8193 m_ftb_q.pop_entry(&p1,&p2,&ident);
8194 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8195 pending_bd_q.insert_entry(p1,p2,ident);
8196 } else {
8197 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008198 }
Arun Menon906de572013-06-18 17:01:40 -07008199 }
8200 //return all non GENERATE FDB to ftb queue
8201 while (tmp_q.m_size) {
8202 tmp_q.pop_entry(&p1,&p2,&ident);
8203 m_ftb_q.insert_entry(p1,p2,ident);
8204 }
8205 // pop all pending GENERATE EDB from etb queue
8206 while (m_etb_q.m_size) {
8207 m_etb_q.pop_entry(&p1,&p2,&ident);
8208 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8209 pending_bd_q.insert_entry(p1,p2,ident);
8210 } else {
8211 tmp_q.insert_entry(p1,p2,ident);
8212 }
8213 }
8214 //return all non GENERATE FDB to etb queue
8215 while (tmp_q.m_size) {
8216 tmp_q.pop_entry(&p1,&p2,&ident);
8217 m_etb_q.insert_entry(p1,p2,ident);
8218 }
8219 pthread_mutex_unlock(&m_lock);
8220 // process all pending buffer dones
8221 while (pending_bd_q.m_size) {
8222 pending_bd_q.pop_entry(&p1,&p2,&ident);
8223 switch (ident) {
8224 case OMX_COMPONENT_GENERATE_EBD:
8225 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008226 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008227 omx_report_error ();
8228 }
8229 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008230
Arun Menon906de572013-06-18 17:01:40 -07008231 case OMX_COMPONENT_GENERATE_FBD:
8232 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008233 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008234 omx_report_error ();
8235 }
8236 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008238 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008239}
8240
8241void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8242{
Arun Menon906de572013-06-18 17:01:40 -07008243 OMX_U32 new_frame_interval = 0;
8244 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8245 && llabs(act_timestamp - prev_ts) > 2000) {
8246 new_frame_interval = client_set_fps ? frm_int :
8247 llabs(act_timestamp - prev_ts);
8248 if (new_frame_interval < frm_int || frm_int == 0) {
8249 frm_int = new_frame_interval;
8250 if (frm_int) {
8251 drv_ctx.frame_rate.fps_numerator = 1e6;
8252 drv_ctx.frame_rate.fps_denominator = frm_int;
8253 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8254 frm_int, drv_ctx.frame_rate.fps_numerator /
8255 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008256
Arun Menon906de572013-06-18 17:01:40 -07008257 /* We need to report the difference between this FBD and the previous FBD
8258 * back to the driver for clock scaling purposes. */
8259 struct v4l2_outputparm oparm;
8260 /*XXX: we're providing timing info as seconds per frame rather than frames
8261 * per second.*/
8262 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8263 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008264
Arun Menon906de572013-06-18 17:01:40 -07008265 struct v4l2_streamparm sparm;
8266 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8267 sparm.parm.output = oparm;
8268 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8269 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8270 performance might be affected");
8271 }
8272
8273 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008274 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008275 }
Arun Menon906de572013-06-18 17:01:40 -07008276 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008277}
8278
8279void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8280{
Arun Menon906de572013-06-18 17:01:40 -07008281 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8282 prev_ts = act_timestamp;
8283 rst_prev_ts = false;
8284 } else if (VALID_TS(prev_ts)) {
8285 bool codec_cond = (drv_ctx.timestamp_adjust)?
8286 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8287 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8288 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8289 if (frm_int > 0 && codec_cond) {
8290 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8291 act_timestamp = prev_ts + frm_int;
8292 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8293 prev_ts = act_timestamp;
8294 } else
8295 set_frame_rate(act_timestamp);
8296 } else if (frm_int > 0) // In this case the frame rate was set along
8297 { // with the port definition, start ts with 0
8298 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8299 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008301}
8302
8303void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8304{
Arun Menon906de572013-06-18 17:01:40 -07008305 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8306 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308307 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008308 OMX_U32 frame_rate = 0;
8309 int consumed_len = 0;
8310 OMX_U32 num_MB_in_frame;
8311 OMX_U32 recovery_sei_flags = 1;
8312 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008313
Arun Menon906de572013-06-18 17:01:40 -07008314 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008315 if (buf_index >= drv_ctx.extradata_info.count) {
8316 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8317 buf_index, drv_ctx.extradata_info.count);
8318 return;
8319 }
Arun Menon906de572013-06-18 17:01:40 -07008320 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8321 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8322 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308323
Arun Menon906de572013-06-18 17:01:40 -07008324 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308325 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008326 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008327 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308328 if (!secure_mode)
8329 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008330 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308331 else
8332 p_extra = m_other_extradata;
8333
Arun Menon906de572013-06-18 17:01:40 -07008334 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308335
8336 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008337 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308338 return;
8339 }
Arun Menon906de572013-06-18 17:01:40 -07008340 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8341 if (data) {
8342 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8343 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308344 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008345 DEBUG_PRINT_LOW("Invalid extra data size");
8346 break;
8347 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308348 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008349 switch ((unsigned long)data->eType) {
8350 case EXTRADATA_INTERLACE_VIDEO:
8351 struct msm_vidc_interlace_payload *payload;
8352 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008353 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008354 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008355 switch (payload->format) {
8356 case INTERLACE_FRAME_PROGRESSIVE:
8357 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8358 enable = 0;
8359 break;
8360 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8361 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8362 break;
8363 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8364 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8365 break;
8366 default:
8367 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8368 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8369 }
Arun Menon906de572013-06-18 17:01:40 -07008370 }
8371 if (m_enable_android_native_buffers)
8372 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8373 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308374 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008375 append_interlace_extradata(p_extra, payload->format,
8376 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008377 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8378 }
8379 break;
8380 case EXTRADATA_FRAME_RATE:
8381 struct msm_vidc_framerate_payload *frame_rate_payload;
8382 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8383 frame_rate = frame_rate_payload->frame_rate;
8384 break;
8385 case EXTRADATA_TIMESTAMP:
8386 struct msm_vidc_ts_payload *time_stamp_payload;
8387 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308388 time_stamp = time_stamp_payload->timestamp_lo;
8389 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8390 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008391 break;
8392 case EXTRADATA_NUM_CONCEALED_MB:
8393 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8394 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8395 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8396 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8397 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8398 break;
8399 case EXTRADATA_INDEX:
8400 int *etype;
8401 etype = (int *)(data->data);
8402 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8403 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8404 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8405 if (aspect_ratio_payload) {
8406 ((struct vdec_output_frameinfo *)
8407 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8408 ((struct vdec_output_frameinfo *)
8409 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8410 }
8411 }
8412 break;
8413 case EXTRADATA_RECOVERY_POINT_SEI:
8414 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8415 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8416 recovery_sei_flags = recovery_sei_payload->flags;
8417 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8418 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008419 DEBUG_PRINT_HIGH("");
8420 DEBUG_PRINT_HIGH("***************************************************");
8421 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8422 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008423 }
8424 break;
8425 case EXTRADATA_PANSCAN_WINDOW:
8426 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8427 break;
8428 case EXTRADATA_MPEG2_SEQDISP:
8429 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8430 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8431 if (seqdisp_payload) {
8432 m_disp_hor_size = seqdisp_payload->disp_width;
8433 m_disp_vert_size = seqdisp_payload->disp_height;
8434 }
8435 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308436 case EXTRADATA_S3D_FRAME_PACKING:
8437 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8438 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308439 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308440 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8441 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8442 }
8443 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008444 case EXTRADATA_FRAME_QP:
8445 struct msm_vidc_frame_qp_payload *qp_payload;
8446 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308447 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008448 append_qp_extradata(p_extra, qp_payload);
8449 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8450 }
8451 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008452 case EXTRADATA_FRAME_BITS_INFO:
8453 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8454 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308455 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008456 append_bitsinfo_extradata(p_extra, bits_info_payload);
8457 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8458 }
8459 break;
Arun Menon906de572013-06-18 17:01:40 -07008460 default:
8461 goto unrecognized_extradata;
8462 }
8463 consumed_len += data->nSize;
8464 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8465 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308466 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008467 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8468 append_frame_info_extradata(p_extra,
8469 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308470 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008471 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008472 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008473 }
8474 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008475unrecognized_extradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308476 if (client_extradata)
Arun Menon906de572013-06-18 17:01:40 -07008477 append_terminator_extradata(p_extra);
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308478 if (secure_mode) {
8479 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8480 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8481 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8482 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8483 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8484 }
Arun Menon906de572013-06-18 17:01:40 -07008485 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008486}
8487
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008488OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008489 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008490{
Arun Menon906de572013-06-18 17:01:40 -07008491 OMX_ERRORTYPE ret = OMX_ErrorNone;
8492 struct v4l2_control control;
8493 if (m_state != OMX_StateLoaded) {
8494 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8495 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008496 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008497 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008498 client_extradata, requested_extradata, enable, is_internal);
8499
8500 if (!is_internal) {
8501 if (enable)
8502 client_extradata |= requested_extradata;
8503 else
8504 client_extradata = client_extradata & ~requested_extradata;
8505 }
8506
8507 if (enable) {
8508 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8509 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8510 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8511 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8512 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008513 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008514 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308515 }
8516 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008517 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8518 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
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 framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008521 }
8522 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8523 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8524 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008525 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008526 }
8527 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8528 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8529 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008530 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008531 }
8532 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8533 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8534 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008535 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008536 }
8537 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8538 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8539 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008540 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008541 }
8542 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8543 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8544 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8545 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008546 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008547 }
8548 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308549 }
8550 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008551 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8552 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8553 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008554 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008555 }
8556 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308557 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8558 if (output_capability == V4L2_PIX_FMT_H264) {
8559 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8560 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8561 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8562 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8563 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8564 }
8565 } else {
8566 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8567 }
8568 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008569 if (requested_extradata & OMX_QP_EXTRADATA) {
8570 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8571 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8572 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8573 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8574 }
8575 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008576 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8577 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8578 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8579 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8580 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8581 }
8582 }
Arun Menon906de572013-06-18 17:01:40 -07008583 }
8584 ret = get_buffer_req(&drv_ctx.op_buf);
8585 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586}
8587
8588OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8589{
Arun Menon906de572013-06-18 17:01:40 -07008590 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8591 OMX_U8 *data_ptr = extra->data, data = 0;
8592 while (byte_count < extra->nDataSize) {
8593 data = *data_ptr;
8594 while (data) {
8595 num_MB += (data&0x01);
8596 data >>= 1;
8597 }
8598 data_ptr++;
8599 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008600 }
Arun Menon906de572013-06-18 17:01:40 -07008601 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8602 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8603 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008604}
8605
8606void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8607{
Arun Menon906de572013-06-18 17:01:40 -07008608 if (!m_debug_extradata)
8609 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008610
8611 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308612 "============== Extra Data ==============\n"
8613 " Size: %lu\n"
8614 " Version: %lu\n"
8615 " PortIndex: %lu\n"
8616 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008617 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008618 extra->nSize, extra->nVersion.nVersion,
8619 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008620
Arun Menon906de572013-06-18 17:01:40 -07008621 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8622 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8623 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308624 "------ Interlace Format ------\n"
8625 " Size: %lu\n"
8626 " Version: %lu\n"
8627 " PortIndex: %lu\n"
8628 " Is Interlace Format: %d\n"
8629 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008630 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008631 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8632 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8633 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8634 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8635
8636 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308637 "-------- Frame Format --------\n"
8638 " Picture Type: %d\n"
8639 " Interlace Type: %d\n"
8640 " Pan Scan Total Frame Num: %lu\n"
8641 " Concealed Macro Blocks: %lu\n"
8642 " frame rate: %lu\n"
8643 " Time Stamp: %llu\n"
8644 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008645 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008646 fminfo->ePicType,
8647 fminfo->interlaceType,
8648 fminfo->panScan.numWindows,
8649 fminfo->nConcealedMacroblocks,
8650 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308651 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008652 fminfo->aspectRatio.aspectRatioX,
8653 fminfo->aspectRatio.aspectRatioY);
8654
8655 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8656 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008657 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308658 " Pan Scan Frame Num: %lu\n"
8659 " Rectangle x: %ld\n"
8660 " Rectangle y: %ld\n"
8661 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008662 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008663 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8664 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8665 }
8666
8667 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308668 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8669 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8670 DEBUG_PRINT_HIGH(
8671 "------------------ Framepack Format ----------\n"
8672 " id: %lu \n"
8673 " cancel_flag: %lu \n"
8674 " type: %lu \n"
8675 " quincunx_sampling_flagFormat: %lu \n"
8676 " content_interpretation_type: %lu \n"
8677 " content_interpretation_type: %lu \n"
8678 " spatial_flipping_flag: %lu \n"
8679 " frame0_flipped_flag: %lu \n"
8680 " field_views_flag: %lu \n"
8681 " current_frame_is_frame0_flag: %lu \n"
8682 " frame0_self_contained_flag: %lu \n"
8683 " frame1_self_contained_flag: %lu \n"
8684 " frame0_grid_position_x: %lu \n"
8685 " frame0_grid_position_y: %lu \n"
8686 " frame1_grid_position_x: %lu \n"
8687 " frame1_grid_position_y: %lu \n"
8688 " reserved_byte: %lu \n"
8689 " repetition_period: %lu \n"
8690 " extension_flag: %lu \n"
8691 "================== End of Framepack ===========",
8692 framepack->id,
8693 framepack->cancel_flag,
8694 framepack->type,
8695 framepack->quincunx_sampling_flag,
8696 framepack->content_interpretation_type,
8697 framepack->spatial_flipping_flag,
8698 framepack->frame0_flipped_flag,
8699 framepack->field_views_flag,
8700 framepack->current_frame_is_frame0_flag,
8701 framepack->frame0_self_contained_flag,
8702 framepack->frame1_self_contained_flag,
8703 framepack->frame0_grid_position_x,
8704 framepack->frame0_grid_position_y,
8705 framepack->frame1_grid_position_x,
8706 framepack->frame1_grid_position_y,
8707 framepack->reserved_byte,
8708 framepack->repetition_period,
8709 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008710 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8711 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8712 DEBUG_PRINT_HIGH(
8713 "---- QP (Frame quantization parameter) ----\n"
8714 " Frame QP: %lu \n"
8715 "================ End of QP ================\n",
8716 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008717 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8718 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8719 DEBUG_PRINT_HIGH(
8720 "--------- Input bits information --------\n"
8721 " Header bits: %lu \n"
8722 " Frame bits: %lu \n"
8723 "===== End of Input bits information =====\n",
8724 bits->header_bits, bits->frame_bits);
Arun Menon906de572013-06-18 17:01:40 -07008725 } else if (extra->eType == OMX_ExtraDataNone) {
8726 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8727 } else {
8728 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008730}
8731
8732void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08008733 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008734{
Arun Menon906de572013-06-18 17:01:40 -07008735 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08008736
Arun Menon906de572013-06-18 17:01:40 -07008737 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8738 return;
8739 }
8740 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8741 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8742 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8743 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8744 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8745 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8746 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8747 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8748 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08008749
8750 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07008751 interlace_format->bInterlaceFormat = OMX_FALSE;
8752 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8753 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008754 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008755 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008756 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008757 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008758 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008759 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008760 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008761 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008762 } else {
8763 interlace_format->bInterlaceFormat = OMX_TRUE;
8764 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8765 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8766 }
8767 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008768}
8769
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008770void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008771 struct vdec_aspectratioinfo *aspect_ratio_info,
8772 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008773{
Arun Menon906de572013-06-18 17:01:40 -07008774 m_extradata = frame_info;
8775 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8776 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308777 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008778 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008779}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008780
8781void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008782 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308783 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008784 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008785{
Arun Menon906de572013-06-18 17:01:40 -07008786 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8787 struct msm_vidc_panscan_window *panscan_window;
8788 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008789 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008790 }
Arun Menon906de572013-06-18 17:01:40 -07008791 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8792 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8793 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8794 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8795 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8796 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8797 switch (picture_type) {
8798 case PICTURE_TYPE_I:
8799 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8800 break;
8801 case PICTURE_TYPE_P:
8802 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8803 break;
8804 case PICTURE_TYPE_B:
8805 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8806 break;
8807 default:
8808 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8809 }
8810 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8811 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8812 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8813 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8814 else
8815 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8816 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8817 frame_info->nConcealedMacroblocks = num_conceal_mb;
8818 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308819 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008820 frame_info->panScan.numWindows = 0;
8821 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8822 if (m_disp_hor_size && m_disp_vert_size) {
8823 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8824 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05308825 } else {
8826 frame_info->displayAspectRatio.displayHorizontalSize = 0;
8827 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07008828 }
8829 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008830
Arun Menon906de572013-06-18 17:01:40 -07008831 if (panscan_payload) {
8832 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8833 panscan_window = &panscan_payload->wnd[0];
8834 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8835 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8836 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8837 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8838 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8839 panscan_window++;
8840 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008841 }
Arun Menon906de572013-06-18 17:01:40 -07008842 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8843 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008844}
8845
8846void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8847{
Arun Menon906de572013-06-18 17:01:40 -07008848 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8849 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8850 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8851 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8852 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8853 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8854 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8855 *portDefn = m_port_def;
8856 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008857 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008858 portDefn->format.video.nFrameWidth,
8859 portDefn->format.video.nStride,
8860 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008861}
8862
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308863void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8864 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8865{
8866 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8867 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8868 DEBUG_PRINT_ERROR("frame packing size mismatch");
8869 return;
8870 }
8871 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8872 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8873 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8874 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8875 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8876 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8877 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8878 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8879 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8880 memcpy(&framepack->id, s3d_frame_packing_payload,
8881 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8882 memcpy(&m_frame_pack_arrangement, framepack,
8883 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8884 print_debug_extradata(extra);
8885}
8886
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008887void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8888 struct msm_vidc_frame_qp_payload *qp_payload)
8889{
8890 OMX_QCOM_EXTRADATA_QP * qp = NULL;
8891 if (!qp_payload) {
8892 DEBUG_PRINT_ERROR("QP payload is NULL");
8893 return;
8894 }
8895 extra->nSize = OMX_QP_EXTRADATA_SIZE;
8896 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8897 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8898 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
8899 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
8900 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8901 qp->nQP = qp_payload->frame_qp;
8902 print_debug_extradata(extra);
8903}
8904
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008905void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8906 struct msm_vidc_frame_bits_info_payload *bits_payload)
8907{
8908 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
8909 if (!bits_payload) {
8910 DEBUG_PRINT_ERROR("bits info payload is NULL");
8911 return;
8912 }
8913 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
8914 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8915 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8916 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
8917 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
8918 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
8919 bits->frame_bits = bits_payload->frame_bits;
8920 bits->header_bits = bits_payload->header_bits;
8921 print_debug_extradata(extra);
8922}
8923
Shalaj Jain273b3e02012-06-22 19:08:03 -07008924void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8925{
Arun Menon906de572013-06-18 17:01:40 -07008926 if (!client_extradata) {
8927 return;
8928 }
8929 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8930 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8931 extra->eType = OMX_ExtraDataNone;
8932 extra->nDataSize = 0;
8933 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008934
Arun Menon906de572013-06-18 17:01:40 -07008935 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008936}
8937
8938OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8939{
Arun Menon906de572013-06-18 17:01:40 -07008940 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8941 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008942 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008943 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008944 }
Arun Menon906de572013-06-18 17:01:40 -07008945 if (m_desc_buffer_ptr == NULL) {
8946 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8947 calloc( (sizeof(desc_buffer_hdr)),
8948 drv_ctx.ip_buf.actualcount);
8949 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008950 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008951 return OMX_ErrorInsufficientResources;
8952 }
8953 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008954
Arun Menon906de572013-06-18 17:01:40 -07008955 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8956 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008957 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008958 return OMX_ErrorInsufficientResources;
8959 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008960
Arun Menon906de572013-06-18 17:01:40 -07008961 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008962}
8963
8964void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8965{
Arun Menon906de572013-06-18 17:01:40 -07008966 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8967 if (m_demux_entries < 8192) {
8968 m_demux_offsets[m_demux_entries++] = address_offset;
8969 }
8970 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008971}
8972
8973void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8974{
Arun Menon906de572013-06-18 17:01:40 -07008975 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8976 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8977 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008978
Arun Menon906de572013-06-18 17:01:40 -07008979 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008980
Arun Menon906de572013-06-18 17:01:40 -07008981 while (index < bytes_to_parse) {
8982 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8983 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8984 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8985 (buf[index+2] == 0x01)) ) {
8986 //Found start code, insert address offset
8987 insert_demux_addr_offset(index);
8988 if (buf[index+2] == 0x01) // 3 byte start code
8989 index += 3;
8990 else //4 byte start code
8991 index += 4;
8992 } else
8993 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008994 }
Arun Menon906de572013-06-18 17:01:40 -07008995 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8996 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008997}
8998
8999OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9000{
Arun Menon906de572013-06-18 17:01:40 -07009001 //fix this, handle 3 byte start code, vc1 terminator entry
9002 OMX_U8 *p_demux_data = NULL;
9003 OMX_U32 desc_data = 0;
9004 OMX_U32 start_addr = 0;
9005 OMX_U32 nal_size = 0;
9006 OMX_U32 suffix_byte = 0;
9007 OMX_U32 demux_index = 0;
9008 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009009
Arun Menon906de572013-06-18 17:01:40 -07009010 if (m_desc_buffer_ptr == NULL) {
9011 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9012 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009013 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009014
Arun Menon906de572013-06-18 17:01:40 -07009015 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9016 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9017 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9018 return OMX_ErrorBadParameter;
9019 }
9020
9021 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9022
9023 if ( ((OMX_U8*)p_demux_data == NULL) ||
9024 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9025 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9026 return OMX_ErrorBadParameter;
9027 } else {
9028 for (; demux_index < m_demux_entries; demux_index++) {
9029 desc_data = 0;
9030 start_addr = m_demux_offsets[demux_index];
9031 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9032 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9033 } else {
9034 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9035 }
9036 if (demux_index < (m_demux_entries - 1)) {
9037 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9038 } else {
9039 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9040 }
9041 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9042 (void *)start_addr,
9043 suffix_byte,
9044 nal_size,
9045 demux_index);
9046 desc_data = (start_addr >> 3) << 1;
9047 desc_data |= (start_addr & 7) << 21;
9048 desc_data |= suffix_byte << 24;
9049
9050 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9051 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9052 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9053 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9054
9055 p_demux_data += 16;
9056 }
9057 if (codec_type_parse == CODEC_TYPE_VC1) {
9058 DEBUG_PRINT_LOW("VC1 terminator entry");
9059 desc_data = 0;
9060 desc_data = 0x82 << 24;
9061 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9062 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9063 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9064 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9065 p_demux_data += 16;
9066 m_demux_entries++;
9067 }
9068 //Add zero word to indicate end of descriptors
9069 memset(p_demux_data, 0, sizeof(OMX_U32));
9070
9071 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9072 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9073 }
9074 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9075 m_demux_entries = 0;
9076 DEBUG_PRINT_LOW("Demux table complete!");
9077 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009078}
9079
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009080OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009081{
Arun Menon906de572013-06-18 17:01:40 -07009082 OMX_ERRORTYPE err = OMX_ErrorNone;
9083 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9084 if (iDivXDrmDecrypt) {
9085 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9086 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009087 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009088 delete iDivXDrmDecrypt;
9089 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009090 }
9091 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009092 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009093 err = OMX_ErrorUndefined;
9094 }
9095 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009096}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009097
Vinay Kaliada4f4422013-01-09 10:45:03 -08009098omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9099{
Arun Menon906de572013-06-18 17:01:40 -07009100 enabled = false;
9101 omx = NULL;
9102 init_members();
9103 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009104 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009105}
9106
9107void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9108{
Arun Menon906de572013-06-18 17:01:40 -07009109 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009110}
9111
Arun Menon906de572013-06-18 17:01:40 -07009112void omx_vdec::allocate_color_convert_buf::init_members()
9113{
9114 allocated_count = 0;
9115 buffer_size_req = 0;
9116 buffer_alignment_req = 0;
9117 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9118 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9119 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9120 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009121#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009122 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009123#endif
Arun Menon906de572013-06-18 17:01:40 -07009124 for (int i = 0; i < MAX_COUNT; i++)
9125 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009126}
9127
Arun Menon906de572013-06-18 17:01:40 -07009128omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9129{
9130 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009131}
9132
9133bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9134{
Arun Menon906de572013-06-18 17:01:40 -07009135 bool status = true;
9136 unsigned int src_size = 0, destination_size = 0;
9137 OMX_COLOR_FORMATTYPE drv_color_format;
9138 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009139 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009140 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009141 }
Arun Menon906de572013-06-18 17:01:40 -07009142 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009143 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009144 return status;
9145 }
9146 pthread_mutex_lock(&omx->c_lock);
9147 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9148 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009149 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009150 status = false;
9151 goto fail_update_buf_req;
9152 }
9153 c2d.close();
9154 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9155 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009156 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009157 if (status) {
9158 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9159 if (status)
9160 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9161 }
9162 if (status) {
9163 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9164 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009165 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009166 "driver size %d destination size %d",
9167 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9168 status = false;
9169 c2d.close();
9170 buffer_size_req = 0;
9171 } else {
9172 buffer_size_req = destination_size;
9173 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9174 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9175 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9176 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9177 }
9178 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009179fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009180 pthread_mutex_unlock(&omx->c_lock);
9181 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009182}
9183
9184bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009185 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009186{
Arun Menon906de572013-06-18 17:01:40 -07009187 bool status = true;
9188 OMX_COLOR_FORMATTYPE drv_color_format;
9189 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009190 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009191 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009192 }
Arun Menon906de572013-06-18 17:01:40 -07009193 pthread_mutex_lock(&omx->c_lock);
9194 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9195 drv_color_format = (OMX_COLOR_FORMATTYPE)
9196 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9197 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009198 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009199 status = false;
9200 }
9201 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009202 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009203 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9204 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009205 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009206 status = false;
9207 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009208 ColorFormat = dest_color_format;
9209 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9210 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009211 if (enabled)
9212 c2d.destroy();
9213 enabled = false;
9214 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009215 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009216 status = false;
9217 } else
9218 enabled = true;
9219 }
9220 } else {
9221 if (enabled)
9222 c2d.destroy();
9223 enabled = false;
9224 }
9225 pthread_mutex_unlock(&omx->c_lock);
9226 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009227}
9228
9229OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9230{
Arun Menon906de572013-06-18 17:01:40 -07009231 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009232 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009233 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009234 }
Arun Menon906de572013-06-18 17:01:40 -07009235 if (!enabled)
9236 return omx->m_out_mem_ptr;
9237 return m_out_mem_ptr_client;
9238}
9239
9240 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9241(OMX_BUFFERHEADERTYPE *bufadd)
9242{
9243 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009244 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009245 return NULL;
9246 }
9247 if (!enabled)
9248 return bufadd;
9249
9250 unsigned index = 0;
9251 index = bufadd - omx->m_out_mem_ptr;
9252 if (index < omx->drv_ctx.op_buf.actualcount) {
9253 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9254 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9255 bool status;
9256 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9257 pthread_mutex_lock(&omx->c_lock);
9258 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9259 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9260 pmem_baseaddress[index], pmem_baseaddress[index]);
9261 pthread_mutex_unlock(&omx->c_lock);
9262 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9263 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009264 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009265 m_out_mem_ptr_client[index].nFilledLen = 0;
9266 return &m_out_mem_ptr_client[index];
9267 }
9268 } else
9269 m_out_mem_ptr_client[index].nFilledLen = 0;
9270 return &m_out_mem_ptr_client[index];
9271 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009272 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009273 return NULL;
9274}
9275
9276 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9277(OMX_BUFFERHEADERTYPE *bufadd)
9278{
9279 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009280 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009281 return NULL;
9282 }
9283 if (!enabled)
9284 return bufadd;
9285 unsigned index = 0;
9286 index = bufadd - m_out_mem_ptr_client;
9287 if (index < omx->drv_ctx.op_buf.actualcount) {
9288 return &omx->m_out_mem_ptr[index];
9289 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009290 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009291 return NULL;
9292}
9293 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9294(unsigned int &buffer_size)
9295{
9296 bool status = true;
9297 pthread_mutex_lock(&omx->c_lock);
9298 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009299 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009300 else {
9301 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009302 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009303 status = false;
9304 goto fail_get_buffer_size;
9305 }
9306 }
9307 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9308 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9309 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9310 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009311fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009312 pthread_mutex_unlock(&omx->c_lock);
9313 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009314}
9315OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009316 OMX_BUFFERHEADERTYPE *bufhdr)
9317{
9318 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009319
Arun Menon906de572013-06-18 17:01:40 -07009320 if (!enabled)
9321 return omx->free_output_buffer(bufhdr);
9322 if (enabled && omx->is_component_secure())
9323 return OMX_ErrorNone;
9324 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009325 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009326 return OMX_ErrorBadParameter;
9327 }
9328 index = bufhdr - m_out_mem_ptr_client;
9329 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009330 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009331 return OMX_ErrorBadParameter;
9332 }
9333 if (pmem_fd[index] > 0) {
9334 munmap(pmem_baseaddress[index], buffer_size_req);
9335 close(pmem_fd[index]);
9336 }
9337 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009338#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009339 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009340#endif
Arun Menon906de572013-06-18 17:01:40 -07009341 m_heap_ptr[index].video_heap_ptr = NULL;
9342 if (allocated_count > 0)
9343 allocated_count--;
9344 else
9345 allocated_count = 0;
9346 if (!allocated_count) {
9347 pthread_mutex_lock(&omx->c_lock);
9348 c2d.close();
9349 init_members();
9350 pthread_mutex_unlock(&omx->c_lock);
9351 }
9352 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009353}
9354
9355OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009356 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009357{
Arun Menon906de572013-06-18 17:01:40 -07009358 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9359 if (!enabled) {
9360 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9361 return eRet;
9362 }
9363 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009364 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009365 omx->is_component_secure());
9366 return OMX_ErrorUnsupportedSetting;
9367 }
9368 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009369 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9370 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009371 buffer_size_req,bytes);
9372 return OMX_ErrorBadParameter;
9373 }
9374 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009375 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009376 return OMX_ErrorInsufficientResources;
9377 }
9378 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9379 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9380 port,appData,omx->drv_ctx.op_buf.buffer_size);
9381 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009382 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009383 return eRet;
9384 }
9385 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309386 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009387 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009388 (temp_bufferHdr - omx->m_out_mem_ptr));
9389 return OMX_ErrorUndefined;
9390 }
9391 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009392#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009393 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9394 buffer_size_req,buffer_alignment_req,
9395 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9396 0);
9397 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9398 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009399 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009400 return OMX_ErrorInsufficientResources;
9401 }
9402 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9403 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009404
Arun Menon906de572013-06-18 17:01:40 -07009405 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009406 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009407 close(pmem_fd[i]);
9408 omx->free_ion_memory(&op_buf_ion_info[i]);
9409 return OMX_ErrorInsufficientResources;
9410 }
9411 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9412 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9413 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009414#endif
Arun Menon906de572013-06-18 17:01:40 -07009415 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9416 m_pmem_info_client[i].offset = 0;
9417 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9418 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9419 m_platform_list_client[i].nEntries = 1;
9420 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9421 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9422 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9423 m_out_mem_ptr_client[i].nFilledLen = 0;
9424 m_out_mem_ptr_client[i].nFlags = 0;
9425 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9426 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9427 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9428 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9429 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9430 m_out_mem_ptr_client[i].pAppPrivate = appData;
9431 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009432 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009433 allocated_count++;
9434 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009435}
9436
9437bool omx_vdec::is_component_secure()
9438{
Arun Menon906de572013-06-18 17:01:40 -07009439 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009440}
9441
9442bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9443{
Arun Menon906de572013-06-18 17:01:40 -07009444 bool status = true;
9445 if (!enabled) {
9446 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9447 dest_color_format = (OMX_COLOR_FORMATTYPE)
9448 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9449 else
9450 status = false;
9451 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009452 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9453 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9454 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009455 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009456 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009457 }
9458 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009459}
Arun Menonbdb80b02013-08-12 17:45:54 -07009460
Arun Menonbdb80b02013-08-12 17:45:54 -07009461void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9462{
9463 int i = 0;
9464 bool buf_present = false;
9465 pthread_mutex_lock(&m_lock);
9466 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9467 //check the buffer fd, offset, uv addr with list contents
9468 //If present increment reference.
9469 if ((out_dynamic_list[i].fd == fd) &&
9470 (out_dynamic_list[i].offset == offset)) {
9471 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009472 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009473 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9474 buf_present = true;
9475 break;
9476 }
9477 }
9478 if (!buf_present) {
9479 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9480 //search for a entry to insert details of the new buffer
9481 if (out_dynamic_list[i].dup_fd == 0) {
9482 out_dynamic_list[i].fd = fd;
9483 out_dynamic_list[i].offset = offset;
9484 out_dynamic_list[i].dup_fd = dup(fd);
9485 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009486 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009487 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9488 break;
9489 }
9490 }
9491 }
9492 pthread_mutex_unlock(&m_lock);
9493}
9494
9495void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9496{
9497 int i = 0;
9498 pthread_mutex_lock(&m_lock);
9499 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9500 //check the buffer fd, offset, uv addr with list contents
9501 //If present decrement reference.
9502 if ((out_dynamic_list[i].fd == fd) &&
9503 (out_dynamic_list[i].offset == offset)) {
9504 out_dynamic_list[i].ref_count--;
9505 if (out_dynamic_list[i].ref_count == 0) {
9506 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009507 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009508 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9509 out_dynamic_list[i].dup_fd = 0;
9510 out_dynamic_list[i].fd = 0;
9511 out_dynamic_list[i].offset = 0;
9512 }
9513 break;
9514 }
9515 }
9516 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009517 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009518 }
9519 pthread_mutex_unlock(&m_lock);
9520}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009521
9522#ifdef _MSM8974_
9523void omx_vdec::send_codec_config() {
9524 if (codec_config_flag) {
9525 unsigned p1 = 0; // Parameter - 1
9526 unsigned p2 = 0; // Parameter - 2
9527 unsigned ident = 0;
9528 pthread_mutex_lock(&m_lock);
9529 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9530 while (m_etb_q.m_size) {
9531 m_etb_q.pop_entry(&p1,&p2,&ident);
9532 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9533 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9534 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9535 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9536 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9537 omx_report_error();
9538 }
9539 } else {
9540 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9541 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9542 }
9543 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9544 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9545 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9546 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9547 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9548 omx_report_error ();
9549 }
9550 } else {
9551 pending_input_buffers++;
9552 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9553 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9554 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9555 }
9556 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9557 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9558 (OMX_BUFFERHEADERTYPE *)p1);
9559 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9560 }
9561 }
9562 pthread_mutex_unlock(&m_lock);
9563 }
9564}
9565#endif