blob: 773ab268c63b87e5001b78734b5bade59ed3b161 [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
90#define MAX_INPUT_ERROR DEFAULT_FPS
91#define MAX_SUPPORTED_FPS 120
Deepak Vermaa2efdb12013-12-26 12:30:05 +053092#define DEFAULT_WIDTH_ALIGNMENT 128
93#define DEFAULT_HEIGHT_ALIGNMENT 32
Shalaj Jain273b3e02012-06-22 19:08:03 -070094
95#define VC1_SP_MP_START_CODE 0xC5000000
96#define VC1_SP_MP_START_CODE_MASK 0xFF000000
97#define VC1_AP_SEQ_START_CODE 0x0F010000
98#define VC1_STRUCT_C_PROFILE_MASK 0xF0
99#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
100#define VC1_SIMPLE_PROFILE 0
101#define VC1_MAIN_PROFILE 1
102#define VC1_ADVANCE_PROFILE 3
103#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
104#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
105#define VC1_STRUCT_C_LEN 4
106#define VC1_STRUCT_C_POS 8
107#define VC1_STRUCT_A_POS 12
108#define VC1_STRUCT_B_POS 24
109#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700110#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700111
112#define MEM_DEVICE "/dev/ion"
113#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
114
115#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700116extern "C" {
117#include<utils/Log.h>
118}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119#endif//_ANDROID_
120
Vinay Kalia53fa6832012-10-11 17:55:30 -0700121#define SZ_4K 0x1000
122#define SZ_1M 0x100000
123
Shalaj Jain273b3e02012-06-22 19:08:03 -0700124#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
125#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700126#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
127
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800128#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800129#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700130
131int debug_level = PRIO_ERROR;
132
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530133static OMX_U32 maxSmoothStreamingWidth = 1920;
134static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800135
Shalaj Jain273b3e02012-06-22 19:08:03 -0700136void* async_message_thread (void *input)
137{
Arun Menon906de572013-06-18 17:01:40 -0700138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
141 struct v4l2_buffer v4l2_buf;
142 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
143 struct v4l2_event dqevent;
144 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
145 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
146 pfd.fd = omx->drv_ctx.video_driver_fd;
147 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700148 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700149 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
150 while (1) {
151 rc = poll(&pfd, 1, POLL_TIMEOUT);
152 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700153 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700154 break;
155 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700156 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700157 break;
158 }
159 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
160 struct vdec_msginfo vdec_msg;
161 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
162 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
163 v4l2_buf.length = omx->drv_ctx.num_planes;
164 v4l2_buf.m.planes = plane;
165 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
166 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
167 vdec_msg.status_code=VDEC_S_SUCCESS;
168 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
169 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
170 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
171 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
172 (uint64_t)v4l2_buf.timestamp.tv_usec;
173 if (vdec_msg.msgdata.output_frame.len) {
174 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
175 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
176 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
177 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
178 }
179 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700180 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700181 break;
182 }
183 }
184 }
185 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
186 struct vdec_msginfo vdec_msg;
187 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
188 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
189 v4l2_buf.length = 1;
190 v4l2_buf.m.planes = plane;
191 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
192 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
193 vdec_msg.status_code=VDEC_S_SUCCESS;
194 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
195 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700196 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700197 break;
198 }
199 }
200 }
201 if (pfd.revents & POLLPRI) {
202 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
203 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
204 struct vdec_msginfo vdec_msg;
205 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
206 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700207 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700208 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700209 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700210 break;
211 }
212 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
213 struct vdec_msginfo vdec_msg;
214 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
215 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700216 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700217 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700218 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700219 break;
220 }
221 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
222 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700223 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700224 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700225 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700226 break;
227 }
228 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700229 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700230 break;
231 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
232 struct vdec_msginfo vdec_msg;
233 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
234 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700235 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700236 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700237 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700238 break;
239 }
Arun Menon45346052013-11-13 12:40:08 -0800240 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700241 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700242 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700243 omx->buf_ref_remove(ptr[0], ptr[1]);
244 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
245 unsigned int *ptr = (unsigned int *)dqevent.u.data;
246 struct vdec_msginfo vdec_msg;
247
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700248 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700249
250 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
251 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
252 v4l2_buf.length = omx->drv_ctx.num_planes;
253 v4l2_buf.m.planes = plane;
254 v4l2_buf.index = ptr[5];
255 v4l2_buf.flags = 0;
256
257 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
258 vdec_msg.status_code = VDEC_S_SUCCESS;
259 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
260 vdec_msg.msgdata.output_frame.len = 0;
261 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
262 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
263 (uint64_t)ptr[4];
264 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700265 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700266 break;
267 }
268 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700269 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700270 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700271 continue;
272 }
273 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700274 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700275 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700276 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700277}
278
279void* message_thread(void *input)
280{
Arun Menon906de572013-06-18 17:01:40 -0700281 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
282 unsigned char id;
283 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700284
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700285 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700286 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
287 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700288
Arun Menon906de572013-06-18 17:01:40 -0700289 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700290
Arun Menon906de572013-06-18 17:01:40 -0700291 if (0 == n) {
292 break;
293 }
294
295 if (1 == n) {
296 omx->process_event_cb(omx, id);
297 }
298 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700299 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700300 break;
301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700303 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700304 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700305}
306
307void post_message(omx_vdec *omx, unsigned char id)
308{
Arun Menon906de572013-06-18 17:01:40 -0700309 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700310 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700311 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700312 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700313}
314
315// omx_cmd_queue destructor
316omx_vdec::omx_cmd_queue::~omx_cmd_queue()
317{
Arun Menon906de572013-06-18 17:01:40 -0700318 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700319}
320
321// omx cmd queue constructor
322omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
323{
324 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
325}
326
327// omx cmd queue insert
328bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
329{
Arun Menon906de572013-06-18 17:01:40 -0700330 bool ret = true;
331 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
332 m_q[m_write].id = id;
333 m_q[m_write].param1 = p1;
334 m_q[m_write].param2 = p2;
335 m_write++;
336 m_size ++;
337 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
338 m_write = 0;
339 }
340 } else {
341 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700342 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700343 }
Arun Menon906de572013-06-18 17:01:40 -0700344 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700345}
346
347// omx cmd queue pop
348bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
349{
Arun Menon906de572013-06-18 17:01:40 -0700350 bool ret = true;
351 if (m_size > 0) {
352 *id = m_q[m_read].id;
353 *p1 = m_q[m_read].param1;
354 *p2 = m_q[m_read].param2;
355 // Move the read pointer ahead
356 ++m_read;
357 --m_size;
358 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
359 m_read = 0;
360 }
361 } else {
362 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700363 }
Arun Menon906de572013-06-18 17:01:40 -0700364 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700365}
366
367// Retrieve the first mesg type in the queue
368unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
369{
370 return m_q[m_read].id;
371}
372
373#ifdef _ANDROID_
374omx_vdec::ts_arr_list::ts_arr_list()
375{
Arun Menon906de572013-06-18 17:01:40 -0700376 //initialize timestamps array
377 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700378}
379omx_vdec::ts_arr_list::~ts_arr_list()
380{
Arun Menon906de572013-06-18 17:01:40 -0700381 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700382}
383
384bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
385{
Arun Menon906de572013-06-18 17:01:40 -0700386 bool ret = true;
387 bool duplicate_ts = false;
388 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700389
Arun Menon906de572013-06-18 17:01:40 -0700390 //insert at the first available empty location
391 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
392 if (!m_ts_arr_list[idx].valid) {
393 //found invalid or empty entry, save timestamp
394 m_ts_arr_list[idx].valid = true;
395 m_ts_arr_list[idx].timestamp = ts;
396 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
397 ts, idx);
398 break;
399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700401
Arun Menon906de572013-06-18 17:01:40 -0700402 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
403 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
404 ret = false;
405 }
406 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700407}
408
409bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
410{
Arun Menon906de572013-06-18 17:01:40 -0700411 bool ret = true;
412 int min_idx = -1;
413 OMX_TICKS min_ts = 0;
414 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415
Arun Menon906de572013-06-18 17:01:40 -0700416 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700417
Arun Menon906de572013-06-18 17:01:40 -0700418 if (m_ts_arr_list[idx].valid) {
419 //found valid entry, save index
420 if (min_idx < 0) {
421 //first valid entry
422 min_ts = m_ts_arr_list[idx].timestamp;
423 min_idx = idx;
424 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
425 min_ts = m_ts_arr_list[idx].timestamp;
426 min_idx = idx;
427 }
428 }
429
Shalaj Jain273b3e02012-06-22 19:08:03 -0700430 }
431
Arun Menon906de572013-06-18 17:01:40 -0700432 if (min_idx < 0) {
433 //no valid entries found
434 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
435 ts = 0;
436 ret = false;
437 } else {
438 ts = m_ts_arr_list[min_idx].timestamp;
439 m_ts_arr_list[min_idx].valid = false;
440 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
441 ts, min_idx);
442 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700443
Arun Menon906de572013-06-18 17:01:40 -0700444 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700445
446}
447
448
449bool omx_vdec::ts_arr_list::reset_ts_list()
450{
Arun Menon906de572013-06-18 17:01:40 -0700451 bool ret = true;
452 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700453
Arun Menon906de572013-06-18 17:01:40 -0700454 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
455 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
456 m_ts_arr_list[idx].valid = false;
457 }
458 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700459}
460#endif
461
462// factory function executed by the core to create instances
463void *get_omx_component_factory_fn(void)
464{
Arun Menon906de572013-06-18 17:01:40 -0700465 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700466}
467
468#ifdef _ANDROID_
469#ifdef USE_ION
470VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700471 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700472{
Arun Menon906de572013-06-18 17:01:40 -0700473 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700474}
475#else
476VideoHeap::VideoHeap(int fd, size_t size, void* base)
477{
478 // dup file descriptor, map once, use pmem
479 init(dup(fd), base, size, 0 , MEM_DEVICE);
480}
481#endif
482#endif // _ANDROID_
483/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700484 FUNCTION
485 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700486
Arun Menon906de572013-06-18 17:01:40 -0700487 DESCRIPTION
488 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700489
Arun Menon906de572013-06-18 17:01:40 -0700490 PARAMETERS
491 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700492
Arun Menon906de572013-06-18 17:01:40 -0700493 RETURN VALUE
494 None.
495 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800496omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700497 m_state(OMX_StateInvalid),
498 m_app_data(NULL),
499 m_inp_mem_ptr(NULL),
500 m_out_mem_ptr(NULL),
501 m_inp_err_count(0),
502 input_flush_progress (false),
503 output_flush_progress (false),
504 input_use_buffer (false),
505 output_use_buffer (false),
506 ouput_egl_buffers(false),
507 m_use_output_pmem(OMX_FALSE),
508 m_out_mem_region_smi(OMX_FALSE),
509 m_out_pvt_entry_pmem(OMX_FALSE),
510 pending_input_buffers(0),
511 pending_output_buffers(0),
512 m_out_bm_count(0),
513 m_inp_bm_count(0),
514 m_inp_bPopulated(OMX_FALSE),
515 m_out_bPopulated(OMX_FALSE),
516 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700517#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700518 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700519#endif
Arun Menon906de572013-06-18 17:01:40 -0700520 m_inp_bEnabled(OMX_TRUE),
521 m_out_bEnabled(OMX_TRUE),
522 m_in_alloc_cnt(0),
523 m_platform_list(NULL),
524 m_platform_entry(NULL),
525 m_pmem_info(NULL),
526 arbitrary_bytes (true),
527 psource_frame (NULL),
528 pdest_frame (NULL),
529 m_inp_heap_ptr (NULL),
530 m_phdr_pmem_ptr(NULL),
531 m_heap_inp_bm_count (0),
532 codec_type_parse ((codec_type)0),
533 first_frame_meta (true),
534 frame_count (0),
535 nal_count (0),
536 nal_length(0),
537 look_ahead_nal (false),
538 first_frame(0),
539 first_buffer(NULL),
540 first_frame_size (0),
541 m_device_file_ptr(NULL),
542 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700543 h264_last_au_ts(LLONG_MAX),
544 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530545 m_disp_hor_size(0),
546 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700547 prev_ts(LLONG_MAX),
548 rst_prev_ts(true),
549 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700550 in_reconfig(false),
551 m_display_id(NULL),
552 h264_parser(NULL),
553 client_extradata(0),
554 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530555 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700556#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700557 m_enable_android_native_buffers(OMX_FALSE),
558 m_use_android_native_buffers(OMX_FALSE),
559 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700560#endif
Arun Menon906de572013-06-18 17:01:40 -0700561 m_desc_buffer_ptr(NULL),
562 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530563 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800564 client_set_fps(false),
565 m_last_rendered_TS(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700566{
Arun Menon906de572013-06-18 17:01:40 -0700567 /* Assumption is that , to begin with , we have all the frames with decoder */
568 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700569 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700570#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700571 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700572 property_get("vidc.debug.level", property_value, "0");
573 debug_level = atoi(property_value);
574 property_value[0] = '\0';
575
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700576 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
577
Arun Menon906de572013-06-18 17:01:40 -0700578 property_get("vidc.dec.debug.perf", property_value, "0");
579 perf_flag = atoi(property_value);
580 if (perf_flag) {
581 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
582 dec_time.start();
583 proc_frms = latency = 0;
584 }
585 prev_n_filled_len = 0;
586 property_value[0] = '\0';
587 property_get("vidc.dec.debug.ts", property_value, "0");
588 m_debug_timestamp = atoi(property_value);
589 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
590 if (m_debug_timestamp) {
591 time_stamp_dts.set_timestamp_reorder_mode(true);
592 time_stamp_dts.enable_debug_print(true);
593 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700594
Arun Menon906de572013-06-18 17:01:40 -0700595 property_value[0] = '\0';
596 property_get("vidc.dec.debug.concealedmb", property_value, "0");
597 m_debug_concealedmb = atoi(property_value);
598 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700599
Arun Menon906de572013-06-18 17:01:40 -0700600 property_value[0] = '\0';
601 property_get("vidc.dec.profile.check", property_value, "0");
602 m_reject_avc_1080p_mp = atoi(property_value);
603 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530604
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700605 property_value[0] = '\0';
606 property_get("vidc.dec.log.in", property_value, "0");
607 m_debug.in_buffer_log = atoi(property_value);
608
609 property_value[0] = '\0';
610 property_get("vidc.dec.log.out", property_value, "0");
611 m_debug.out_buffer_log = atoi(property_value);
612 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
613
614 property_value[0] = '\0';
615 property_get("vidc.log.loc", property_value, "");
616 if (*property_value)
617 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800618
619 property_value[0] = '\0';
620 property_get("vidc.dec.120fps.enabled", property_value, "0");
621
622 //if this feature is not enabled then reset this value -ve
623 if(atoi(property_value)) {
624 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
625 m_last_rendered_TS = 0;
626 }
627
Shalaj Jain273b3e02012-06-22 19:08:03 -0700628#endif
Arun Menon906de572013-06-18 17:01:40 -0700629 memset(&m_cmp,0,sizeof(m_cmp));
630 memset(&m_cb,0,sizeof(m_cb));
631 memset (&drv_ctx,0,sizeof(drv_ctx));
632 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
633 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
634 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
635 m_demux_entries = 0;
636 msg_thread_id = 0;
637 async_thread_id = 0;
638 msg_thread_created = false;
639 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700640#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700641 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700642#endif
Arun Menon906de572013-06-18 17:01:40 -0700643 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530644 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700645 drv_ctx.timestamp_adjust = false;
646 drv_ctx.video_driver_fd = -1;
647 m_vendor_config.pData = NULL;
648 pthread_mutex_init(&m_lock, NULL);
649 pthread_mutex_init(&c_lock, NULL);
650 sem_init(&m_cmd_lock,0,0);
651 streaming[CAPTURE_PORT] =
652 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700653#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700654 char extradata_value[PROPERTY_VALUE_MAX] = {0};
655 property_get("vidc.dec.debug.extradata", extradata_value, "0");
656 m_debug_extradata = atoi(extradata_value);
657 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700658#endif
Arun Menon906de572013-06-18 17:01:40 -0700659 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
660 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700661 dynamic_buf_mode = false;
662 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800663 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800664 m_smoothstreaming_mode = false;
665 m_smoothstreaming_width = 0;
666 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530667 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700668}
669
Vinay Kalia85793762012-06-14 19:12:34 -0700670static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700671 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
672 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
673 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700674 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
675 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700676 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
677 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700678};
679
680static OMX_ERRORTYPE subscribe_to_events(int fd)
681{
Arun Menon906de572013-06-18 17:01:40 -0700682 OMX_ERRORTYPE eRet = OMX_ErrorNone;
683 struct v4l2_event_subscription sub;
684 int array_sz = sizeof(event_type)/sizeof(int);
685 int i,rc;
686 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700687 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700688 return OMX_ErrorBadParameter;
689 }
Vinay Kalia85793762012-06-14 19:12:34 -0700690
Arun Menon906de572013-06-18 17:01:40 -0700691 for (i = 0; i < array_sz; ++i) {
692 memset(&sub, 0, sizeof(sub));
693 sub.type = event_type[i];
694 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
695 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700696 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700697 break;
698 }
699 }
700 if (i < array_sz) {
701 for (--i; i >=0 ; i--) {
702 memset(&sub, 0, sizeof(sub));
703 sub.type = event_type[i];
704 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
705 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700706 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700707 }
708 eRet = OMX_ErrorNotImplemented;
709 }
710 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700711}
712
713
714static OMX_ERRORTYPE unsubscribe_to_events(int fd)
715{
Arun Menon906de572013-06-18 17:01:40 -0700716 OMX_ERRORTYPE eRet = OMX_ErrorNone;
717 struct v4l2_event_subscription sub;
718 int array_sz = sizeof(event_type)/sizeof(int);
719 int i,rc;
720 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700721 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700722 return OMX_ErrorBadParameter;
723 }
Vinay Kalia85793762012-06-14 19:12:34 -0700724
Arun Menon906de572013-06-18 17:01:40 -0700725 for (i = 0; i < array_sz; ++i) {
726 memset(&sub, 0, sizeof(sub));
727 sub.type = event_type[i];
728 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
729 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700730 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700731 break;
732 }
733 }
734 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700735}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700736
737/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700738 FUNCTION
739 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700740
Arun Menon906de572013-06-18 17:01:40 -0700741 DESCRIPTION
742 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700743
Arun Menon906de572013-06-18 17:01:40 -0700744 PARAMETERS
745 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700746
Arun Menon906de572013-06-18 17:01:40 -0700747 RETURN VALUE
748 None.
749 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700750omx_vdec::~omx_vdec()
751{
Arun Menon906de572013-06-18 17:01:40 -0700752 m_pmem_info = NULL;
753 struct v4l2_decoder_cmd dec;
754 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
755 if (m_pipe_in) close(m_pipe_in);
756 if (m_pipe_out) close(m_pipe_out);
757 m_pipe_in = -1;
758 m_pipe_out = -1;
759 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
760 if (msg_thread_created)
761 pthread_join(msg_thread_id,NULL);
762 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
763 dec.cmd = V4L2_DEC_CMD_STOP;
764 if (drv_ctx.video_driver_fd >=0 ) {
765 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700766 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700767 }
768 if (async_thread_created)
769 pthread_join(async_thread_id,NULL);
770 unsubscribe_to_events(drv_ctx.video_driver_fd);
771 close(drv_ctx.video_driver_fd);
772 pthread_mutex_destroy(&m_lock);
773 pthread_mutex_destroy(&c_lock);
774 sem_destroy(&m_cmd_lock);
775 if (perf_flag) {
776 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
777 dec_time.end();
778 }
779 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700780}
781
Arun Menon906de572013-06-18 17:01:40 -0700782int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
783{
784 struct v4l2_requestbuffers bufreq;
785 int rc = 0;
786 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
787 bufreq.memory = V4L2_MEMORY_USERPTR;
788 bufreq.count = 0;
789 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
790 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530791 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
792 bufreq.memory = V4L2_MEMORY_USERPTR;
793 bufreq.count = 0;
794 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
795 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700796 }
797 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700798}
799
Shalaj Jain273b3e02012-06-22 19:08:03 -0700800/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700801 FUNCTION
802 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803
Arun Menon906de572013-06-18 17:01:40 -0700804 DESCRIPTION
805 IL Client callbacks are generated through this routine. The decoder
806 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700807
Arun Menon906de572013-06-18 17:01:40 -0700808 PARAMETERS
809 ctxt -- Context information related to the self.
810 id -- Event identifier. This could be any of the following:
811 1. Command completion event
812 2. Buffer done callback event
813 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700814
Arun Menon906de572013-06-18 17:01:40 -0700815 RETURN VALUE
816 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700817
Arun Menon906de572013-06-18 17:01:40 -0700818 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700819void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
820{
Arun Menon906de572013-06-18 17:01:40 -0700821 signed p1; // Parameter - 1
822 signed p2; // Parameter - 2
823 unsigned ident;
824 unsigned qsize=0; // qsize
825 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700826
Arun Menon906de572013-06-18 17:01:40 -0700827 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700828 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700829 __func__);
830 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700831 }
832
Arun Menon906de572013-06-18 17:01:40 -0700833 // Protect the shared queue data structure
834 do {
835 /*Read the message id's from the queue*/
836 pthread_mutex_lock(&pThis->m_lock);
837 qsize = pThis->m_cmd_q.m_size;
838 if (qsize) {
839 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700840 }
Arun Menon906de572013-06-18 17:01:40 -0700841
842 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
843 qsize = pThis->m_ftb_q.m_size;
844 if (qsize) {
845 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
846 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700847 }
Arun Menon906de572013-06-18 17:01:40 -0700848
849 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
850 qsize = pThis->m_etb_q.m_size;
851 if (qsize) {
852 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
853 }
854 }
855 pthread_mutex_unlock(&pThis->m_lock);
856
857 /*process message if we have one*/
858 if (qsize > 0) {
859 id = ident;
860 switch (id) {
861 case OMX_COMPONENT_GENERATE_EVENT:
862 if (pThis->m_cb.EventHandler) {
863 switch (p1) {
864 case OMX_CommandStateSet:
865 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700866 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700867 pThis->m_state);
868 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
869 OMX_EventCmdComplete, p1, p2, NULL);
870 break;
871
872 case OMX_EventError:
873 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700874 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700875 pThis->m_state = (OMX_STATETYPE) p2;
876 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
877 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
878 } else if (p2 == OMX_ErrorHardware) {
879 pThis->omx_report_error();
880 } else {
881 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
882 OMX_EventError, p2, (OMX_U32)NULL, NULL );
883 }
884 break;
885
886 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700887 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700888 if (BITMASK_PRESENT(&pThis->m_flags,
889 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
890 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
891 break;
892 }
893 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
894 OMX_ERRORTYPE eRet = OMX_ErrorNone;
895 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
896 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700897 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700898 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
899 pThis->in_reconfig = false;
900 if (eRet != OMX_ErrorNone) {
901 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
902 pThis->omx_report_error();
903 break;
904 }
905 }
906 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
907 OMX_EventCmdComplete, p1, p2, NULL );
908 break;
909 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700910 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700911 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
912 OMX_EventCmdComplete, p1, p2, NULL );
913 break;
914
915 default:
916 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
917 OMX_EventCmdComplete, p1, p2, NULL );
918 break;
919
920 }
921 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700922 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700923 }
924 break;
925 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
926 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
927 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->omx_report_error ();
930 }
931 break;
932 case OMX_COMPONENT_GENERATE_ETB:
933 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
934 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700935 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700936 pThis->omx_report_error ();
937 }
938 break;
939
940 case OMX_COMPONENT_GENERATE_FTB:
941 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
942 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700943 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700944 pThis->omx_report_error ();
945 }
946 break;
947
948 case OMX_COMPONENT_GENERATE_COMMAND:
949 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
950 (OMX_U32)p2,(OMX_PTR)NULL);
951 break;
952
953 case OMX_COMPONENT_GENERATE_EBD:
954
955 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700956 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700957 pThis->omx_report_error ();
958 } else {
959 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
960 pThis->m_inp_err_count++;
961 pThis->time_stamp_dts.remove_time_stamp(
962 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
963 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
964 ?true:false);
965 } else {
966 pThis->m_inp_err_count = 0;
967 }
968 if ( pThis->empty_buffer_done(&pThis->m_cmp,
969 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700970 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700971 pThis->omx_report_error ();
972 }
973 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700974 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700975 pThis->omx_report_error ();
976 }
977 }
978 break;
979 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
980 int64_t *timestamp = (int64_t *)p1;
981 if (p1) {
982 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
983 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
984 ?true:false);
985 free(timestamp);
986 }
987 }
988 break;
989 case OMX_COMPONENT_GENERATE_FBD:
990 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700991 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700992 pThis->omx_report_error ();
993 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
994 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700995 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700996 pThis->omx_report_error ();
997 }
998 break;
999
1000 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001001 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001002 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001003 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001004 } else {
1005 pThis->execute_input_flush();
1006 if (pThis->m_cb.EventHandler) {
1007 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001008 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001009 pThis->omx_report_error ();
1010 } else {
1011 /*Check if we need generate event for Flush done*/
1012 if (BITMASK_PRESENT(&pThis->m_flags,
1013 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1014 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001015 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001016 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1017 OMX_EventCmdComplete,OMX_CommandFlush,
1018 OMX_CORE_INPUT_PORT_INDEX,NULL );
1019 }
1020 if (BITMASK_PRESENT(&pThis->m_flags,
1021 OMX_COMPONENT_IDLE_PENDING)) {
1022 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001023 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001024 pThis->omx_report_error ();
1025 } else {
1026 pThis->streaming[OUTPUT_PORT] = false;
1027 }
1028 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001029 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001030 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1031 OMX_COMPONENT_GENERATE_STOP_DONE);
1032 }
1033 }
1034 }
1035 } else {
1036 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1037 }
1038 }
1039 break;
1040
1041 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001042 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001043 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001044 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001045 } else {
1046 pThis->execute_output_flush();
1047 if (pThis->m_cb.EventHandler) {
1048 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001049 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001050 pThis->omx_report_error ();
1051 } else {
1052 /*Check if we need generate event for Flush done*/
1053 if (BITMASK_PRESENT(&pThis->m_flags,
1054 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001055 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001056 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1057 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1058 OMX_EventCmdComplete,OMX_CommandFlush,
1059 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1060 }
1061 if (BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001063 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001064 BITMASK_CLEAR (&pThis->m_flags,
1065 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1066 if (BITMASK_PRESENT(&pThis->m_flags,
1067 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1068 pThis->post_event(OMX_CommandPortDisable,
1069 OMX_CORE_OUTPUT_PORT_INDEX,
1070 OMX_COMPONENT_GENERATE_EVENT);
1071 BITMASK_CLEAR (&pThis->m_flags,
1072 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001073 BITMASK_CLEAR (&pThis->m_flags,
1074 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001075
1076 }
1077 }
1078
1079 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1080 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001081 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001082 pThis->omx_report_error ();
1083 break;
1084 }
1085 pThis->streaming[CAPTURE_PORT] = false;
1086 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001087 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001088 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1089 OMX_COMPONENT_GENERATE_STOP_DONE);
1090 }
1091 }
1092 }
1093 } else {
1094 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1095 }
1096 }
1097 break;
1098
1099 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001100 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001101
1102 if (pThis->m_cb.EventHandler) {
1103 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001104 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001105 pThis->omx_report_error ();
1106 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001107 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001108 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001109 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001110 // Send the callback now
1111 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1112 pThis->m_state = OMX_StateExecuting;
1113 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1114 OMX_EventCmdComplete,OMX_CommandStateSet,
1115 OMX_StateExecuting, NULL);
1116 } else if (BITMASK_PRESENT(&pThis->m_flags,
1117 OMX_COMPONENT_PAUSE_PENDING)) {
1118 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1119 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001120 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001121 pThis->omx_report_error ();
1122 }
1123 }
1124 }
1125 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001126 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001127 }
1128 break;
1129
1130 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001131 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001132 if (pThis->m_cb.EventHandler) {
1133 if (p2 != VDEC_S_SUCCESS) {
1134 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1135 pThis->omx_report_error ();
1136 } else {
1137 pThis->complete_pending_buffer_done_cbs();
1138 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001139 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001140 //Send the callback now
1141 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1142 pThis->m_state = OMX_StatePause;
1143 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1144 OMX_EventCmdComplete,OMX_CommandStateSet,
1145 OMX_StatePause, NULL);
1146 }
1147 }
1148 } else {
1149 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1150 }
1151
1152 break;
1153
1154 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001155 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001156 if (pThis->m_cb.EventHandler) {
1157 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001158 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001159 pThis->omx_report_error ();
1160 } else {
1161 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001162 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001163 // Send the callback now
1164 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1165 pThis->m_state = OMX_StateExecuting;
1166 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1167 OMX_EventCmdComplete,OMX_CommandStateSet,
1168 OMX_StateExecuting,NULL);
1169 }
1170 }
1171 } else {
1172 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1173 }
1174
1175 break;
1176
1177 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001178 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001179 if (pThis->m_cb.EventHandler) {
1180 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001181 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001182 pThis->omx_report_error ();
1183 } else {
1184 pThis->complete_pending_buffer_done_cbs();
1185 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001186 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001187 // Send the callback now
1188 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1189 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001190 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001191 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1192 OMX_EventCmdComplete,OMX_CommandStateSet,
1193 OMX_StateIdle,NULL);
1194 }
1195 }
1196 } else {
1197 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1198 }
1199
1200 break;
1201
1202 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001203 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001204
1205 if (p2 == OMX_IndexParamPortDefinition) {
1206 pThis->in_reconfig = true;
1207 }
1208 if (pThis->m_cb.EventHandler) {
1209 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1210 OMX_EventPortSettingsChanged, p1, p2, NULL );
1211 } else {
1212 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1213 }
1214
Arun Menon906de572013-06-18 17:01:40 -07001215 break;
1216
1217 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001218 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001219 if (pThis->m_cb.EventHandler) {
1220 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1221 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1222 } else {
1223 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1224 }
1225 pThis->prev_ts = LLONG_MAX;
1226 pThis->rst_prev_ts = true;
1227 break;
1228
1229 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001230 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001231 pThis->omx_report_error ();
1232 break;
1233
1234 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001235 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001236 pThis->omx_report_unsupported_setting();
1237 break;
1238
Arun Menon906de572013-06-18 17:01:40 -07001239 default:
1240 break;
1241 }
1242 }
1243 pthread_mutex_lock(&pThis->m_lock);
1244 qsize = pThis->m_cmd_q.m_size;
1245 if (pThis->m_state != OMX_StatePause)
1246 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1247 pthread_mutex_unlock(&pThis->m_lock);
1248 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001249
1250}
1251
Vinay Kaliab9e98102013-04-02 19:31:43 -07001252int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001253{
Arun Menon906de572013-06-18 17:01:40 -07001254 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301255 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1256 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001257 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001258 width, drv_ctx.video_resolution.frame_width,
1259 height,drv_ctx.video_resolution.frame_height);
1260 format_changed = 1;
1261 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001262 drv_ctx.video_resolution.frame_height = height;
1263 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001264 drv_ctx.video_resolution.scan_lines = scan_lines;
1265 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001266 rectangle.nLeft = 0;
1267 rectangle.nTop = 0;
1268 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1269 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001270 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001271}
1272
Arun Menon6836ba02013-02-19 20:37:40 -08001273OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1274{
Arun Menon906de572013-06-18 17:01:40 -07001275 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1276 OMX_MAX_STRINGNAME_SIZE) &&
1277 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1278 m_decoder_capability.max_width = 1280;
1279 m_decoder_capability.max_height = 720;
1280 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1281 }
Arun Menon888aa852013-05-30 11:24:42 -07001282
Arun Menon906de572013-06-18 17:01:40 -07001283 if ((drv_ctx.video_resolution.frame_width *
1284 drv_ctx.video_resolution.frame_height >
1285 m_decoder_capability.max_width *
1286 m_decoder_capability.max_height) ||
1287 (drv_ctx.video_resolution.frame_width*
1288 drv_ctx.video_resolution.frame_height <
1289 m_decoder_capability.min_width *
1290 m_decoder_capability.min_height)) {
1291 DEBUG_PRINT_ERROR(
1292 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1293 drv_ctx.video_resolution.frame_width,
1294 drv_ctx.video_resolution.frame_height,
1295 m_decoder_capability.min_width,
1296 m_decoder_capability.min_height,
1297 m_decoder_capability.max_width,
1298 m_decoder_capability.max_height);
1299 return OMX_ErrorUnsupportedSetting;
1300 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001301 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001302 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001303}
1304
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001305int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1306{
1307 if (m_debug.in_buffer_log && !m_debug.infile) {
1308 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1309 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1310 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1311 }
1312 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1313 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); }
1314 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1315 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
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.avc", OMX_MAX_STRINGNAME_SIZE)) {
1319 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
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.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1323 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1324 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1325 }
1326 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1327 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1328 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1329 }
1330 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1331 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1332 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1333 }
1334 m_debug.infile = fopen (m_debug.infile_name, "ab");
1335 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001336 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001337 m_debug.infile_name[0] = '\0';
1338 return -1;
1339 }
1340 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1341 struct ivf_file_header {
1342 OMX_U8 signature[4]; //='DKIF';
1343 OMX_U8 version ; //= 0;
1344 OMX_U8 headersize ; //= 32;
1345 OMX_U32 FourCC;
1346 OMX_U8 width;
1347 OMX_U8 height;
1348 OMX_U32 rate;
1349 OMX_U32 scale;
1350 OMX_U32 length;
1351 OMX_U8 unused[4];
1352 } file_header;
1353
1354 memset((void *)&file_header,0,sizeof(file_header));
1355 file_header.signature[0] = 'D';
1356 file_header.signature[1] = 'K';
1357 file_header.signature[2] = 'I';
1358 file_header.signature[3] = 'F';
1359 file_header.version = 0;
1360 file_header.headersize = 32;
1361 file_header.FourCC = 0x30385056;
1362 fwrite((const char *)&file_header,
1363 sizeof(file_header),1,m_debug.infile);
1364 }
1365 }
1366 if (m_debug.infile && buffer_addr && buffer_len) {
1367 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1368 struct vp8_ivf_frame_header {
1369 OMX_U32 framesize;
1370 OMX_U32 timestamp_lo;
1371 OMX_U32 timestamp_hi;
1372 } vp8_frame_header;
1373 vp8_frame_header.framesize = buffer_len;
1374 /* Currently FW doesn't use timestamp values */
1375 vp8_frame_header.timestamp_lo = 0;
1376 vp8_frame_header.timestamp_hi = 0;
1377 fwrite((const char *)&vp8_frame_header,
1378 sizeof(vp8_frame_header),1,m_debug.infile);
1379 }
1380 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1381 }
1382 return 0;
1383}
1384
1385int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1386 if (m_debug.out_buffer_log && !m_debug.outfile) {
1387 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1388 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1389 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1390 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001391 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001392 m_debug.outfile_name[0] = '\0';
1393 return -1;
1394 }
1395 }
1396 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1397 int buf_index = buffer - m_out_mem_ptr;
1398 int stride = drv_ctx.video_resolution.stride;
1399 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301400 if (m_smoothstreaming_mode) {
1401 stride = drv_ctx.video_resolution.frame_width;
1402 scanlines = drv_ctx.video_resolution.frame_height;
1403 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1404 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1405 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001406 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1407 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301408 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1409 drv_ctx.video_resolution.frame_width,
1410 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001411 int bytes_written = 0;
1412 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1413 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1414 temp += stride;
1415 }
1416 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1417 int stride_c = stride;
1418 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1419 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1420 temp += stride_c;
1421 }
1422 }
1423 return 0;
1424}
1425
Shalaj Jain273b3e02012-06-22 19:08:03 -07001426/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001427 FUNCTION
1428 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001429
Arun Menon906de572013-06-18 17:01:40 -07001430 DESCRIPTION
1431 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001432
Arun Menon906de572013-06-18 17:01:40 -07001433 PARAMETERS
1434 ctxt -- Context information related to the self.
1435 id -- Event identifier. This could be any of the following:
1436 1. Command completion event
1437 2. Buffer done callback event
1438 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001439
Arun Menon906de572013-06-18 17:01:40 -07001440 RETURN VALUE
1441 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001442
Arun Menon906de572013-06-18 17:01:40 -07001443 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001444OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1445{
1446
Arun Menon906de572013-06-18 17:01:40 -07001447 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1448 struct v4l2_fmtdesc fdesc;
1449 struct v4l2_format fmt;
1450 struct v4l2_requestbuffers bufreq;
1451 struct v4l2_control control;
1452 struct v4l2_frmsizeenum frmsize;
1453 unsigned int alignment = 0,buffer_size = 0;
1454 int fds[2];
1455 int r,ret=0;
1456 bool codec_ambiguous = false;
1457 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001458 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001459
1460#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001461 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001462 property_get("ro.board.platform", platform_name, "0");
1463 if (!strncmp(platform_name, "msm8610", 7)) {
1464 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301465 is_q6_platform = true;
1466 maxSmoothStreamingWidth = 1280;
1467 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001468 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001469#endif
1470
Arun Menon906de572013-06-18 17:01:40 -07001471 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1472 struct v4l2_control control;
1473 secure_mode = true;
1474 arbitrary_bytes = false;
1475 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301476 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1477 OMX_MAX_STRINGNAME_SIZE)){
1478 secure_mode = true;
1479 arbitrary_bytes = false;
1480 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001481 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001482
Arun Menon906de572013-06-18 17:01:40 -07001483 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001484
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001485 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001486 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001487
Arun Menon906de572013-06-18 17:01:40 -07001488 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001489 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001490 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1491 close(0);
1492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001493
Arun Menon906de572013-06-18 17:01:40 -07001494 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001495 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001496 return OMX_ErrorInsufficientResources;
1497 }
1498 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1499 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001500
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001501 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001502 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001503 async_thread_created = true;
1504 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1505 }
1506 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001507 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001508 async_thread_created = false;
1509 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001510 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001511
Shalaj Jain273b3e02012-06-22 19:08:03 -07001512#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001513 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001514#endif
1515
Arun Menon906de572013-06-18 17:01:40 -07001516 // Copy the role information which provides the decoder kind
1517 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001518
Arun Menon906de572013-06-18 17:01:40 -07001519 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1520 OMX_MAX_STRINGNAME_SIZE)) {
1521 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1522 OMX_MAX_STRINGNAME_SIZE);
1523 drv_ctx.timestamp_adjust = true;
1524 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1525 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1526 output_capability=V4L2_PIX_FMT_MPEG4;
1527 /*Initialize Start Code for MPEG4*/
1528 codec_type_parse = CODEC_TYPE_MPEG4;
1529 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001530 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1531 OMX_MAX_STRINGNAME_SIZE)) {
1532 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1533 OMX_MAX_STRINGNAME_SIZE);
1534 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1535 output_capability = V4L2_PIX_FMT_MPEG2;
1536 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1537 /*Initialize Start Code for MPEG2*/
1538 codec_type_parse = CODEC_TYPE_MPEG2;
1539 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001540 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1541 OMX_MAX_STRINGNAME_SIZE)) {
1542 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001543 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001544 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1545 eCompressionFormat = OMX_VIDEO_CodingH263;
1546 output_capability = V4L2_PIX_FMT_H263;
1547 codec_type_parse = CODEC_TYPE_H263;
1548 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001549 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1550 OMX_MAX_STRINGNAME_SIZE)) {
1551 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001552 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001553 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1554 output_capability = V4L2_PIX_FMT_DIVX_311;
1555 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1556 codec_type_parse = CODEC_TYPE_DIVX;
1557 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001558
Arun Menon906de572013-06-18 17:01:40 -07001559 eRet = createDivxDrmContext();
1560 if (eRet != OMX_ErrorNone) {
1561 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1562 return eRet;
1563 }
1564 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1565 OMX_MAX_STRINGNAME_SIZE)) {
1566 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001567 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001568 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1569 output_capability = V4L2_PIX_FMT_DIVX;
1570 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1571 codec_type_parse = CODEC_TYPE_DIVX;
1572 codec_ambiguous = true;
1573 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001574
Arun Menon906de572013-06-18 17:01:40 -07001575 eRet = createDivxDrmContext();
1576 if (eRet != OMX_ErrorNone) {
1577 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1578 return eRet;
1579 }
1580 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1581 OMX_MAX_STRINGNAME_SIZE)) {
1582 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001583 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001584 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1585 output_capability = V4L2_PIX_FMT_DIVX;
1586 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1587 codec_type_parse = CODEC_TYPE_DIVX;
1588 codec_ambiguous = true;
1589 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001590
Arun Menon906de572013-06-18 17:01:40 -07001591 eRet = createDivxDrmContext();
1592 if (eRet != OMX_ErrorNone) {
1593 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1594 return eRet;
1595 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001596
Arun Menon906de572013-06-18 17:01:40 -07001597 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1598 OMX_MAX_STRINGNAME_SIZE)) {
1599 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1600 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1601 output_capability=V4L2_PIX_FMT_H264;
1602 eCompressionFormat = OMX_VIDEO_CodingAVC;
1603 codec_type_parse = CODEC_TYPE_H264;
1604 m_frame_parser.init_start_codes (codec_type_parse);
1605 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001606 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
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;
1610 eCompressionFormat = OMX_VIDEO_CodingWMV;
1611 codec_type_parse = CODEC_TYPE_VC1;
1612 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
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.wmv",\
1615 OMX_MAX_STRINGNAME_SIZE)) {
1616 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1617 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1618 eCompressionFormat = OMX_VIDEO_CodingWMV;
1619 codec_type_parse = CODEC_TYPE_VC1;
1620 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1621 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001622 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1623 OMX_MAX_STRINGNAME_SIZE)) {
1624 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1625 output_capability=V4L2_PIX_FMT_VP8;
1626 eCompressionFormat = OMX_VIDEO_CodingVPX;
1627 codec_type_parse = CODEC_TYPE_VP8;
1628 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001629
Arun Menon906de572013-06-18 17:01:40 -07001630 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001631 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001632 eRet = OMX_ErrorInvalidComponentName;
1633 }
Arun Menon906de572013-06-18 17:01:40 -07001634 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001635
Arun Menon906de572013-06-18 17:01:40 -07001636 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001637 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1638 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1639 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001640 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001641 eRet = OMX_ErrorInsufficientResources;
1642 }
1643
Arun Menon906de572013-06-18 17:01:40 -07001644 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645
Arun Menon906de572013-06-18 17:01:40 -07001646 struct v4l2_capability cap;
1647 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1648 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001649 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001650 /*TODO: How to handle this case */
1651 } else {
1652 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001653 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001654 cap.bus_info, cap.version, cap.capabilities);
1655 }
1656 ret=0;
1657 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1658 fdesc.index=0;
1659 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
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 }
1664 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1665 fdesc.index=0;
1666 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001667
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001668 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001669 fdesc.pixelformat, fdesc.flags);
1670 fdesc.index++;
1671 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001672 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001673 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1674 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1675 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1676 fmt.fmt.pix_mp.pixelformat = output_capability;
1677 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1678 if (ret) {
1679 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001680 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001681 return OMX_ErrorInsufficientResources;
1682 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001683 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001684 if (codec_ambiguous) {
1685 if (output_capability == V4L2_PIX_FMT_DIVX) {
1686 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001687
Arun Menon906de572013-06-18 17:01:40 -07001688 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1689 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1690 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1691 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1692 } else {
1693 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1694 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001695
Arun Menon906de572013-06-18 17:01:40 -07001696 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1697 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1698 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001699 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001700 }
1701 } else {
1702 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1703 }
1704 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001705
Jia Meng3a3c6492013-12-19 17:16:52 +08001706 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1707 m_conceal_color= atoi(property_value);
1708 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1709 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1710 control.value = m_conceal_color;
1711 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1712 if (ret) {
1713 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1714 }
1715
Arun Menon906de572013-06-18 17:01:40 -07001716 //Get the hardware capabilities
1717 memset((void *)&frmsize,0,sizeof(frmsize));
1718 frmsize.index = 0;
1719 frmsize.pixel_format = output_capability;
1720 ret = ioctl(drv_ctx.video_driver_fd,
1721 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1722 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001723 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001724 return OMX_ErrorHardware;
1725 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001726
Arun Menon906de572013-06-18 17:01:40 -07001727 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1728 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1729 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1730 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1731 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1732 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001733
Arun Menon906de572013-06-18 17:01:40 -07001734 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1735 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1736 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1737 fmt.fmt.pix_mp.pixelformat = capture_capability;
1738 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1739 if (ret) {
1740 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001741 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001742 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001743 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001744 if (secure_mode) {
1745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1746 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001747 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001748 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1749 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001750 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001751 return OMX_ErrorInsufficientResources;
1752 }
1753 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001754
Arun Menon906de572013-06-18 17:01:40 -07001755 /*Get the Buffer requirements for input and output ports*/
1756 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1757 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1758 if (secure_mode) {
1759 drv_ctx.op_buf.alignment=SZ_1M;
1760 drv_ctx.ip_buf.alignment=SZ_1M;
1761 } else {
1762 drv_ctx.op_buf.alignment=SZ_4K;
1763 drv_ctx.ip_buf.alignment=SZ_4K;
1764 }
1765 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1766 drv_ctx.extradata = 0;
1767 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1768 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1769 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1770 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1771 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001772
Vinay Kalia5713bb32013-01-16 18:39:59 -08001773 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001774#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001775 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1776 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1777 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001778#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001779 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001780 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001781 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001782 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1783 if (m_frame_parser.mutils == NULL) {
1784 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001785
Arun Menon906de572013-06-18 17:01:40 -07001786 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001787 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001788 eRet = OMX_ErrorInsufficientResources;
1789 } else {
1790 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1791 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1792 h264_scratch.nFilledLen = 0;
1793 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001794
Arun Menon906de572013-06-18 17:01:40 -07001795 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001796 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001797 return OMX_ErrorInsufficientResources;
1798 }
1799 m_frame_parser.mutils->initialize_frame_checking_environment();
1800 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1801 }
1802 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001803
Arun Menon906de572013-06-18 17:01:40 -07001804 h264_parser = new h264_stream_parser();
1805 if (!h264_parser) {
1806 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1807 eRet = OMX_ErrorInsufficientResources;
1808 }
1809 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001810
Arun Menon906de572013-06-18 17:01:40 -07001811 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001812 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001813 eRet = OMX_ErrorInsufficientResources;
1814 } else {
1815 int temp1[2];
1816 if (fds[0] == 0 || fds[1] == 0) {
1817 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001818 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001819 return OMX_ErrorInsufficientResources;
1820 }
1821 //close (fds[0]);
1822 //close (fds[1]);
1823 fds[0] = temp1 [0];
1824 fds[1] = temp1 [1];
1825 }
1826 m_pipe_in = fds[0];
1827 m_pipe_out = fds[1];
1828 msg_thread_created = true;
1829 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001830
Arun Menon906de572013-06-18 17:01:40 -07001831 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001832 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001833 msg_thread_created = false;
1834 eRet = OMX_ErrorInsufficientResources;
1835 }
1836 }
1837 }
1838
1839 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001840 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001841 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001842 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001843 }
1844 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1845 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001846}
1847
1848/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001849 FUNCTION
1850 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001851
Arun Menon906de572013-06-18 17:01:40 -07001852 DESCRIPTION
1853 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854
Arun Menon906de572013-06-18 17:01:40 -07001855 PARAMETERS
1856 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001857
Arun Menon906de572013-06-18 17:01:40 -07001858 RETURN VALUE
1859 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001860
Arun Menon906de572013-06-18 17:01:40 -07001861 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001862OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001863(
1864 OMX_IN OMX_HANDLETYPE hComp,
1865 OMX_OUT OMX_STRING componentName,
1866 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1867 OMX_OUT OMX_VERSIONTYPE* specVersion,
1868 OMX_OUT OMX_UUIDTYPE* componentUUID
1869 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001870{
Arun Menon906de572013-06-18 17:01:40 -07001871 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001872 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001873 return OMX_ErrorInvalidState;
1874 }
Arun Menon906de572013-06-18 17:01:40 -07001875 /* TBD -- Return the proper version */
1876 if (specVersion) {
1877 specVersion->nVersion = OMX_SPEC_VERSION;
1878 }
1879 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001880}
1881/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001882 FUNCTION
1883 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001884
Arun Menon906de572013-06-18 17:01:40 -07001885 DESCRIPTION
1886 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001887
Arun Menon906de572013-06-18 17:01:40 -07001888 PARAMETERS
1889 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001890
Arun Menon906de572013-06-18 17:01:40 -07001891 RETURN VALUE
1892 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001893
Arun Menon906de572013-06-18 17:01:40 -07001894 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001895OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001896 OMX_IN OMX_COMMANDTYPE cmd,
1897 OMX_IN OMX_U32 param1,
1898 OMX_IN OMX_PTR cmdData
1899 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001900{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001901 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001902 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001903 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001904 return OMX_ErrorInvalidState;
1905 }
1906 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001907 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001908 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001909 "to invalid port: %lu", param1);
1910 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001911 }
1912 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1913 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001914 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001915 return OMX_ErrorNone;
1916}
1917
1918/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001919 FUNCTION
1920 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001921
Arun Menon906de572013-06-18 17:01:40 -07001922 DESCRIPTION
1923 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001924
Arun Menon906de572013-06-18 17:01:40 -07001925 PARAMETERS
1926 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001927
Arun Menon906de572013-06-18 17:01:40 -07001928 RETURN VALUE
1929 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001930
Arun Menon906de572013-06-18 17:01:40 -07001931 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001932OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001933 OMX_IN OMX_COMMANDTYPE cmd,
1934 OMX_IN OMX_U32 param1,
1935 OMX_IN OMX_PTR cmdData
1936 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001937{
Arun Menon906de572013-06-18 17:01:40 -07001938 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1939 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1940 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001941
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001942 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1943 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001944 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001945
Arun Menon906de572013-06-18 17:01:40 -07001946 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001947 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1948 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001949 /***************************/
1950 /* Current State is Loaded */
1951 /***************************/
1952 if (m_state == OMX_StateLoaded) {
1953 if (eState == OMX_StateIdle) {
1954 //if all buffers are allocated or all ports disabled
1955 if (allocate_done() ||
1956 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001957 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001958 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001959 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001960 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1961 // Skip the event notification
1962 bFlag = 0;
1963 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001964 }
Arun Menon906de572013-06-18 17:01:40 -07001965 /* Requesting transition from Loaded to Loaded */
1966 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001967 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001968 post_event(OMX_EventError,OMX_ErrorSameState,\
1969 OMX_COMPONENT_GENERATE_EVENT);
1970 eRet = OMX_ErrorSameState;
1971 }
1972 /* Requesting transition from Loaded to WaitForResources */
1973 else if (eState == OMX_StateWaitForResources) {
1974 /* Since error is None , we will post an event
1975 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001976 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001977 }
1978 /* Requesting transition from Loaded to Executing */
1979 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001980 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001981 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1982 OMX_COMPONENT_GENERATE_EVENT);
1983 eRet = OMX_ErrorIncorrectStateTransition;
1984 }
1985 /* Requesting transition from Loaded to Pause */
1986 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001987 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001988 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1989 OMX_COMPONENT_GENERATE_EVENT);
1990 eRet = OMX_ErrorIncorrectStateTransition;
1991 }
1992 /* Requesting transition from Loaded to Invalid */
1993 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001994 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001995 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1996 eRet = OMX_ErrorInvalidState;
1997 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001998 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001999 eState);
2000 eRet = OMX_ErrorBadParameter;
2001 }
2002 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002003
Arun Menon906de572013-06-18 17:01:40 -07002004 /***************************/
2005 /* Current State is IDLE */
2006 /***************************/
2007 else if (m_state == OMX_StateIdle) {
2008 if (eState == OMX_StateLoaded) {
2009 if (release_done()) {
2010 /*
2011 Since error is None , we will post an event at the end
2012 of this function definition
2013 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002015 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002016 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002017 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2018 // Skip the event notification
2019 bFlag = 0;
2020 }
2021 }
2022 /* Requesting transition from Idle to Executing */
2023 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002024 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002025 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2026 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002027 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002028 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002029 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002030 }
2031 /* Requesting transition from Idle to Idle */
2032 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002033 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002034 post_event(OMX_EventError,OMX_ErrorSameState,\
2035 OMX_COMPONENT_GENERATE_EVENT);
2036 eRet = OMX_ErrorSameState;
2037 }
2038 /* Requesting transition from Idle to WaitForResources */
2039 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002040 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002041 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2042 OMX_COMPONENT_GENERATE_EVENT);
2043 eRet = OMX_ErrorIncorrectStateTransition;
2044 }
2045 /* Requesting transition from Idle to Pause */
2046 else if (eState == OMX_StatePause) {
2047 /*To pause the Video core we need to start the driver*/
2048 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2049 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002050 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002051 omx_report_error ();
2052 eRet = OMX_ErrorHardware;
2053 } else {
2054 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002055 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002056 bFlag = 0;
2057 }
2058 }
2059 /* Requesting transition from Idle to Invalid */
2060 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002061 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002062 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2063 eRet = OMX_ErrorInvalidState;
2064 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002065 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002066 eRet = OMX_ErrorBadParameter;
2067 }
2068 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002069
Arun Menon906de572013-06-18 17:01:40 -07002070 /******************************/
2071 /* Current State is Executing */
2072 /******************************/
2073 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002074 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002075 /* Requesting transition from Executing to Idle */
2076 if (eState == OMX_StateIdle) {
2077 /* Since error is None , we will post an event
2078 at the end of this function definition
2079 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002080 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002081 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2082 if (!sem_posted) {
2083 sem_posted = 1;
2084 sem_post (&m_cmd_lock);
2085 execute_omx_flush(OMX_ALL);
2086 }
2087 bFlag = 0;
2088 }
2089 /* Requesting transition from Executing to Paused */
2090 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002091 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002092 m_state = OMX_StatePause;
2093 bFlag = 1;
2094 }
2095 /* Requesting transition from Executing to Loaded */
2096 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002097 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002098 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2099 OMX_COMPONENT_GENERATE_EVENT);
2100 eRet = OMX_ErrorIncorrectStateTransition;
2101 }
2102 /* Requesting transition from Executing to WaitForResources */
2103 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002104 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002105 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2106 OMX_COMPONENT_GENERATE_EVENT);
2107 eRet = OMX_ErrorIncorrectStateTransition;
2108 }
2109 /* Requesting transition from Executing to Executing */
2110 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002111 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002112 post_event(OMX_EventError,OMX_ErrorSameState,\
2113 OMX_COMPONENT_GENERATE_EVENT);
2114 eRet = OMX_ErrorSameState;
2115 }
2116 /* Requesting transition from Executing to Invalid */
2117 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002118 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002119 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2120 eRet = OMX_ErrorInvalidState;
2121 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002122 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002123 eRet = OMX_ErrorBadParameter;
2124 }
2125 }
2126 /***************************/
2127 /* Current State is Pause */
2128 /***************************/
2129 else if (m_state == OMX_StatePause) {
2130 /* Requesting transition from Pause to Executing */
2131 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002132 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002133 m_state = OMX_StateExecuting;
2134 bFlag = 1;
2135 }
2136 /* Requesting transition from Pause to Idle */
2137 else if (eState == OMX_StateIdle) {
2138 /* Since error is None , we will post an event
2139 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002140 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002141 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2142 if (!sem_posted) {
2143 sem_posted = 1;
2144 sem_post (&m_cmd_lock);
2145 execute_omx_flush(OMX_ALL);
2146 }
2147 bFlag = 0;
2148 }
2149 /* Requesting transition from Pause to loaded */
2150 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002151 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002152 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2153 OMX_COMPONENT_GENERATE_EVENT);
2154 eRet = OMX_ErrorIncorrectStateTransition;
2155 }
2156 /* Requesting transition from Pause to WaitForResources */
2157 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002158 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002159 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2160 OMX_COMPONENT_GENERATE_EVENT);
2161 eRet = OMX_ErrorIncorrectStateTransition;
2162 }
2163 /* Requesting transition from Pause to Pause */
2164 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002165 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002166 post_event(OMX_EventError,OMX_ErrorSameState,\
2167 OMX_COMPONENT_GENERATE_EVENT);
2168 eRet = OMX_ErrorSameState;
2169 }
2170 /* Requesting transition from Pause to Invalid */
2171 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002172 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002173 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorInvalidState;
2175 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002176 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002177 eRet = OMX_ErrorBadParameter;
2178 }
2179 }
2180 /***************************/
2181 /* Current State is WaitForResources */
2182 /***************************/
2183 else if (m_state == OMX_StateWaitForResources) {
2184 /* Requesting transition from WaitForResources to Loaded */
2185 if (eState == OMX_StateLoaded) {
2186 /* Since error is None , we will post an event
2187 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002188 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002189 }
2190 /* Requesting transition from WaitForResources to WaitForResources */
2191 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002192 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002193 post_event(OMX_EventError,OMX_ErrorSameState,
2194 OMX_COMPONENT_GENERATE_EVENT);
2195 eRet = OMX_ErrorSameState;
2196 }
2197 /* Requesting transition from WaitForResources to Executing */
2198 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002199 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002200 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2201 OMX_COMPONENT_GENERATE_EVENT);
2202 eRet = OMX_ErrorIncorrectStateTransition;
2203 }
2204 /* Requesting transition from WaitForResources to Pause */
2205 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002206 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002207 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2208 OMX_COMPONENT_GENERATE_EVENT);
2209 eRet = OMX_ErrorIncorrectStateTransition;
2210 }
2211 /* Requesting transition from WaitForResources to Invalid */
2212 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002213 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002214 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2215 eRet = OMX_ErrorInvalidState;
2216 }
2217 /* Requesting transition from WaitForResources to Loaded -
2218 is NOT tested by Khronos TS */
2219
2220 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002221 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002222 eRet = OMX_ErrorBadParameter;
2223 }
2224 }
2225 /********************************/
2226 /* Current State is Invalid */
2227 /*******************************/
2228 else if (m_state == OMX_StateInvalid) {
2229 /* State Transition from Inavlid to any state */
2230 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2231 || OMX_StateIdle || OMX_StateExecuting
2232 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002233 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002234 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2235 OMX_COMPONENT_GENERATE_EVENT);
2236 eRet = OMX_ErrorInvalidState;
2237 }
2238 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002239 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002240 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002241#ifdef _MSM8974_
2242 send_codec_config();
2243#endif
Arun Menon906de572013-06-18 17:01:40 -07002244 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2245 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2246 }
2247 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2248 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2249 }
2250 if (!sem_posted) {
2251 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002252 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002253 sem_post (&m_cmd_lock);
2254 execute_omx_flush(param1);
2255 }
2256 bFlag = 0;
2257 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002258 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002259 "with param1: %lu", param1);
2260 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2261 m_inp_bEnabled = OMX_TRUE;
2262
2263 if ( (m_state == OMX_StateLoaded &&
2264 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2265 || allocate_input_done()) {
2266 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2267 OMX_COMPONENT_GENERATE_EVENT);
2268 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002269 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002270 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2271 // Skip the event notification
2272 bFlag = 0;
2273 }
2274 }
2275 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002276 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002277 m_out_bEnabled = OMX_TRUE;
2278
2279 if ( (m_state == OMX_StateLoaded &&
2280 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2281 || (allocate_output_done())) {
2282 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2283 OMX_COMPONENT_GENERATE_EVENT);
2284
2285 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002286 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002287 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2288 // Skip the event notification
2289 bFlag = 0;
2290 }
2291 }
2292 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002293 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002294 "with param1: %lu", param1);
2295 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002296 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002297 m_inp_bEnabled = OMX_FALSE;
2298 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2299 && release_input_done()) {
2300 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2301 OMX_COMPONENT_GENERATE_EVENT);
2302 } else {
2303 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2304 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2305 if (!sem_posted) {
2306 sem_posted = 1;
2307 sem_post (&m_cmd_lock);
2308 }
2309 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2310 }
2311
2312 // Skip the event notification
2313 bFlag = 0;
2314 }
2315 }
2316 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2317 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002318 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002319 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2320 && release_output_done()) {
2321 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2322 OMX_COMPONENT_GENERATE_EVENT);
2323 } else {
2324 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2325 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2326 if (!sem_posted) {
2327 sem_posted = 1;
2328 sem_post (&m_cmd_lock);
2329 }
2330 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2331 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2332 }
2333 // Skip the event notification
2334 bFlag = 0;
2335
2336 }
2337 }
2338 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002339 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002340 eRet = OMX_ErrorNotImplemented;
2341 }
2342 if (eRet == OMX_ErrorNone && bFlag) {
2343 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2344 }
2345 if (!sem_posted) {
2346 sem_post(&m_cmd_lock);
2347 }
2348
2349 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002350}
2351
2352/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002353 FUNCTION
2354 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002355
Arun Menon906de572013-06-18 17:01:40 -07002356 DESCRIPTION
2357 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002358
Arun Menon906de572013-06-18 17:01:40 -07002359 PARAMETERS
2360 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002361
Arun Menon906de572013-06-18 17:01:40 -07002362 RETURN VALUE
2363 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002364
Arun Menon906de572013-06-18 17:01:40 -07002365 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002366bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2367{
Arun Menon906de572013-06-18 17:01:40 -07002368 bool bRet = false;
2369 struct v4l2_plane plane;
2370 struct v4l2_buffer v4l2_buf;
2371 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302372 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002373 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2374 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002375
Arun Menon906de572013-06-18 17:01:40 -07002376 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002377
Arun Menon906de572013-06-18 17:01:40 -07002378 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2379 output_flush_progress = true;
2380 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2381 } else {
2382 /* XXX: The driver/hardware does not support flushing of individual ports
2383 * in all states. So we pretty much need to flush both ports internally,
2384 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2385 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2386 * we automatically omit sending the FLUSH done for the "opposite" port. */
2387 input_flush_progress = true;
2388 output_flush_progress = true;
2389 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2390 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002391
Arun Menon906de572013-06-18 17:01:40 -07002392 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002393 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002394 bRet = false;
2395 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002396
Arun Menon906de572013-06-18 17:01:40 -07002397 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002398}
2399/*=========================================================================
2400FUNCTION : execute_output_flush
2401
2402DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002403Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002404
2405PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002406None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002407
2408RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002409true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002410==========================================================================*/
2411bool omx_vdec::execute_output_flush()
2412{
Arun Menon906de572013-06-18 17:01:40 -07002413 unsigned p1 = 0; // Parameter - 1
2414 unsigned p2 = 0; // Parameter - 2
2415 unsigned ident = 0;
2416 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002417
Arun Menon906de572013-06-18 17:01:40 -07002418 /*Generate FBD for all Buffers in the FTBq*/
2419 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002420 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002421
2422 //reset last render TS
2423 if(m_last_rendered_TS > 0) {
2424 m_last_rendered_TS = 0;
2425 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002426
Arun Menon906de572013-06-18 17:01:40 -07002427 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002428 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002429 m_ftb_q.m_size,pending_output_buffers);
2430 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002431 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002432 if (ident == m_fill_output_msg ) {
2433 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2434 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2435 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2436 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002437 }
Arun Menon906de572013-06-18 17:01:40 -07002438 pthread_mutex_unlock(&m_lock);
2439 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002440
Arun Menon906de572013-06-18 17:01:40 -07002441 if (arbitrary_bytes) {
2442 prev_ts = LLONG_MAX;
2443 rst_prev_ts = true;
2444 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002445 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002446 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002447}
2448/*=========================================================================
2449FUNCTION : execute_input_flush
2450
2451DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002452Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002453
2454PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002455None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002456
2457RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002458true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459==========================================================================*/
2460bool omx_vdec::execute_input_flush()
2461{
Arun Menon906de572013-06-18 17:01:40 -07002462 unsigned i =0;
2463 unsigned p1 = 0; // Parameter - 1
2464 unsigned p2 = 0; // Parameter - 2
2465 unsigned ident = 0;
2466 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002467
Arun Menon906de572013-06-18 17:01:40 -07002468 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002469 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002470
Arun Menon906de572013-06-18 17:01:40 -07002471 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002472 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002473 while (m_etb_q.m_size) {
2474 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002475
Arun Menon906de572013-06-18 17:01:40 -07002476 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002477 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002478 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2479 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2480 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002481 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002482 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2483 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2484 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002485 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002486 (OMX_BUFFERHEADERTYPE *)p1);
2487 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2488 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002489 }
Arun Menon906de572013-06-18 17:01:40 -07002490 time_stamp_dts.flush_timestamp();
2491 /*Check if Heap Buffers are to be flushed*/
2492 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002493 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002494 h264_scratch.nFilledLen = 0;
2495 nal_count = 0;
2496 look_ahead_nal = false;
2497 frame_count = 0;
2498 h264_last_au_ts = LLONG_MAX;
2499 h264_last_au_flags = 0;
2500 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2501 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002502 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002503 if (m_frame_parser.mutils) {
2504 m_frame_parser.mutils->initialize_frame_checking_environment();
2505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002506
Arun Menon906de572013-06-18 17:01:40 -07002507 while (m_input_pending_q.m_size) {
2508 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2509 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2510 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002511
Arun Menon906de572013-06-18 17:01:40 -07002512 if (psource_frame) {
2513 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2514 psource_frame = NULL;
2515 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002516
Arun Menon906de572013-06-18 17:01:40 -07002517 if (pdest_frame) {
2518 pdest_frame->nFilledLen = 0;
2519 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2520 (unsigned int)NULL);
2521 pdest_frame = NULL;
2522 }
2523 m_frame_parser.flush();
2524 } else if (codec_config_flag) {
2525 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2526 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002527 }
Arun Menon906de572013-06-18 17:01:40 -07002528 pthread_mutex_unlock(&m_lock);
2529 input_flush_progress = false;
2530 if (!arbitrary_bytes) {
2531 prev_ts = LLONG_MAX;
2532 rst_prev_ts = true;
2533 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002534#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002535 if (m_debug_timestamp) {
2536 m_timestamp_list.reset_ts_list();
2537 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002538#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002539 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002540 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002541}
2542
2543
2544/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002545 FUNCTION
2546 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002547
Arun Menon906de572013-06-18 17:01:40 -07002548 DESCRIPTION
2549 Send the event to decoder pipe. This is needed to generate the callbacks
2550 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002551
Arun Menon906de572013-06-18 17:01:40 -07002552 PARAMETERS
2553 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002554
Arun Menon906de572013-06-18 17:01:40 -07002555 RETURN VALUE
2556 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002557
Arun Menon906de572013-06-18 17:01:40 -07002558 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002559bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002560 unsigned int p2,
2561 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002562{
Arun Menon906de572013-06-18 17:01:40 -07002563 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002564
2565
Arun Menon906de572013-06-18 17:01:40 -07002566 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002567
Arun Menon906de572013-06-18 17:01:40 -07002568 if (id == m_fill_output_msg ||
2569 id == OMX_COMPONENT_GENERATE_FBD) {
2570 m_ftb_q.insert_entry(p1,p2,id);
2571 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2572 id == OMX_COMPONENT_GENERATE_EBD ||
2573 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2574 m_etb_q.insert_entry(p1,p2,id);
2575 } else {
2576 m_cmd_q.insert_entry(p1,p2,id);
2577 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002578
Arun Menon906de572013-06-18 17:01:40 -07002579 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002580 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002581 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002582
Arun Menon906de572013-06-18 17:01:40 -07002583 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002584
Arun Menon906de572013-06-18 17:01:40 -07002585 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002586}
2587
2588OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2589{
Arun Menon906de572013-06-18 17:01:40 -07002590 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2591 if (!profileLevelType)
2592 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002593
Arun Menon906de572013-06-18 17:01:40 -07002594 if (profileLevelType->nPortIndex == 0) {
2595 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2596 if (profileLevelType->nProfileIndex == 0) {
2597 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2598 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002599
Arun Menon906de572013-06-18 17:01:40 -07002600 } else if (profileLevelType->nProfileIndex == 1) {
2601 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2602 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2603 } else if (profileLevelType->nProfileIndex == 2) {
2604 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2605 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2606 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002607 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002608 profileLevelType->nProfileIndex);
2609 eRet = OMX_ErrorNoMore;
2610 }
2611 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2612 if (profileLevelType->nProfileIndex == 0) {
2613 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2614 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2615 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002616 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002617 eRet = OMX_ErrorNoMore;
2618 }
2619 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2620 if (profileLevelType->nProfileIndex == 0) {
2621 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2622 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2623 } else if (profileLevelType->nProfileIndex == 1) {
2624 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2625 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2626 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002627 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002628 eRet = OMX_ErrorNoMore;
2629 }
2630 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2631 eRet = OMX_ErrorNoMore;
2632 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2633 if (profileLevelType->nProfileIndex == 0) {
2634 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2635 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2636 } else if (profileLevelType->nProfileIndex == 1) {
2637 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2638 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2639 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002641 eRet = OMX_ErrorNoMore;
2642 }
2643 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002644 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002645 eRet = OMX_ErrorNoMore;
2646 }
2647 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002648 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002649 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002650 }
Arun Menon906de572013-06-18 17:01:40 -07002651 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002652}
2653
2654/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002655 FUNCTION
2656 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002657
Arun Menon906de572013-06-18 17:01:40 -07002658 DESCRIPTION
2659 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002660
Arun Menon906de572013-06-18 17:01:40 -07002661 PARAMETERS
2662 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002663
Arun Menon906de572013-06-18 17:01:40 -07002664 RETURN VALUE
2665 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002666
Arun Menon906de572013-06-18 17:01:40 -07002667 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002668OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002669 OMX_IN OMX_INDEXTYPE paramIndex,
2670 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002671{
2672 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2673
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002674 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002675 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002676 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002677 return OMX_ErrorInvalidState;
2678 }
Arun Menon906de572013-06-18 17:01:40 -07002679 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002680 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002681 return OMX_ErrorBadParameter;
2682 }
Arun Menon906de572013-06-18 17:01:40 -07002683 switch ((unsigned long)paramIndex) {
2684 case OMX_IndexParamPortDefinition: {
2685 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2686 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002687 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002688 eRet = update_portdef(portDefn);
2689 if (eRet == OMX_ErrorNone)
2690 m_port_def = *portDefn;
2691 break;
2692 }
2693 case OMX_IndexParamVideoInit: {
2694 OMX_PORT_PARAM_TYPE *portParamType =
2695 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002696 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002697
Arun Menon906de572013-06-18 17:01:40 -07002698 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2699 portParamType->nSize = sizeof(portParamType);
2700 portParamType->nPorts = 2;
2701 portParamType->nStartPortNumber = 0;
2702 break;
2703 }
2704 case OMX_IndexParamVideoPortFormat: {
2705 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2706 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002707 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002708
Arun Menon906de572013-06-18 17:01:40 -07002709 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2710 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002711
Arun Menon906de572013-06-18 17:01:40 -07002712 if (0 == portFmt->nPortIndex) {
2713 if (0 == portFmt->nIndex) {
2714 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2715 portFmt->eCompressionFormat = eCompressionFormat;
2716 } else {
2717 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002718 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002719 eRet = OMX_ErrorNoMore;
2720 }
2721 } else if (1 == portFmt->nPortIndex) {
2722 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002723
Arun Menon906de572013-06-18 17:01:40 -07002724 if (0 == portFmt->nIndex)
2725 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2726 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2727 else if (1 == portFmt->nIndex)
2728 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2729 else {
2730 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002731 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002732 eRet = OMX_ErrorNoMore;
2733 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002734 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002735 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002736 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002737 (int)portFmt->nPortIndex);
2738 eRet = OMX_ErrorBadPortIndex;
2739 }
2740 break;
2741 }
2742 /*Component should support this port definition*/
2743 case OMX_IndexParamAudioInit: {
2744 OMX_PORT_PARAM_TYPE *audioPortParamType =
2745 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002746 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002747 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2748 audioPortParamType->nSize = sizeof(audioPortParamType);
2749 audioPortParamType->nPorts = 0;
2750 audioPortParamType->nStartPortNumber = 0;
2751 break;
2752 }
2753 /*Component should support this port definition*/
2754 case OMX_IndexParamImageInit: {
2755 OMX_PORT_PARAM_TYPE *imagePortParamType =
2756 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002757 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002758 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2759 imagePortParamType->nSize = sizeof(imagePortParamType);
2760 imagePortParamType->nPorts = 0;
2761 imagePortParamType->nStartPortNumber = 0;
2762 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002763
Arun Menon906de572013-06-18 17:01:40 -07002764 }
2765 /*Component should support this port definition*/
2766 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002767 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002768 paramIndex);
2769 eRet =OMX_ErrorUnsupportedIndex;
2770 break;
2771 }
2772 case OMX_IndexParamStandardComponentRole: {
2773 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2774 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2775 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2776 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002777
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002778 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002779 paramIndex);
2780 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2781 OMX_MAX_STRINGNAME_SIZE);
2782 break;
2783 }
2784 /* Added for parameter test */
2785 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002786
Arun Menon906de572013-06-18 17:01:40 -07002787 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2788 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002789 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002790 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2791 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002792
Arun Menon906de572013-06-18 17:01:40 -07002793 break;
2794 }
2795 /* Added for parameter test */
2796 case OMX_IndexParamCompBufferSupplier: {
2797 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2798 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002799 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002800
Arun Menon906de572013-06-18 17:01:40 -07002801 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2802 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2803 if (0 == bufferSupplierType->nPortIndex)
2804 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2805 else if (1 == bufferSupplierType->nPortIndex)
2806 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2807 else
2808 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002809
2810
Arun Menon906de572013-06-18 17:01:40 -07002811 break;
2812 }
2813 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002814 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002815 paramIndex);
2816 break;
2817 }
2818 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002819 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002820 paramIndex);
2821 break;
2822 }
2823 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002824 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002825 paramIndex);
2826 break;
2827 }
2828 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002829 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002830 paramIndex);
2831 break;
2832 }
2833 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002834 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002835 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2836 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2837 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2838 break;
2839 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002840#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002841 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002842 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002843 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2844 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002845
Arun Menon906de572013-06-18 17:01:40 -07002846 if (secure_mode) {
2847 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2848 GRALLOC_USAGE_PRIVATE_UNCACHED);
2849 } else {
2850 nativeBuffersUsage->nUsage =
2851 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2852 GRALLOC_USAGE_PRIVATE_UNCACHED);
2853 }
2854 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002855 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002856 eRet = OMX_ErrorBadParameter;
2857 }
2858 }
2859 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002860#endif
2861
Arun Menon906de572013-06-18 17:01:40 -07002862 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002863 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002864 eRet =OMX_ErrorUnsupportedIndex;
2865 }
2866
Shalaj Jain273b3e02012-06-22 19:08:03 -07002867 }
2868
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002869 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002870 drv_ctx.video_resolution.frame_width,
2871 drv_ctx.video_resolution.frame_height,
2872 drv_ctx.video_resolution.stride,
2873 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002874
Arun Menon906de572013-06-18 17:01:40 -07002875 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002876}
2877
2878#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2879OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2880{
2881 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2882 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2883 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2884
Arun Menon906de572013-06-18 17:01:40 -07002885 if ((params == NULL) ||
2886 (params->nativeBuffer == NULL) ||
2887 (params->nativeBuffer->handle == NULL) ||
2888 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002889 return OMX_ErrorBadParameter;
2890 m_use_android_native_buffers = OMX_TRUE;
2891 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2892 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002893 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 -07002894 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002895 if (!secure_mode) {
2896 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002897 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002898 if (buffer == MAP_FAILED) {
2899 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2900 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002901 }
2902 }
2903 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2904 } else {
2905 eRet = OMX_ErrorBadParameter;
2906 }
2907 return eRet;
2908}
2909#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002910
2911OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2912 struct v4l2_control control;
2913 struct v4l2_format fmt;
2914 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2915 control.value = 1;
2916 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2917 if (rc < 0) {
2918 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2919 return OMX_ErrorHardware;
2920 }
2921 m_smoothstreaming_mode = true;
2922 return OMX_ErrorNone;
2923}
2924
Shalaj Jain273b3e02012-06-22 19:08:03 -07002925/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002926 FUNCTION
2927 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002928
Arun Menon906de572013-06-18 17:01:40 -07002929 DESCRIPTION
2930 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002931
Arun Menon906de572013-06-18 17:01:40 -07002932 PARAMETERS
2933 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002934
Arun Menon906de572013-06-18 17:01:40 -07002935 RETURN VALUE
2936 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002937
Arun Menon906de572013-06-18 17:01:40 -07002938 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002939OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002940 OMX_IN OMX_INDEXTYPE paramIndex,
2941 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002942{
2943 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002944 int ret=0;
2945 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002946 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002947 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002948 return OMX_ErrorInvalidState;
2949 }
Arun Menon906de572013-06-18 17:01:40 -07002950 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002951 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002952 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002953 }
Arun Menon906de572013-06-18 17:01:40 -07002954 if ((m_state != OMX_StateLoaded) &&
2955 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2956 (m_out_bEnabled == OMX_TRUE) &&
2957 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2958 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002959 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002960 return OMX_ErrorIncorrectStateOperation;
2961 }
Arun Menon906de572013-06-18 17:01:40 -07002962 switch ((unsigned long)paramIndex) {
2963 case OMX_IndexParamPortDefinition: {
2964 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2965 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2966 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2967 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002968 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002969 (int)portDefn->format.video.nFrameHeight,
2970 (int)portDefn->format.video.nFrameWidth);
2971 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002972 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002973 m_display_id = portDefn->format.video.pNativeWindow;
2974 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002975 /* update output port resolution with client supplied dimensions
2976 in case scaling is enabled, else it follows input resolution set
2977 */
2978 if (is_down_scalar_enabled) {
2979 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002980 portDefn->format.video.nFrameWidth,
2981 portDefn->format.video.nFrameHeight);
2982 if (portDefn->format.video.nFrameHeight != 0x0 &&
2983 portDefn->format.video.nFrameWidth != 0x0) {
2984 update_resolution(portDefn->format.video.nFrameWidth,
2985 portDefn->format.video.nFrameHeight,
2986 portDefn->format.video.nFrameWidth,
2987 portDefn->format.video.nFrameHeight);
2988 eRet = is_video_session_supported();
2989 if (eRet)
2990 break;
2991 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2992 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2993 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2994 fmt.fmt.pix_mp.pixelformat = capture_capability;
2995 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);
2996 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2997 if (ret) {
2998 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2999 eRet = OMX_ErrorUnsupportedSetting;
3000 } else
3001 eRet = get_buffer_req(&drv_ctx.op_buf);
3002 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003003 }
Arun Menon906de572013-06-18 17:01:40 -07003004 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003005 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003006 eRet = OMX_ErrorBadParameter;
3007 } else {
3008 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3009 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3010 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3011 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3012 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3013 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3014 drv_ctx.extradata_info.buffer_size;
3015 eRet = set_buffer_req(&drv_ctx.op_buf);
3016 if (eRet == OMX_ErrorNone)
3017 m_port_def = *portDefn;
3018 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003019 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003020 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3021 portDefn->nBufferCountActual, portDefn->nBufferSize);
3022 eRet = OMX_ErrorBadParameter;
3023 }
3024 }
3025 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003026 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003027 bool port_format_changed = false;
3028 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3029 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3030 // Frame rate only should be set if this is a "known value" or to
3031 // activate ts prediction logic (arbitrary mode only) sending input
3032 // timestamps with max value (LLONG_MAX).
3033 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3034 portDefn->format.video.xFramerate >> 16);
3035 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3036 drv_ctx.frame_rate.fps_denominator);
3037 if (!drv_ctx.frame_rate.fps_numerator) {
3038 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3039 drv_ctx.frame_rate.fps_numerator = 30;
3040 }
3041 if (drv_ctx.frame_rate.fps_denominator)
3042 drv_ctx.frame_rate.fps_numerator = (int)
3043 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3044 drv_ctx.frame_rate.fps_denominator = 1;
3045 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3046 drv_ctx.frame_rate.fps_numerator;
3047 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3048 frm_int, drv_ctx.frame_rate.fps_numerator /
3049 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003050
3051 struct v4l2_outputparm oparm;
3052 /*XXX: we're providing timing info as seconds per frame rather than frames
3053 * per second.*/
3054 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3055 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3056
3057 struct v4l2_streamparm sparm;
3058 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3059 sparm.parm.output = oparm;
3060 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3061 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3062 eRet = OMX_ErrorHardware;
3063 break;
3064 }
Arun Menon906de572013-06-18 17:01:40 -07003065 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003066
Arun Menon906de572013-06-18 17:01:40 -07003067 if (drv_ctx.video_resolution.frame_height !=
3068 portDefn->format.video.nFrameHeight ||
3069 drv_ctx.video_resolution.frame_width !=
3070 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003071 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003072 portDefn->format.video.nFrameWidth,
3073 portDefn->format.video.nFrameHeight);
3074 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003075 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3076 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3077 if (frameHeight != 0x0 && frameWidth != 0x0) {
3078 if (m_smoothstreaming_mode &&
3079 ((frameWidth * frameHeight) <
3080 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3081 frameWidth = m_smoothstreaming_width;
3082 frameHeight = m_smoothstreaming_height;
3083 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3084 frameWidth, frameHeight);
3085 }
3086 update_resolution(frameWidth, frameHeight,
3087 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003088 eRet = is_video_session_supported();
3089 if (eRet)
3090 break;
3091 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3092 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3093 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3094 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003095 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 -07003096 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3097 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003098 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003099 eRet = OMX_ErrorUnsupportedSetting;
3100 } else
3101 eRet = get_buffer_req(&drv_ctx.op_buf);
3102 }
3103 }
3104 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3105 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3106 port_format_changed = true;
3107 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3108 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3109 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3110 (~(buffer_prop->alignment - 1));
3111 eRet = set_buffer_req(buffer_prop);
3112 }
3113 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003114 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003115 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3116 portDefn->nBufferCountActual, portDefn->nBufferSize);
3117 eRet = OMX_ErrorBadParameter;
3118 }
3119 } else if (portDefn->eDir == OMX_DirMax) {
3120 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3121 (int)portDefn->nPortIndex);
3122 eRet = OMX_ErrorBadPortIndex;
3123 }
3124 }
3125 break;
3126 case OMX_IndexParamVideoPortFormat: {
3127 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3128 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3129 int ret=0;
3130 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003131 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003132 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003133
Arun Menon906de572013-06-18 17:01:40 -07003134 if (1 == portFmt->nPortIndex) {
3135 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3136 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3137 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3138 fmt.fmt.pix_mp.pixelformat = capture_capability;
3139 enum vdec_output_fromat op_format;
3140 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3141 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3142 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3143 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3144 else if (portFmt->eColorFormat ==
3145 (OMX_COLOR_FORMATTYPE)
3146 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3147 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3148 else
3149 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003150
Arun Menon906de572013-06-18 17:01:40 -07003151 if (eRet == OMX_ErrorNone) {
3152 drv_ctx.output_format = op_format;
3153 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3154 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003155 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003156 eRet = OMX_ErrorUnsupportedSetting;
3157 /*TODO: How to handle this case */
3158 } else {
3159 eRet = get_buffer_req(&drv_ctx.op_buf);
3160 }
3161 }
3162 if (eRet == OMX_ErrorNone) {
3163 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003164 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003165 eRet = OMX_ErrorBadParameter;
3166 }
3167 }
3168 }
3169 }
3170 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003171
Arun Menon906de572013-06-18 17:01:40 -07003172 case OMX_QcomIndexPortDefn: {
3173 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3174 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003175 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003176 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003177
Arun Menon906de572013-06-18 17:01:40 -07003178 /* Input port */
3179 if (portFmt->nPortIndex == 0) {
3180 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3181 if (secure_mode) {
3182 arbitrary_bytes = false;
3183 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3184 eRet = OMX_ErrorUnsupportedSetting;
3185 } else {
3186 arbitrary_bytes = true;
3187 }
3188 } else if (portFmt->nFramePackingFormat ==
3189 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3190 arbitrary_bytes = false;
3191 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003192 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003193 portFmt->nFramePackingFormat);
3194 eRet = OMX_ErrorUnsupportedSetting;
3195 }
3196 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003197 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003198 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3199 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3200 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3201 m_out_mem_region_smi = OMX_TRUE;
3202 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003203 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003204 m_use_output_pmem = OMX_TRUE;
3205 }
3206 }
3207 }
3208 }
3209 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003210
Arun Menon906de572013-06-18 17:01:40 -07003211 case OMX_IndexParamStandardComponentRole: {
3212 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3213 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003214 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003215 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003216
Arun Menon906de572013-06-18 17:01:40 -07003217 if ((m_state == OMX_StateLoaded)&&
3218 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3219 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3220 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003221 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003222 return OMX_ErrorIncorrectStateOperation;
3223 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003224
Arun Menon906de572013-06-18 17:01:40 -07003225 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3226 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3227 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3228 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003229 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003230 eRet =OMX_ErrorUnsupportedSetting;
3231 }
3232 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3233 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3234 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3235 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003236 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003237 eRet = OMX_ErrorUnsupportedSetting;
3238 }
3239 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3240 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3241 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3242 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003243 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003244 eRet =OMX_ErrorUnsupportedSetting;
3245 }
3246 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3247 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3248 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3249 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003250 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003251 eRet = OMX_ErrorUnsupportedSetting;
3252 }
3253 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3254 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3255 ) {
3256 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3257 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3258 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003259 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003260 eRet =OMX_ErrorUnsupportedSetting;
3261 }
3262 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3263 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3264 ) {
3265 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3266 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3267 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003268 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003269 eRet =OMX_ErrorUnsupportedSetting;
3270 }
3271 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3272 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3273 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3274 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3275 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003276 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003277 eRet = OMX_ErrorUnsupportedSetting;
3278 }
3279 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003280 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003281 eRet = OMX_ErrorInvalidComponentName;
3282 }
3283 break;
3284 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003285
Arun Menon906de572013-06-18 17:01:40 -07003286 case OMX_IndexParamPriorityMgmt: {
3287 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003288 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003289 return OMX_ErrorIncorrectStateOperation;
3290 }
3291 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003292 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003293 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003294
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003295 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003296 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003297
Arun Menon906de572013-06-18 17:01:40 -07003298 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3299 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003300
Arun Menon906de572013-06-18 17:01:40 -07003301 break;
3302 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003303
Arun Menon906de572013-06-18 17:01:40 -07003304 case OMX_IndexParamCompBufferSupplier: {
3305 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003306 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003307 bufferSupplierType->eBufferSupplier);
3308 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3309 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003310
Arun Menon906de572013-06-18 17:01:40 -07003311 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003312
Arun Menon906de572013-06-18 17:01:40 -07003313 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003314
Arun Menon906de572013-06-18 17:01:40 -07003315 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003316
Arun Menon906de572013-06-18 17:01:40 -07003317 }
3318 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003319 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003320 paramIndex);
3321 break;
3322 }
3323 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003324 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003325 paramIndex);
3326 break;
3327 }
3328 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003329 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003330 paramIndex);
3331 break;
3332 }
3333 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003334 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003335 paramIndex);
3336 break;
3337 }
3338 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3339 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3340 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3341 struct v4l2_control control;
3342 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003343 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003344 pictureOrder->eOutputPictureOrder);
3345 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3346 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3347 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3348 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3349 time_stamp_dts.set_timestamp_reorder_mode(false);
3350 } else
3351 eRet = OMX_ErrorBadParameter;
3352 if (eRet == OMX_ErrorNone) {
3353 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3354 control.value = pic_order;
3355 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3356 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003357 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003358 eRet = OMX_ErrorUnsupportedSetting;
3359 }
3360 }
3361 break;
3362 }
3363 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303364 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3365 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3366 break;
3367 case OMX_QcomIndexParamFrameInfoExtraData:
3368 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3369 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3370 break;
Arun Menon906de572013-06-18 17:01:40 -07003371 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303372 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3373 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3374 break;
Arun Menon906de572013-06-18 17:01:40 -07003375 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303376 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3377 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3378 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303379 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303380 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3381 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3382 break;
3383 case OMX_QcomIndexParamVideoQPExtraData:
3384 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3385 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3386 break;
3387 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3388 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3389 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3390 break;
Arun Menon906de572013-06-18 17:01:40 -07003391 case OMX_QcomIndexParamVideoDivx: {
3392 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3393 }
3394 break;
3395 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003396 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003397 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3398 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3399 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3400 eRet = OMX_ErrorUnsupportedSetting;
3401 } else {
3402 m_out_pvt_entry_pmem = OMX_TRUE;
3403 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003404 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003405 m_use_output_pmem = OMX_TRUE;
3406 }
3407 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003408
Arun Menon906de572013-06-18 17:01:40 -07003409 }
3410 break;
3411 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3412 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3413 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3414 struct v4l2_control control;
3415 int rc;
3416 drv_ctx.idr_only_decoding = 1;
3417 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3418 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3419 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3420 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003421 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003422 eRet = OMX_ErrorUnsupportedSetting;
3423 } else {
3424 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3425 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3426 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3427 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003428 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003429 eRet = OMX_ErrorUnsupportedSetting;
3430 }
3431 /*Setting sync frame decoding on driver might change buffer
3432 * requirements so update them here*/
3433 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003434 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003435 eRet = OMX_ErrorUnsupportedSetting;
3436 }
3437 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003438 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003439 eRet = OMX_ErrorUnsupportedSetting;
3440 }
3441 }
3442 }
3443 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003444
Arun Menon906de572013-06-18 17:01:40 -07003445 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303446 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3447 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3448 (extradataIndexType->bEnabled == OMX_TRUE) &&
3449 (extradataIndexType->nPortIndex == 1)) {
3450 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3451 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3452 }
3453 }
Arun Menon906de572013-06-18 17:01:40 -07003454 break;
3455 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003456#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003457 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003458#else
Arun Menon906de572013-06-18 17:01:40 -07003459 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003460#endif
Arun Menon906de572013-06-18 17:01:40 -07003461 }
3462 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003463#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003464 /* Need to allow following two set_parameters even in Idle
3465 * state. This is ANDROID architecture which is not in sync
3466 * with openmax standard. */
3467 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3468 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3469 if (enableNativeBuffers) {
3470 m_enable_android_native_buffers = enableNativeBuffers->enable;
3471 }
3472 }
3473 break;
3474 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3475 eRet = use_android_native_buffer(hComp, paramData);
3476 }
3477 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003478#endif
Arun Menon906de572013-06-18 17:01:40 -07003479 case OMX_QcomIndexParamEnableTimeStampReorder: {
3480 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3481 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3482 if (reorder->bEnable == OMX_TRUE) {
3483 frm_int =0;
3484 time_stamp_dts.set_timestamp_reorder_mode(true);
3485 } else
3486 time_stamp_dts.set_timestamp_reorder_mode(false);
3487 } else {
3488 time_stamp_dts.set_timestamp_reorder_mode(false);
3489 if (reorder->bEnable == OMX_TRUE) {
3490 eRet = OMX_ErrorUnsupportedSetting;
3491 }
3492 }
3493 }
3494 break;
3495 case OMX_IndexParamVideoProfileLevelCurrent: {
3496 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3497 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3498 if (pParam) {
3499 m_profile_lvl.eProfile = pParam->eProfile;
3500 m_profile_lvl.eLevel = pParam->eLevel;
3501 }
3502 break;
Arun Menon888aa852013-05-30 11:24:42 -07003503
Arun Menon906de572013-06-18 17:01:40 -07003504 }
Arun Menone5652482013-08-04 13:33:05 -07003505 case OMX_QcomIndexParamVideoMetaBufferMode:
3506 {
3507 StoreMetaDataInBuffersParams *metabuffer =
3508 (StoreMetaDataInBuffersParams *)paramData;
3509 if (!metabuffer) {
3510 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3511 eRet = OMX_ErrorBadParameter;
3512 break;
3513 }
3514 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3515 //set property dynamic buffer mode to driver.
3516 struct v4l2_control control;
3517 struct v4l2_format fmt;
3518 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3519 if (metabuffer->bStoreMetaData == true) {
3520 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3521 } else {
3522 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3523 }
3524 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3525 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003526 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003527 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003528 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003529 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003530 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003531 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3532 eRet = OMX_ErrorUnsupportedSetting;
3533 }
3534 } else {
3535 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003536 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003537 metabuffer->nPortIndex);
3538 eRet = OMX_ErrorUnsupportedSetting;
3539 }
3540 break;
3541 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003542 case OMX_QcomIndexParamVideoDownScalar: {
3543 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3544 struct v4l2_control control;
3545 int rc;
3546 if (pParam) {
3547 is_down_scalar_enabled = pParam->bEnable;
3548 if (is_down_scalar_enabled) {
3549 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3550 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3551 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3552 pParam->bEnable);
3553 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3554 if (rc < 0) {
3555 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3556 eRet = OMX_ErrorUnsupportedSetting;
3557 }
3558 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3559 control.value = 1;
3560 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3561 if (rc < 0) {
3562 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3563 eRet = OMX_ErrorUnsupportedSetting;
3564 }
3565 }
3566 }
3567 break;
3568 }
Praveen Chavancf924182013-12-06 23:16:23 -08003569#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3570 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3571 {
3572 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3573 PrepareForAdaptivePlaybackParams* pParams =
3574 (PrepareForAdaptivePlaybackParams *) paramData;
3575 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3576 if (!pParams->bEnable) {
3577 return OMX_ErrorNone;
3578 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303579 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3580 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003581 DEBUG_PRINT_ERROR(
3582 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3583 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303584 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003585 eRet = OMX_ErrorBadParameter;
3586 } else {
3587 eRet = enable_smoothstreaming();
3588 if (eRet != OMX_ErrorNone) {
3589 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3590 eRet = OMX_ErrorHardware;
3591 } else {
3592 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3593 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3594 m_smoothstreaming_mode = true;
3595 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3596 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3597 }
Deepak Vermaf8771292014-02-03 12:22:50 +05303598 struct v4l2_format fmt;
3599 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
3600 m_smoothstreaming_width, m_smoothstreaming_height);
3601 eRet = is_video_session_supported();
3602 if (eRet)
3603 break;
3604 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3605 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3606 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3607 fmt.fmt.pix_mp.pixelformat = output_capability;
3608 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
3609 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
3610 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3611 if (ret) {
3612 DEBUG_PRINT_ERROR("Set Resolution failed");
3613 eRet = OMX_ErrorUnsupportedSetting;
3614 } else
3615 eRet = get_buffer_req(&drv_ctx.op_buf);
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303616 }
Praveen Chavancf924182013-12-06 23:16:23 -08003617 } else {
3618 DEBUG_PRINT_ERROR(
3619 "Prepare for adaptive playback supported only on output port");
3620 eRet = OMX_ErrorBadParameter;
3621 }
3622 break;
3623 }
3624
3625#endif
Arun Menon906de572013-06-18 17:01:40 -07003626 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003627 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003628 eRet = OMX_ErrorUnsupportedIndex;
3629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003630 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003631 if (eRet != OMX_ErrorNone)
3632 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003633 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003634}
3635
3636/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003637 FUNCTION
3638 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003639
Arun Menon906de572013-06-18 17:01:40 -07003640 DESCRIPTION
3641 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003642
Arun Menon906de572013-06-18 17:01:40 -07003643 PARAMETERS
3644 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003645
Arun Menon906de572013-06-18 17:01:40 -07003646 RETURN VALUE
3647 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003648
Arun Menon906de572013-06-18 17:01:40 -07003649 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003650OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003651 OMX_IN OMX_INDEXTYPE configIndex,
3652 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653{
Arun Menon906de572013-06-18 17:01:40 -07003654 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003655
Arun Menon906de572013-06-18 17:01:40 -07003656 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003657 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003658 return OMX_ErrorInvalidState;
3659 }
Arun Menon906de572013-06-18 17:01:40 -07003660
3661 switch ((unsigned long)configIndex) {
3662 case OMX_QcomIndexConfigInterlaced: {
3663 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3664 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3665 if (configFmt->nPortIndex == 1) {
3666 if (configFmt->nIndex == 0) {
3667 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3668 } else if (configFmt->nIndex == 1) {
3669 configFmt->eInterlaceType =
3670 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3671 } else if (configFmt->nIndex == 2) {
3672 configFmt->eInterlaceType =
3673 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3674 } else {
3675 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003676 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003677 eRet = OMX_ErrorNoMore;
3678 }
3679
3680 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003681 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003682 (int)configFmt->nPortIndex);
3683 eRet = OMX_ErrorBadPortIndex;
3684 }
3685 break;
3686 }
3687 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3688 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3689 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3690 decoderinstances->nNumOfInstances = 16;
3691 /*TODO: How to handle this case */
3692 break;
3693 }
3694 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3695 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3696 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3697 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303698 memcpy(configFmt, &m_frame_pack_arrangement,
3699 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003700 } else {
3701 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3702 }
3703 break;
3704 }
3705 case OMX_IndexConfigCommonOutputCrop: {
3706 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3707 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3708 break;
3709 }
3710 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003711 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003712 eRet = OMX_ErrorBadParameter;
3713 }
3714
Shalaj Jain273b3e02012-06-22 19:08:03 -07003715 }
Arun Menon906de572013-06-18 17:01:40 -07003716
3717 return eRet;
3718}
3719
3720/* ======================================================================
3721 FUNCTION
3722 omx_vdec::SetConfig
3723
3724 DESCRIPTION
3725 OMX Set Config method implementation
3726
3727 PARAMETERS
3728 <TBD>.
3729
3730 RETURN VALUE
3731 OMX Error None if successful.
3732 ========================================================================== */
3733OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3734 OMX_IN OMX_INDEXTYPE configIndex,
3735 OMX_IN OMX_PTR configData)
3736{
3737 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003738 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003739 return OMX_ErrorInvalidState;
3740 }
3741
3742 OMX_ERRORTYPE ret = OMX_ErrorNone;
3743 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3744
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003745 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003746
3747 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3748 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003749 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003750 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003751 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003752 OMX_U32 extra_size;
3753 // Parsing done here for the AVC atom is definitely not generic
3754 // Currently this piece of code is working, but certainly
3755 // not tested with all .mp4 files.
3756 // Incase of failure, we might need to revisit this
3757 // for a generic piece of code.
3758
3759 // Retrieve size of NAL length field
3760 // byte #4 contains the size of NAL lenght field
3761 nal_length = (config->pData[4] & 0x03) + 1;
3762
3763 extra_size = 0;
3764 if (nal_length > 2) {
3765 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3766 extra_size = (nal_length - 2) * 2;
3767 }
3768
3769 // SPS starts from byte #6
3770 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3771 OMX_U8 *pDestBuf;
3772 m_vendor_config.nPortIndex = config->nPortIndex;
3773
3774 // minus 6 --> SPS starts from byte #6
3775 // minus 1 --> picture param set byte to be ignored from avcatom
3776 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3777 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3778 OMX_U32 len;
3779 OMX_U8 index = 0;
3780 // case where SPS+PPS is sent as part of set_config
3781 pDestBuf = m_vendor_config.pData;
3782
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003783 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003784 m_vendor_config.nPortIndex,
3785 m_vendor_config.nDataSize,
3786 m_vendor_config.pData);
3787 while (index < 2) {
3788 uint8 *psize;
3789 len = *pSrcBuf;
3790 len = len << 8;
3791 len |= *(pSrcBuf + 1);
3792 psize = (uint8 *) & len;
3793 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3794 for (unsigned int i = 0; i < nal_length; i++) {
3795 pDestBuf[i] = psize[nal_length - 1 - i];
3796 }
3797 //memcpy(pDestBuf,pSrcBuf,(len+2));
3798 pDestBuf += len + nal_length;
3799 pSrcBuf += len + 2;
3800 index++;
3801 pSrcBuf++; // skip picture param set
3802 len = 0;
3803 }
3804 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3805 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3806 m_vendor_config.nPortIndex = config->nPortIndex;
3807 m_vendor_config.nDataSize = config->nDataSize;
3808 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3809 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3810 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3811 if (m_vendor_config.pData) {
3812 free(m_vendor_config.pData);
3813 m_vendor_config.pData = NULL;
3814 m_vendor_config.nDataSize = 0;
3815 }
3816
3817 if (((*((OMX_U32 *) config->pData)) &
3818 VC1_SP_MP_START_CODE_MASK) ==
3819 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003820 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003821 m_vendor_config.nPortIndex = config->nPortIndex;
3822 m_vendor_config.nDataSize = config->nDataSize;
3823 m_vendor_config.pData =
3824 (OMX_U8 *) malloc(config->nDataSize);
3825 memcpy(m_vendor_config.pData, config->pData,
3826 config->nDataSize);
3827 m_vc1_profile = VC1_SP_MP_RCV;
3828 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003829 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003830 m_vendor_config.nPortIndex = config->nPortIndex;
3831 m_vendor_config.nDataSize = config->nDataSize;
3832 m_vendor_config.pData =
3833 (OMX_U8 *) malloc((config->nDataSize));
3834 memcpy(m_vendor_config.pData, config->pData,
3835 config->nDataSize);
3836 m_vc1_profile = VC1_AP;
3837 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003838 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003839 m_vendor_config.nPortIndex = config->nPortIndex;
3840 m_vendor_config.nDataSize = config->nDataSize;
3841 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3842 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3843 m_vc1_profile = VC1_SP_MP_RCV;
3844 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003845 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003846 }
3847 }
3848 return ret;
3849 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3850 struct v4l2_control temp;
3851 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3852
3853 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3854 switch (pNal->nNaluBytes) {
3855 case 0:
3856 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3857 break;
3858 case 2:
3859 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3860 break;
3861 case 4:
3862 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3863 break;
3864 default:
3865 return OMX_ErrorUnsupportedSetting;
3866 }
3867
3868 if (!arbitrary_bytes) {
3869 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3870 * with start code, so only need to notify driver in frame by frame mode */
3871 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3872 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3873 return OMX_ErrorHardware;
3874 }
3875 }
3876
3877 nal_length = pNal->nNaluBytes;
3878 m_frame_parser.init_nal_length(nal_length);
3879
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003880 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003881 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303882 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003883 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303884 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003885
3886 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3887 if (config->bEnabled) {
3888 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303889 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003890 config->nFps >> 16);
3891 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3892 drv_ctx.frame_rate.fps_denominator);
3893
3894 if (!drv_ctx.frame_rate.fps_numerator) {
3895 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3896 drv_ctx.frame_rate.fps_numerator = 30;
3897 }
3898
3899 if (drv_ctx.frame_rate.fps_denominator) {
3900 drv_ctx.frame_rate.fps_numerator = (int)
3901 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3902 }
3903
3904 drv_ctx.frame_rate.fps_denominator = 1;
3905 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3906 drv_ctx.frame_rate.fps_numerator;
3907
3908 struct v4l2_outputparm oparm;
3909 /*XXX: we're providing timing info as seconds per frame rather than frames
3910 * per second.*/
3911 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3912 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3913
3914 struct v4l2_streamparm sparm;
3915 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3916 sparm.parm.output = oparm;
3917 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3918 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3919 performance might be affected");
3920 ret = OMX_ErrorHardware;
3921 }
3922 client_set_fps = true;
3923 } else {
3924 DEBUG_PRINT_ERROR("Frame rate not supported.");
3925 ret = OMX_ErrorUnsupportedSetting;
3926 }
3927 } else {
3928 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3929 client_set_fps = false;
3930 }
3931 } else {
3932 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3933 (int)config->nPortIndex);
3934 ret = OMX_ErrorBadPortIndex;
3935 }
3936
3937 return ret;
3938 }
3939
3940 return OMX_ErrorNotImplemented;
3941}
3942
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303943#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3944
Arun Menon906de572013-06-18 17:01:40 -07003945/* ======================================================================
3946 FUNCTION
3947 omx_vdec::GetExtensionIndex
3948
3949 DESCRIPTION
3950 OMX GetExtensionIndex method implementaion. <TBD>
3951
3952 PARAMETERS
3953 <TBD>.
3954
3955 RETURN VALUE
3956 OMX Error None if everything successful.
3957
3958 ========================================================================== */
3959OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3960 OMX_IN OMX_STRING paramName,
3961 OMX_OUT OMX_INDEXTYPE* indexType)
3962{
3963 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003964 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003965 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303966 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003967 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303968 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003969 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303970 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3971 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3972 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3973 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003974 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
3975 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08003976 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
3977 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003978 }
3979#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303980 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003981 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303982 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003983 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303984 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003985 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303987 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003988 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3989 }
3990#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303991 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07003992 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3993 }
Praveen Chavancf924182013-12-06 23:16:23 -08003994#if ADAPTIVE_PLAYBACK_SUPPORTED
3995 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
3996 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
3997 }
3998#endif
Arun Menon906de572013-06-18 17:01:40 -07003999 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004000 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004001 return OMX_ErrorNotImplemented;
4002 }
4003 return OMX_ErrorNone;
4004}
4005
4006/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004007 FUNCTION
4008 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004009
Arun Menon906de572013-06-18 17:01:40 -07004010 DESCRIPTION
4011 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004012
Arun Menon906de572013-06-18 17:01:40 -07004013 PARAMETERS
4014 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004015
Arun Menon906de572013-06-18 17:01:40 -07004016 RETURN VALUE
4017 Error None if everything is successful.
4018 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004019OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004020 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004021{
Arun Menon906de572013-06-18 17:01:40 -07004022 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004023 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004024 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004025}
4026
4027/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004028 FUNCTION
4029 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004030
Arun Menon906de572013-06-18 17:01:40 -07004031 DESCRIPTION
4032 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004033
Arun Menon906de572013-06-18 17:01:40 -07004034 PARAMETERS
4035 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004036
Arun Menon906de572013-06-18 17:01:40 -07004037 RETURN VALUE
4038 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004039
Arun Menon906de572013-06-18 17:01:40 -07004040 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004041OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004042 OMX_IN OMX_U32 port,
4043 OMX_IN OMX_HANDLETYPE peerComponent,
4044 OMX_IN OMX_U32 peerPort,
4045 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004046{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004047 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004048 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004049}
4050
4051/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004052 FUNCTION
4053 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004054
Arun Menon906de572013-06-18 17:01:40 -07004055 DESCRIPTION
4056 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004057
Arun Menon906de572013-06-18 17:01:40 -07004058 PARAMETERS
4059 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004060
Arun Menon906de572013-06-18 17:01:40 -07004061 RETURN VALUE
4062 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004063
Arun Menon906de572013-06-18 17:01:40 -07004064 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004065OMX_ERRORTYPE omx_vdec::allocate_extradata()
4066{
4067#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004068 if (drv_ctx.extradata_info.buffer_size) {
4069 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4070 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4071 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4072 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004073 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004074 }
4075 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4076 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4077 drv_ctx.extradata_info.size, 4096,
4078 &drv_ctx.extradata_info.ion.ion_alloc_data,
4079 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4080 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004081 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004082 return OMX_ErrorInsufficientResources;
4083 }
4084 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4085 drv_ctx.extradata_info.size,
4086 PROT_READ|PROT_WRITE, MAP_SHARED,
4087 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4088 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004089 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004090 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4091 free_ion_memory(&drv_ctx.extradata_info.ion);
4092 return OMX_ErrorInsufficientResources;
4093 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004094 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004095#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304096 if (!m_other_extradata) {
4097 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4098 if (!m_other_extradata) {
4099 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4100 return OMX_ErrorInsufficientResources;
4101 }
4102 }
Arun Menon906de572013-06-18 17:01:40 -07004103 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004104}
4105
Arun Menon906de572013-06-18 17:01:40 -07004106void omx_vdec::free_extradata()
4107{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004108#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004109 if (drv_ctx.extradata_info.uaddr) {
4110 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4111 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4112 free_ion_memory(&drv_ctx.extradata_info.ion);
4113 }
4114 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004115#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304116 if (m_other_extradata) {
4117 free(m_other_extradata);
4118 m_other_extradata = NULL;
4119 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004120}
4121
Shalaj Jain273b3e02012-06-22 19:08:03 -07004122OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004123 OMX_IN OMX_HANDLETYPE hComp,
4124 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4125 OMX_IN OMX_U32 port,
4126 OMX_IN OMX_PTR appData,
4127 OMX_IN OMX_U32 bytes,
4128 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004129{
Arun Menon906de572013-06-18 17:01:40 -07004130 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4131 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4132 unsigned i= 0; // Temporary counter
4133 struct vdec_setbuffer_cmd setbuffers;
4134 OMX_PTR privateAppData = NULL;
4135 private_handle_t *handle = NULL;
4136 OMX_U8 *buff = buffer;
4137 struct v4l2_buffer buf;
4138 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4139 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004140
Arun Menon906de572013-06-18 17:01:40 -07004141 if (!m_out_mem_ptr) {
4142 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4143 eRet = allocate_output_headers();
4144 if (eRet == OMX_ErrorNone)
4145 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004146 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004147
Arun Menon906de572013-06-18 17:01:40 -07004148 if (eRet == OMX_ErrorNone) {
4149 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4150 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4151 break;
4152 }
4153 }
4154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004155
Arun Menon906de572013-06-18 17:01:40 -07004156 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004157 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004158 eRet = OMX_ErrorInsufficientResources;
4159 }
4160
Arun Menonbdb80b02013-08-12 17:45:54 -07004161 if (dynamic_buf_mode) {
4162 *bufferHdr = (m_out_mem_ptr + i );
4163 (*bufferHdr)->pBuffer = NULL;
4164 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4165 enum v4l2_buf_type buf_type;
4166 int rr = 0;
4167 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4168 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4169 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4170 return OMX_ErrorInsufficientResources;
4171 } else {
4172 streaming[CAPTURE_PORT] = true;
4173 DEBUG_PRINT_LOW("STREAMON Successful");
4174 }
4175 }
4176 BITMASK_SET(&m_out_bm_count,i);
4177 (*bufferHdr)->pAppPrivate = appData;
4178 (*bufferHdr)->pBuffer = buffer;
4179 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4180 return eRet;
4181 }
Arun Menon906de572013-06-18 17:01:40 -07004182 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004183#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004184 if (m_enable_android_native_buffers) {
4185 if (m_use_android_native_buffers) {
4186 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4187 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4188 handle = (private_handle_t *)nBuf->handle;
4189 privateAppData = params->pAppPrivate;
4190 } else {
4191 handle = (private_handle_t *)buff;
4192 privateAppData = appData;
4193 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004194
Arun Menon906de572013-06-18 17:01:40 -07004195 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4196 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4197 " expected %u, got %lu",
4198 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4199 return OMX_ErrorBadParameter;
4200 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004201
Arun Menon906de572013-06-18 17:01:40 -07004202 if (!m_use_android_native_buffers) {
4203 if (!secure_mode) {
4204 buff = (OMX_U8*)mmap(0, handle->size,
4205 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4206 if (buff == MAP_FAILED) {
4207 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4208 return OMX_ErrorInsufficientResources;
4209 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004210 }
4211 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004212#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004213 native_buffer[i].nativehandle = handle;
4214 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004215#endif
Arun Menon906de572013-06-18 17:01:40 -07004216 if (!handle) {
4217 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4218 return OMX_ErrorBadParameter;
4219 }
4220 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4221 drv_ctx.ptr_outputbuffer[i].offset = 0;
4222 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4223 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4224 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4225 } else
4226#endif
4227
4228 if (!ouput_egl_buffers && !m_use_output_pmem) {
4229#ifdef USE_ION
4230 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4231 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4232 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4233 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4234 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004235 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 -07004236 return OMX_ErrorInsufficientResources;
4237 }
4238 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4239 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4240#else
4241 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4242 open (MEM_DEVICE,O_RDWR);
4243
4244 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004245 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004246 return OMX_ErrorInsufficientResources;
4247 }
4248
4249 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4250 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4251 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4252 open (MEM_DEVICE,O_RDWR);
4253 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004254 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004255 return OMX_ErrorInsufficientResources;
4256 }
4257 }
4258
4259 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4260 drv_ctx.op_buf.buffer_size,
4261 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004262 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004263 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4264 return OMX_ErrorInsufficientResources;
4265 }
4266#endif
4267 if (!secure_mode) {
4268 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4269 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4270 PROT_READ|PROT_WRITE, MAP_SHARED,
4271 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4272 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4273 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4274#ifdef USE_ION
4275 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4276#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004277 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004278 return OMX_ErrorInsufficientResources;
4279 }
4280 }
4281 drv_ctx.ptr_outputbuffer[i].offset = 0;
4282 privateAppData = appData;
4283 } else {
4284
4285 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4286 if (!appData || !bytes ) {
4287 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004288 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004289 return OMX_ErrorBadParameter;
4290 }
4291 }
4292
4293 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4294 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4295 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4296 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4297 !pmem_list->nEntries ||
4298 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004299 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004300 return OMX_ErrorBadParameter;
4301 }
4302 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4303 pmem_list->entryList->entry;
4304 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4305 pmem_info->pmem_fd);
4306 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4307 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4308 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4309 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4310 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4311 privateAppData = appData;
4312 }
4313 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4314 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304315 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4316 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4317 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004318
4319 *bufferHdr = (m_out_mem_ptr + i );
4320 if (secure_mode)
4321 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4322 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4323 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4324 sizeof (vdec_bufferpayload));
4325
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004326 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004327 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4328 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4329
4330 buf.index = i;
4331 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4332 buf.memory = V4L2_MEMORY_USERPTR;
4333 plane[0].length = drv_ctx.op_buf.buffer_size;
4334 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4335 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4336 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4337 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4338 plane[0].data_offset = 0;
4339 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4340 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4341 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4342 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4343#ifdef USE_ION
4344 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4345#endif
4346 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4347 plane[extra_idx].data_offset = 0;
4348 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004349 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004350 return OMX_ErrorBadParameter;
4351 }
Arun Menon906de572013-06-18 17:01:40 -07004352 buf.m.planes = plane;
4353 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004354
Arun Menon906de572013-06-18 17:01:40 -07004355 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004356 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004357 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004358 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004359 }
4360
Arun Menon906de572013-06-18 17:01:40 -07004361 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4362 enum v4l2_buf_type buf_type;
4363 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4364 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4365 return OMX_ErrorInsufficientResources;
4366 } else {
4367 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004368 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369 }
4370 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004371
Arun Menon906de572013-06-18 17:01:40 -07004372 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4373 if (m_enable_android_native_buffers) {
4374 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4375 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4376 } else {
4377 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004378 }
Arun Menon906de572013-06-18 17:01:40 -07004379 (*bufferHdr)->pAppPrivate = privateAppData;
4380 BITMASK_SET(&m_out_bm_count,i);
4381 }
4382 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383}
4384
4385/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004386 FUNCTION
4387 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004388
Arun Menon906de572013-06-18 17:01:40 -07004389 DESCRIPTION
4390 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004391
Arun Menon906de572013-06-18 17:01:40 -07004392 PARAMETERS
4393 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004394
Arun Menon906de572013-06-18 17:01:40 -07004395 RETURN VALUE
4396 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004397
Arun Menon906de572013-06-18 17:01:40 -07004398 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004400 OMX_IN OMX_HANDLETYPE hComp,
4401 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4402 OMX_IN OMX_U32 port,
4403 OMX_IN OMX_PTR appData,
4404 OMX_IN OMX_U32 bytes,
4405 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004406{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004407 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004408 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4409 if (!m_inp_heap_ptr)
4410 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4411 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4412 drv_ctx.ip_buf.actualcount);
4413 if (!m_phdr_pmem_ptr)
4414 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4415 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4416 drv_ctx.ip_buf.actualcount);
4417 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4418 DEBUG_PRINT_ERROR("Insufficent memory");
4419 eRet = OMX_ErrorInsufficientResources;
4420 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4421 input_use_buffer = true;
4422 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4423 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4424 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4425 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4426 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4427 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4428 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4429 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004430 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 -07004431 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4432 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004433 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004434 return OMX_ErrorInsufficientResources;
4435 }
4436 m_in_alloc_cnt++;
4437 } else {
4438 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4439 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004440 }
Arun Menon906de572013-06-18 17:01:40 -07004441 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004442}
4443
4444/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004445 FUNCTION
4446 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004447
Arun Menon906de572013-06-18 17:01:40 -07004448 DESCRIPTION
4449 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004450
Arun Menon906de572013-06-18 17:01:40 -07004451 PARAMETERS
4452 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004453
Arun Menon906de572013-06-18 17:01:40 -07004454 RETURN VALUE
4455 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004456
Arun Menon906de572013-06-18 17:01:40 -07004457 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004458OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004459 OMX_IN OMX_HANDLETYPE hComp,
4460 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4461 OMX_IN OMX_U32 port,
4462 OMX_IN OMX_PTR appData,
4463 OMX_IN OMX_U32 bytes,
4464 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004465{
Arun Menon906de572013-06-18 17:01:40 -07004466 OMX_ERRORTYPE error = OMX_ErrorNone;
4467 struct vdec_setbuffer_cmd setbuffers;
4468
4469 if (bufferHdr == NULL || bytes == 0) {
4470 if (!secure_mode && buffer == NULL) {
4471 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4472 return OMX_ErrorBadParameter;
4473 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004474 }
Arun Menon906de572013-06-18 17:01:40 -07004475 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004476 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004477 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004478 }
Arun Menon906de572013-06-18 17:01:40 -07004479 if (port == OMX_CORE_INPUT_PORT_INDEX)
4480 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4481 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4482 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4483 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004484 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004485 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004486 }
Arun Menon906de572013-06-18 17:01:40 -07004487 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4488 if (error == OMX_ErrorNone) {
4489 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4490 // Send the callback now
4491 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4492 post_event(OMX_CommandStateSet,OMX_StateIdle,
4493 OMX_COMPONENT_GENERATE_EVENT);
4494 }
4495 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4496 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4497 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4498 post_event(OMX_CommandPortEnable,
4499 OMX_CORE_INPUT_PORT_INDEX,
4500 OMX_COMPONENT_GENERATE_EVENT);
4501 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4502 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4503 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4504 post_event(OMX_CommandPortEnable,
4505 OMX_CORE_OUTPUT_PORT_INDEX,
4506 OMX_COMPONENT_GENERATE_EVENT);
4507 }
4508 }
4509 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004510}
4511
4512OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004513 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004514{
Arun Menon906de572013-06-18 17:01:40 -07004515 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4516 if (m_inp_heap_ptr[bufferindex].pBuffer)
4517 free(m_inp_heap_ptr[bufferindex].pBuffer);
4518 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4519 }
4520 if (pmem_bufferHdr)
4521 free_input_buffer(pmem_bufferHdr);
4522 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004523}
4524
4525OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4526{
Arun Menon906de572013-06-18 17:01:40 -07004527 unsigned int index = 0;
4528 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4529 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004530 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004531
Arun Menon906de572013-06-18 17:01:40 -07004532 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004533 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004534
4535 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004536 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004537 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4538 struct vdec_setbuffer_cmd setbuffers;
4539 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4540 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4541 sizeof (vdec_bufferpayload));
4542 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004543 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004544 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004545 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004546 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4547 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4548 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4549 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4550 }
4551 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4552 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4553 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4554 free(m_desc_buffer_ptr[index].buf_addr);
4555 m_desc_buffer_ptr[index].buf_addr = NULL;
4556 m_desc_buffer_ptr[index].desc_data_size = 0;
4557 }
4558#ifdef USE_ION
4559 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4560#endif
4561 }
4562 }
4563
4564 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565}
4566
4567OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4568{
Arun Menon906de572013-06-18 17:01:40 -07004569 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570
Arun Menon906de572013-06-18 17:01:40 -07004571 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4572 return OMX_ErrorBadParameter;
4573 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004574
Arun Menon906de572013-06-18 17:01:40 -07004575 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004576 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577
Arun Menon906de572013-06-18 17:01:40 -07004578 if (index < drv_ctx.op_buf.actualcount
4579 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004580 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004581 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004582
Arun Menon906de572013-06-18 17:01:40 -07004583 struct vdec_setbuffer_cmd setbuffers;
4584 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4585 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4586 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004587
4588 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004589#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004590 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004591 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004592 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4593 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4594 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4595 }
Arun Menon906de572013-06-18 17:01:40 -07004596 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004597 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4598 } else {
4599#endif
4600 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4601 if (!secure_mode) {
4602 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4603 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4604 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4605 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4606 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4607 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4608 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4609 }
4610 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4611 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004613 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004614#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004615 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004616#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004617 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004618#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004619 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004620 if (release_output_done()) {
4621 free_extradata();
4622 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004623 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624
Arun Menon906de572013-06-18 17:01:40 -07004625 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004626
4627}
4628
4629OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004630 OMX_BUFFERHEADERTYPE **bufferHdr,
4631 OMX_U32 port,
4632 OMX_PTR appData,
4633 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004634{
Arun Menon906de572013-06-18 17:01:40 -07004635 OMX_BUFFERHEADERTYPE *input = NULL;
4636 unsigned char *buf_addr = NULL;
4637 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4638 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004639
Arun Menon906de572013-06-18 17:01:40 -07004640 /* Sanity Check*/
4641 if (bufferHdr == NULL) {
4642 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004643 }
4644
Arun Menon906de572013-06-18 17:01:40 -07004645 if (m_inp_heap_ptr == NULL) {
4646 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4647 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4648 drv_ctx.ip_buf.actualcount);
4649 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4650 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4651 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004652
Arun Menon906de572013-06-18 17:01:40 -07004653 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004654 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004655 return OMX_ErrorInsufficientResources;
4656 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004658
Arun Menon906de572013-06-18 17:01:40 -07004659 /*Find a Free index*/
4660 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4661 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004662 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004663 break;
4664 }
4665 }
4666
4667 if (i < drv_ctx.ip_buf.actualcount) {
4668 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4669
4670 if (buf_addr == NULL) {
4671 return OMX_ErrorInsufficientResources;
4672 }
4673
4674 *bufferHdr = (m_inp_heap_ptr + i);
4675 input = *bufferHdr;
4676 BITMASK_SET(&m_heap_inp_bm_count,i);
4677
4678 input->pBuffer = (OMX_U8 *)buf_addr;
4679 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4680 input->nVersion.nVersion = OMX_SPEC_VERSION;
4681 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4682 input->pAppPrivate = appData;
4683 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004684 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004685 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004686 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004687 /*Add the Buffers to freeq*/
4688 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4689 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004690 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004691 return OMX_ErrorInsufficientResources;
4692 }
4693 } else {
4694 return OMX_ErrorBadParameter;
4695 }
4696
4697 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004698
4699}
4700
4701
4702/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004703 FUNCTION
4704 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705
Arun Menon906de572013-06-18 17:01:40 -07004706 DESCRIPTION
4707 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004708
Arun Menon906de572013-06-18 17:01:40 -07004709 PARAMETERS
4710 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004711
Arun Menon906de572013-06-18 17:01:40 -07004712 RETURN VALUE
4713 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004714
Arun Menon906de572013-06-18 17:01:40 -07004715 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004716OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004717 OMX_IN OMX_HANDLETYPE hComp,
4718 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4719 OMX_IN OMX_U32 port,
4720 OMX_IN OMX_PTR appData,
4721 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004722{
4723
Arun Menon906de572013-06-18 17:01:40 -07004724 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4725 struct vdec_setbuffer_cmd setbuffers;
4726 OMX_BUFFERHEADERTYPE *input = NULL;
4727 unsigned i = 0;
4728 unsigned char *buf_addr = NULL;
4729 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004730
Arun Menon906de572013-06-18 17:01:40 -07004731 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004732 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004733 bytes, drv_ctx.ip_buf.buffer_size);
4734 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004735 }
4736
Arun Menon906de572013-06-18 17:01:40 -07004737 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004738 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004739 drv_ctx.ip_buf.actualcount,
4740 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004741
Arun Menon906de572013-06-18 17:01:40 -07004742 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4743 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4744
4745 if (m_inp_mem_ptr == NULL) {
4746 return OMX_ErrorInsufficientResources;
4747 }
4748
4749 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4750 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4751
4752 if (drv_ctx.ptr_inputbuffer == NULL) {
4753 return OMX_ErrorInsufficientResources;
4754 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004755#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004756 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4757 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004758
Arun Menon906de572013-06-18 17:01:40 -07004759 if (drv_ctx.ip_buf_ion_info == NULL) {
4760 return OMX_ErrorInsufficientResources;
4761 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004762#endif
4763
Arun Menon906de572013-06-18 17:01:40 -07004764 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4765 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004766#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004767 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004768#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769 }
4770 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004771
Arun Menon906de572013-06-18 17:01:40 -07004772 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4773 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004774 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004775 break;
4776 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004777 }
Arun Menon906de572013-06-18 17:01:40 -07004778
4779 if (i < drv_ctx.ip_buf.actualcount) {
4780 struct v4l2_buffer buf;
4781 struct v4l2_plane plane;
4782 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004783 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004784#ifdef USE_ION
4785 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4786 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4787 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4788 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4789 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4790 return OMX_ErrorInsufficientResources;
4791 }
4792 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4793#else
4794 pmem_fd = open (MEM_DEVICE,O_RDWR);
4795
4796 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004797 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004798 return OMX_ErrorInsufficientResources;
4799 }
4800
4801 if (pmem_fd == 0) {
4802 pmem_fd = open (MEM_DEVICE,O_RDWR);
4803
4804 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004805 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004806 return OMX_ErrorInsufficientResources;
4807 }
4808 }
4809
4810 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4811 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004812 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004813 close(pmem_fd);
4814 return OMX_ErrorInsufficientResources;
4815 }
4816#endif
4817 if (!secure_mode) {
4818 buf_addr = (unsigned char *)mmap(NULL,
4819 drv_ctx.ip_buf.buffer_size,
4820 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4821
4822 if (buf_addr == MAP_FAILED) {
4823 close(pmem_fd);
4824#ifdef USE_ION
4825 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4826#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004827 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004828 return OMX_ErrorInsufficientResources;
4829 }
4830 }
4831 *bufferHdr = (m_inp_mem_ptr + i);
4832 if (secure_mode)
4833 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4834 else
4835 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4836 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4837 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4838 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4839 drv_ctx.ptr_inputbuffer [i].offset = 0;
4840
4841
4842 buf.index = i;
4843 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4844 buf.memory = V4L2_MEMORY_USERPTR;
4845 plane.bytesused = 0;
4846 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4847 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4848 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4849 plane.reserved[1] = 0;
4850 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4851 buf.m.planes = &plane;
4852 buf.length = 1;
4853
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004854 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004855 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4856
4857 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4858
4859 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004860 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004861 /*TODO: How to handle this case */
4862 return OMX_ErrorInsufficientResources;
4863 }
4864
4865 input = *bufferHdr;
4866 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004867 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004868 if (secure_mode)
4869 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4870 else
4871 input->pBuffer = (OMX_U8 *)buf_addr;
4872 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4873 input->nVersion.nVersion = OMX_SPEC_VERSION;
4874 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4875 input->pAppPrivate = appData;
4876 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4877 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4878
4879 if (drv_ctx.disable_dmx) {
4880 eRet = allocate_desc_buffer(i);
4881 }
4882 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004883 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004884 eRet = OMX_ErrorInsufficientResources;
4885 }
4886 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004887}
4888
4889
4890/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004891 FUNCTION
4892 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004893
Arun Menon906de572013-06-18 17:01:40 -07004894 DESCRIPTION
4895 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004896
Arun Menon906de572013-06-18 17:01:40 -07004897 PARAMETERS
4898 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004899
Arun Menon906de572013-06-18 17:01:40 -07004900 RETURN VALUE
4901 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004902
Arun Menon906de572013-06-18 17:01:40 -07004903 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004905 OMX_IN OMX_HANDLETYPE hComp,
4906 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4907 OMX_IN OMX_U32 port,
4908 OMX_IN OMX_PTR appData,
4909 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910{
Arun Menon906de572013-06-18 17:01:40 -07004911 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4912 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4913 unsigned i= 0; // Temporary counter
4914 struct vdec_setbuffer_cmd setbuffers;
4915 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004916#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004917 int ion_device_fd =-1;
4918 struct ion_allocation_data ion_alloc_data;
4919 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004920#endif
Arun Menon906de572013-06-18 17:01:40 -07004921 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004922 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004923 drv_ctx.op_buf.actualcount,
4924 drv_ctx.op_buf.buffer_size);
4925 int nBufHdrSize = 0;
4926 int nPlatformEntrySize = 0;
4927 int nPlatformListSize = 0;
4928 int nPMEMInfoSize = 0;
4929 int pmem_fd = -1;
4930 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004931
Arun Menon906de572013-06-18 17:01:40 -07004932 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4933 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4934 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004935
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004936 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004937 drv_ctx.op_buf.actualcount);
4938 nBufHdrSize = drv_ctx.op_buf.actualcount *
4939 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004940
Arun Menon906de572013-06-18 17:01:40 -07004941 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4942 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4943 nPlatformListSize = drv_ctx.op_buf.actualcount *
4944 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4945 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4946 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004947
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004948 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004949 sizeof(OMX_BUFFERHEADERTYPE),
4950 nPMEMInfoSize,
4951 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004952 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004953 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004954#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004955 ion_device_fd = alloc_map_ion_memory(
4956 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4957 drv_ctx.op_buf.alignment,
4958 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4959 if (ion_device_fd < 0) {
4960 return OMX_ErrorInsufficientResources;
4961 }
4962 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963#else
Arun Menon906de572013-06-18 17:01:40 -07004964 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004965
Arun Menon906de572013-06-18 17:01:40 -07004966 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004967 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004968 drv_ctx.op_buf.buffer_size);
4969 return OMX_ErrorInsufficientResources;
4970 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004971
Arun Menon906de572013-06-18 17:01:40 -07004972 if (pmem_fd == 0) {
4973 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004974
Arun Menon906de572013-06-18 17:01:40 -07004975 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004976 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004977 drv_ctx.op_buf.buffer_size);
4978 return OMX_ErrorInsufficientResources;
4979 }
4980 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004981
Arun Menon906de572013-06-18 17:01:40 -07004982 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4983 drv_ctx.op_buf.actualcount,
4984 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004985 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004986 close(pmem_fd);
4987 return OMX_ErrorInsufficientResources;
4988 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989#endif
Arun Menon906de572013-06-18 17:01:40 -07004990 if (!secure_mode) {
4991 pmem_baseaddress = (unsigned char *)mmap(NULL,
4992 (drv_ctx.op_buf.buffer_size *
4993 drv_ctx.op_buf.actualcount),
4994 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4995 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004996 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07004997 drv_ctx.op_buf.buffer_size);
4998 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004999#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005000 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005001#endif
Arun Menon906de572013-06-18 17:01:40 -07005002 return OMX_ErrorInsufficientResources;
5003 }
5004 }
5005 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5006 // Alloc mem for platform specific info
5007 char *pPtr=NULL;
5008 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5009 nPMEMInfoSize,1);
5010 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5011 calloc (sizeof(struct vdec_bufferpayload),
5012 drv_ctx.op_buf.actualcount);
5013 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5014 calloc (sizeof (struct vdec_output_frameinfo),
5015 drv_ctx.op_buf.actualcount);
5016#ifdef USE_ION
5017 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5018 calloc (sizeof(struct vdec_ion),
5019 drv_ctx.op_buf.actualcount);
5020#endif
5021
5022 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5023 && drv_ctx.ptr_respbuffer) {
5024 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5025 (drv_ctx.op_buf.buffer_size *
5026 drv_ctx.op_buf.actualcount);
5027 bufHdr = m_out_mem_ptr;
5028 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5029 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5030 (((char *) m_platform_list) + nPlatformListSize);
5031 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5032 (((char *) m_platform_entry) + nPlatformEntrySize);
5033 pPlatformList = m_platform_list;
5034 pPlatformEntry = m_platform_entry;
5035 pPMEMInfo = m_pmem_info;
5036
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005037 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005038
5039 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005040 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5041 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005042 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5043 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5044 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5045 // Set the values when we determine the right HxW param
5046 bufHdr->nAllocLen = bytes;
5047 bufHdr->nFilledLen = 0;
5048 bufHdr->pAppPrivate = appData;
5049 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5050 // Platform specific PMEM Information
5051 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005052 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005053 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5054 pPlatformEntry->entry = pPMEMInfo;
5055 // Initialize the Platform List
5056 pPlatformList->nEntries = 1;
5057 pPlatformList->entryList = pPlatformEntry;
5058 // Keep pBuffer NULL till vdec is opened
5059 bufHdr->pBuffer = NULL;
5060 bufHdr->nOffset = 0;
5061
5062 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5063 pPMEMInfo->pmem_fd = 0;
5064 bufHdr->pPlatformPrivate = pPlatformList;
5065
5066 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5067 m_pmem_info[i].pmem_fd = pmem_fd;
5068#ifdef USE_ION
5069 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5070 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5071 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5072#endif
5073
5074 /*Create a mapping between buffers*/
5075 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5076 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5077 &drv_ctx.ptr_outputbuffer[i];
5078 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5079 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5080 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305081 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5082 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5083 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005084
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005085 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005086 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5087 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5088 // Move the buffer and buffer header pointers
5089 bufHdr++;
5090 pPMEMInfo++;
5091 pPlatformEntry++;
5092 pPlatformList++;
5093 }
5094 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005095 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005096 m_out_mem_ptr, pPtr);
5097 if (m_out_mem_ptr) {
5098 free(m_out_mem_ptr);
5099 m_out_mem_ptr = NULL;
5100 }
5101 if (pPtr) {
5102 free(pPtr);
5103 pPtr = NULL;
5104 }
5105 if (drv_ctx.ptr_outputbuffer) {
5106 free(drv_ctx.ptr_outputbuffer);
5107 drv_ctx.ptr_outputbuffer = NULL;
5108 }
5109 if (drv_ctx.ptr_respbuffer) {
5110 free(drv_ctx.ptr_respbuffer);
5111 drv_ctx.ptr_respbuffer = NULL;
5112 }
5113#ifdef USE_ION
5114 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005115 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005116 free(drv_ctx.op_buf_ion_info);
5117 drv_ctx.op_buf_ion_info = NULL;
5118 }
5119#endif
5120 eRet = OMX_ErrorInsufficientResources;
5121 }
5122 if (eRet == OMX_ErrorNone)
5123 eRet = allocate_extradata();
5124 }
5125
5126 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5127 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005128 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005129 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005130 }
5131 }
Arun Menon906de572013-06-18 17:01:40 -07005132
5133 if (eRet == OMX_ErrorNone) {
5134 if (i < drv_ctx.op_buf.actualcount) {
5135 struct v4l2_buffer buf;
5136 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5137 int rc;
5138 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5139
5140 drv_ctx.ptr_outputbuffer[i].buffer_len =
5141 drv_ctx.op_buf.buffer_size;
5142
5143 *bufferHdr = (m_out_mem_ptr + i );
5144 if (secure_mode) {
5145 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5146 }
5147 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5148
5149 buf.index = i;
5150 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5151 buf.memory = V4L2_MEMORY_USERPTR;
5152 plane[0].length = drv_ctx.op_buf.buffer_size;
5153 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5154 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005155#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005156 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005157#endif
Arun Menon906de572013-06-18 17:01:40 -07005158 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5159 plane[0].data_offset = 0;
5160 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5161 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5162 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5163 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 -07005164#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005165 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005166#endif
Arun Menon906de572013-06-18 17:01:40 -07005167 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5168 plane[extra_idx].data_offset = 0;
5169 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005170 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005171 return OMX_ErrorBadParameter;
5172 }
5173 buf.m.planes = plane;
5174 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005175 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 -07005176 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5177 if (rc) {
5178 /*TODO: How to handle this case */
5179 return OMX_ErrorInsufficientResources;
5180 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005181
Arun Menon906de572013-06-18 17:01:40 -07005182 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5183 enum v4l2_buf_type buf_type;
5184 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5185 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5186 if (rc) {
5187 return OMX_ErrorInsufficientResources;
5188 } else {
5189 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005190 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005191 }
5192 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005193
Arun Menon906de572013-06-18 17:01:40 -07005194 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5195 (*bufferHdr)->pAppPrivate = appData;
5196 BITMASK_SET(&m_out_bm_count,i);
5197 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005198 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005199 eRet = OMX_ErrorInsufficientResources;
5200 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005202
Arun Menon906de572013-06-18 17:01:40 -07005203 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204}
5205
5206
5207// AllocateBuffer -- API Call
5208/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005209 FUNCTION
5210 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211
Arun Menon906de572013-06-18 17:01:40 -07005212 DESCRIPTION
5213 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005214
Arun Menon906de572013-06-18 17:01:40 -07005215 PARAMETERS
5216 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005217
Arun Menon906de572013-06-18 17:01:40 -07005218 RETURN VALUE
5219 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005220
Arun Menon906de572013-06-18 17:01:40 -07005221 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005222OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005223 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5224 OMX_IN OMX_U32 port,
5225 OMX_IN OMX_PTR appData,
5226 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005227{
5228 unsigned i = 0;
5229 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5230
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005231 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005232 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005233 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005234 return OMX_ErrorInvalidState;
5235 }
5236
Arun Menon906de572013-06-18 17:01:40 -07005237 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5238 if (arbitrary_bytes) {
5239 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5240 } else {
5241 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5242 }
5243 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005244 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5245 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005246 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005247 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005248 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249 }
5250 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005251 if (eRet == OMX_ErrorNone) {
5252 if (allocate_done()) {
5253 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005254 // Send the callback now
5255 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5256 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005257 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005258 }
5259 }
Arun Menon906de572013-06-18 17:01:40 -07005260 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5261 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5262 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5263 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264 OMX_CORE_INPUT_PORT_INDEX,
5265 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005266 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267 }
Arun Menon906de572013-06-18 17:01:40 -07005268 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5269 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5270 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005271 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005272 OMX_CORE_OUTPUT_PORT_INDEX,
5273 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005274 }
5275 }
5276 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005277 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005278 return eRet;
5279}
5280
5281// Free Buffer - API call
5282/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005283 FUNCTION
5284 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005285
Arun Menon906de572013-06-18 17:01:40 -07005286 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005287
Arun Menon906de572013-06-18 17:01:40 -07005288 PARAMETERS
5289 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005290
Arun Menon906de572013-06-18 17:01:40 -07005291 RETURN VALUE
5292 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005293
Arun Menon906de572013-06-18 17:01:40 -07005294 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005295OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005296 OMX_IN OMX_U32 port,
5297 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298{
5299 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5300 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005301 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302
Arun Menon906de572013-06-18 17:01:40 -07005303 if (m_state == OMX_StateIdle &&
5304 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005305 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005306 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5307 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005308 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005309 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5310 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5311 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5312 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005313 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005314 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005315 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005316 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005317 OMX_ErrorPortUnpopulated,
5318 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005319
5320 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005321 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005322 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005323 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005324 OMX_ErrorPortUnpopulated,
5325 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005326 }
5327
Arun Menon906de572013-06-18 17:01:40 -07005328 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5329 /*Check if arbitrary bytes*/
5330 if (!arbitrary_bytes && !input_use_buffer)
5331 nPortIndex = buffer - m_inp_mem_ptr;
5332 else
5333 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005334
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005335 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005336 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5337 // Clear the bit associated with it.
5338 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5339 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5340 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005341
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005342 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005343 if (m_phdr_pmem_ptr)
5344 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5345 } else {
5346 if (arbitrary_bytes) {
5347 if (m_phdr_pmem_ptr)
5348 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5349 else
5350 free_input_buffer(nPortIndex,NULL);
5351 } else
5352 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005353 }
Arun Menon906de572013-06-18 17:01:40 -07005354 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305355 if(release_input_done())
5356 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005357 /*Free the Buffer Header*/
5358 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005359 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005360 free_input_buffer_header();
5361 }
5362 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005363 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005364 eRet = OMX_ErrorBadPortIndex;
5365 }
5366
Arun Menon906de572013-06-18 17:01:40 -07005367 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5368 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005369 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005370 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5371 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005372 OMX_CORE_INPUT_PORT_INDEX,
5373 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005374 }
Arun Menon906de572013-06-18 17:01:40 -07005375 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005376 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005377 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005378 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005379 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005380 // Clear the bit associated with it.
5381 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5382 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005383 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005384
Surajit Podder12aefac2013-08-06 18:43:32 +05305385 if(release_output_done()) {
5386 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5387 }
Arun Menon906de572013-06-18 17:01:40 -07005388 if (release_output_done()) {
5389 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005390 }
Arun Menon906de572013-06-18 17:01:40 -07005391 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005392 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393 eRet = OMX_ErrorBadPortIndex;
5394 }
Arun Menon906de572013-06-18 17:01:40 -07005395 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5396 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005397 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005398
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005399 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005400 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005402 if (m_enable_android_native_buffers) {
5403 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5404 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005406#endif
5407
Arun Menon906de572013-06-18 17:01:40 -07005408 post_event(OMX_CommandPortDisable,
5409 OMX_CORE_OUTPUT_PORT_INDEX,
5410 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411 }
Arun Menon906de572013-06-18 17:01:40 -07005412 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005413 eRet = OMX_ErrorBadPortIndex;
5414 }
Arun Menon906de572013-06-18 17:01:40 -07005415 if ((eRet == OMX_ErrorNone) &&
5416 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5417 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005418 // Send the callback now
5419 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5420 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005421 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005422 }
5423 }
5424 return eRet;
5425}
5426
5427
5428/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005429 FUNCTION
5430 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 DESCRIPTION
5433 This routine is used to push the encoded video frames to
5434 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005435
Arun Menon906de572013-06-18 17:01:40 -07005436 PARAMETERS
5437 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005438
Arun Menon906de572013-06-18 17:01:40 -07005439 RETURN VALUE
5440 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005441
Arun Menon906de572013-06-18 17:01:40 -07005442 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005443OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005444 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005445{
Arun Menon906de572013-06-18 17:01:40 -07005446 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5447 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005448
Arun Menon906de572013-06-18 17:01:40 -07005449 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005450 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005451 return OMX_ErrorInvalidState;
5452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453
Arun Menon906de572013-06-18 17:01:40 -07005454 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005455 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005456 return OMX_ErrorBadParameter;
5457 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458
Arun Menon906de572013-06-18 17:01:40 -07005459 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005460 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005461 return OMX_ErrorIncorrectStateOperation;
5462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463
Arun Menon906de572013-06-18 17:01:40 -07005464 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005465 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005466 return OMX_ErrorBadPortIndex;
5467 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468
5469#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005470 if (iDivXDrmDecrypt) {
5471 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5472 if (drmErr != OMX_ErrorNone) {
5473 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005474 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005477#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005478 if (perf_flag) {
5479 if (!latency) {
5480 dec_time.stop();
5481 latency = dec_time.processing_time_us();
5482 dec_time.start();
5483 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 if (arbitrary_bytes) {
5487 nBufferIndex = buffer - m_inp_heap_ptr;
5488 } else {
5489 if (input_use_buffer == true) {
5490 nBufferIndex = buffer - m_inp_heap_ptr;
5491 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5492 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5493 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5494 buffer = &m_inp_mem_ptr[nBufferIndex];
5495 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5496 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5497 } else {
5498 nBufferIndex = buffer - m_inp_mem_ptr;
5499 }
5500 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005501
Arun Menon906de572013-06-18 17:01:40 -07005502 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005503 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005504 return OMX_ErrorBadParameter;
5505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005506
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005507 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5508 codec_config_flag = true;
5509 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5510 }
5511
Arun Menon906de572013-06-18 17:01:40 -07005512 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5513 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5514 if (arbitrary_bytes) {
5515 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005517 } else {
Arun Menon906de572013-06-18 17:01:40 -07005518 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5519 }
5520 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005521}
5522
5523/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005524 FUNCTION
5525 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005526
Arun Menon906de572013-06-18 17:01:40 -07005527 DESCRIPTION
5528 This routine is used to push the encoded video frames to
5529 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005530
Arun Menon906de572013-06-18 17:01:40 -07005531 PARAMETERS
5532 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533
Arun Menon906de572013-06-18 17:01:40 -07005534 RETURN VALUE
5535 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536
Arun Menon906de572013-06-18 17:01:40 -07005537 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005538OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005539 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540{
Arun Menon906de572013-06-18 17:01:40 -07005541 int push_cnt = 0,i=0;
5542 unsigned nPortIndex = 0;
5543 OMX_ERRORTYPE ret = OMX_ErrorNone;
5544 struct vdec_input_frameinfo frameinfo;
5545 struct vdec_bufferpayload *temp_buffer;
5546 struct vdec_seqheader seq_header;
5547 bool port_setting_changed = true;
5548 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549
Arun Menon906de572013-06-18 17:01:40 -07005550 /*Should we generate a Aync error event*/
5551 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005552 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005553 return OMX_ErrorBadParameter;
5554 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005555
Arun Menon906de572013-06-18 17:01:40 -07005556 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005557
Arun Menon906de572013-06-18 17:01:40 -07005558 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005559 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005560 nPortIndex);
5561 return OMX_ErrorBadParameter;
5562 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005563
Arun Menon906de572013-06-18 17:01:40 -07005564 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005565
Arun Menon906de572013-06-18 17:01:40 -07005566 /* return zero length and not an EOS buffer */
5567 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5568 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005569 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005570 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5571 OMX_COMPONENT_GENERATE_EBD);
5572 return OMX_ErrorNone;
5573 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005574
5575
Arun Menon906de572013-06-18 17:01:40 -07005576 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5577 mp4StreamType psBits;
5578 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5579 psBits.numBytes = buffer->nFilledLen;
5580 mp4_headerparser.parseHeader(&psBits);
5581 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5582 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5583 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005584 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005585 buffer->nFilledLen,frame_count);
5586 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005587 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005588 not_coded_vop = false;
5589 buffer->nFilledLen = 0;
5590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591 }
5592 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005593
Arun Menon906de572013-06-18 17:01:40 -07005594 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005595
Arun Menon906de572013-06-18 17:01:40 -07005596 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005597
Arun Menon906de572013-06-18 17:01:40 -07005598 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005599 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005600 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5601 OMX_COMPONENT_GENERATE_EBD);
5602 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005603 }
5604
Arun Menon906de572013-06-18 17:01:40 -07005605 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005606
Surajit Podderd2644d52013-08-28 17:59:06 +05305607 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005608 return OMX_ErrorBadParameter;
5609 }
5610 /* If its first frame, H264 codec and reject is true, then parse the nal
5611 and get the profile. Based on this, reject the clip playback */
5612 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5613 m_reject_avc_1080p_mp) {
5614 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005615 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005616 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5617 NALU_TYPE_SPS);
5618 m_profile = h264_parser->get_profile();
5619 ret = is_video_session_supported();
5620 if (ret) {
5621 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5622 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5623 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5624 m_state = OMX_StateInvalid;
5625 return OMX_ErrorNone;
5626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005627 }
5628
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005629 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005630 /*for use buffer we need to memcpy the data*/
5631 temp_buffer->buffer_len = buffer->nFilledLen;
5632
5633 if (input_use_buffer) {
5634 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5635 if (arbitrary_bytes) {
5636 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5637 } else {
5638 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5639 buffer->nFilledLen);
5640 }
5641 } else {
5642 return OMX_ErrorBadParameter;
5643 }
5644
5645 }
5646
5647 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5648 frameinfo.client_data = (void *) buffer;
5649 frameinfo.datalen = temp_buffer->buffer_len;
5650 frameinfo.flags = 0;
5651 frameinfo.offset = buffer->nOffset;
5652 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5653 frameinfo.pmem_offset = temp_buffer->offset;
5654 frameinfo.timestamp = buffer->nTimeStamp;
5655 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5656 DEBUG_PRINT_LOW("ETB: dmx enabled");
5657 if (m_demux_entries == 0) {
5658 extract_demux_addr_offsets(buffer);
5659 }
5660
5661 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5662 handle_demux_data(buffer);
5663 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5664 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5665 } else {
5666 frameinfo.desc_addr = NULL;
5667 frameinfo.desc_size = 0;
5668 }
5669 if (!arbitrary_bytes) {
5670 frameinfo.flags |= buffer->nFlags;
5671 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005672
5673#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005674 if (m_debug_timestamp) {
5675 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005676 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005677 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5678 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005679 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005680 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5681 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005682 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005683#endif
5684
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005685log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005686
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005687if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005688 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5689 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5690 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691
Arun Menon906de572013-06-18 17:01:40 -07005692 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005693 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005694 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5695 h264_scratch.nFilledLen = 0;
5696 nal_count = 0;
5697 look_ahead_nal = false;
5698 frame_count = 0;
5699 if (m_frame_parser.mutils)
5700 m_frame_parser.mutils->initialize_frame_checking_environment();
5701 m_frame_parser.flush();
5702 h264_last_au_ts = LLONG_MAX;
5703 h264_last_au_flags = 0;
5704 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5705 m_demux_entries = 0;
5706 }
5707 struct v4l2_buffer buf;
5708 struct v4l2_plane plane;
5709 memset( (void *)&buf, 0, sizeof(buf));
5710 memset( (void *)&plane, 0, sizeof(plane));
5711 int rc;
5712 unsigned long print_count;
5713 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005714 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005715 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005716 }
5717 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5718 buf.index = nPortIndex;
5719 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5720 buf.memory = V4L2_MEMORY_USERPTR;
5721 plane.bytesused = temp_buffer->buffer_len;
5722 plane.length = drv_ctx.ip_buf.buffer_size;
5723 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5724 (unsigned long)temp_buffer->offset;
5725 plane.reserved[0] = temp_buffer->pmem_fd;
5726 plane.reserved[1] = temp_buffer->offset;
5727 plane.data_offset = 0;
5728 buf.m.planes = &plane;
5729 buf.length = 1;
5730 if (frameinfo.timestamp >= LLONG_MAX) {
5731 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5732 }
5733 //assumption is that timestamp is in milliseconds
5734 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5735 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5736 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5737 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5740 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005741 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005742 return OMX_ErrorHardware;
5743 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005744 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5745 codec_config_flag = false;
5746 }
Arun Menon906de572013-06-18 17:01:40 -07005747 if (!streaming[OUTPUT_PORT]) {
5748 enum v4l2_buf_type buf_type;
5749 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005750
Arun Menon906de572013-06-18 17:01:40 -07005751 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005752 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005753 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5754 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005755 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005756 streaming[OUTPUT_PORT] = true;
5757 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005758 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005759 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5760 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5761 OMX_COMPONENT_GENERATE_EBD);
5762 return OMX_ErrorBadParameter;
5763 }
5764 }
5765 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5766 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5767 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768
Arun Menon906de572013-06-18 17:01:40 -07005769 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770}
5771
5772/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005773 FUNCTION
5774 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005775
Arun Menon906de572013-06-18 17:01:40 -07005776 DESCRIPTION
5777 IL client uses this method to release the frame buffer
5778 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779
Arun Menon906de572013-06-18 17:01:40 -07005780 PARAMETERS
5781 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005782
Arun Menon906de572013-06-18 17:01:40 -07005783 RETURN VALUE
5784 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785
Arun Menon906de572013-06-18 17:01:40 -07005786 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005788 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005789{
Arun Menonbdb80b02013-08-12 17:45:54 -07005790 if (dynamic_buf_mode) {
5791 private_handle_t *handle = NULL;
5792 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005793 unsigned int nPortIndex = 0;
5794
5795 if (!buffer || !buffer->pBuffer) {
5796 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5797 return OMX_ErrorBadParameter;
5798 }
5799
5800 //get the buffer type and fd info
5801 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5802 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005803 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5804
5805 if (!handle) {
5806 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5807 return OMX_ErrorBadParameter;
5808 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005809 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5810 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5811 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005812 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005813
5814 //Store private handle from GraphicBuffer
5815 native_buffer[nPortIndex].privatehandle = handle;
5816 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818
Arun Menon906de572013-06-18 17:01:40 -07005819 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005820 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005821 return OMX_ErrorInvalidState;
5822 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005823
Arun Menon906de572013-06-18 17:01:40 -07005824 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005825 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005826 return OMX_ErrorIncorrectStateOperation;
5827 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828
Arun Menon906de572013-06-18 17:01:40 -07005829 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305830 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005831 return OMX_ErrorBadParameter;
5832 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005833
Arun Menon906de572013-06-18 17:01:40 -07005834 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005835 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005836 return OMX_ErrorBadPortIndex;
5837 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005838
Arun Menon906de572013-06-18 17:01:40 -07005839 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5840 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5841 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005842}
5843/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005844 FUNCTION
5845 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005846
Arun Menon906de572013-06-18 17:01:40 -07005847 DESCRIPTION
5848 IL client uses this method to release the frame buffer
5849 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005850
Arun Menon906de572013-06-18 17:01:40 -07005851 PARAMETERS
5852 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005853
Arun Menon906de572013-06-18 17:01:40 -07005854 RETURN VALUE
5855 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005856
Arun Menon906de572013-06-18 17:01:40 -07005857 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005858OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005859 OMX_IN OMX_HANDLETYPE hComp,
5860 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005861{
Arun Menon906de572013-06-18 17:01:40 -07005862 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5863 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5864 unsigned nPortIndex = 0;
5865 struct vdec_fillbuffer_cmd fillbuffer;
5866 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5867 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005868
Arun Menon906de572013-06-18 17:01:40 -07005869 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005870
Arun Menon906de572013-06-18 17:01:40 -07005871 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5872 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005873
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005874 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005875 bufferAdd, bufferAdd->pBuffer);
5876 /*Return back the output buffer to client*/
5877 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005878 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005879 buffer->nFilledLen = 0;
5880 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5881 return OMX_ErrorNone;
5882 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005883
5884 if (dynamic_buf_mode) {
5885 //map the buffer handle based on the size set on output port definition.
5886 if (!secure_mode) {
5887 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5888 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5889 PROT_READ|PROT_WRITE, MAP_SHARED,
5890 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5891 }
5892 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5893 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5894 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5895 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5896 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5897 }
5898
Arun Menon906de572013-06-18 17:01:40 -07005899 pending_output_buffers++;
5900 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5901 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5902 if (ptr_respbuffer) {
5903 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5904 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905
Arun Menon906de572013-06-18 17:01:40 -07005906 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5907 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5908 buffer->nFilledLen = 0;
5909 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5910 pending_output_buffers--;
5911 return OMX_ErrorBadParameter;
5912 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913
Arun Menon906de572013-06-18 17:01:40 -07005914 int rc = 0;
5915 struct v4l2_buffer buf;
5916 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5917 memset( (void *)&buf, 0, sizeof(buf));
5918 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5919 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005920
Arun Menon906de572013-06-18 17:01:40 -07005921 buf.index = nPortIndex;
5922 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5923 buf.memory = V4L2_MEMORY_USERPTR;
5924 plane[0].bytesused = buffer->nFilledLen;
5925 plane[0].length = drv_ctx.op_buf.buffer_size;
5926 plane[0].m.userptr =
5927 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5928 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5929 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5930 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5931 plane[0].data_offset = 0;
5932 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5933 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5934 plane[extra_idx].bytesused = 0;
5935 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5936 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 -07005937#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005938 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005939#endif
Arun Menon906de572013-06-18 17:01:40 -07005940 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5941 plane[extra_idx].data_offset = 0;
5942 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005943 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005944 return OMX_ErrorBadParameter;
5945 }
5946 buf.m.planes = plane;
5947 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005948 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005949 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5950
Arun Menon906de572013-06-18 17:01:40 -07005951 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5952 if (rc) {
5953 /*TODO: How to handle this case */
5954 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5955 }
Arun Menon906de572013-06-18 17:01:40 -07005956return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005957}
5958
5959/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005960 FUNCTION
5961 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005962
Arun Menon906de572013-06-18 17:01:40 -07005963 DESCRIPTION
5964 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005965
Arun Menon906de572013-06-18 17:01:40 -07005966 PARAMETERS
5967 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005968
Arun Menon906de572013-06-18 17:01:40 -07005969 RETURN VALUE
5970 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005971
Arun Menon906de572013-06-18 17:01:40 -07005972 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005973OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005974 OMX_IN OMX_CALLBACKTYPE* callbacks,
5975 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005976{
5977
Arun Menon906de572013-06-18 17:01:40 -07005978 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005979 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005980 m_cb.EventHandler,m_cb.FillBufferDone);
5981 m_app_data = appData;
5982 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005983}
5984
5985/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005986 FUNCTION
5987 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005988
Arun Menon906de572013-06-18 17:01:40 -07005989 DESCRIPTION
5990 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005991
Arun Menon906de572013-06-18 17:01:40 -07005992 PARAMETERS
5993 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005994
Arun Menon906de572013-06-18 17:01:40 -07005995 RETURN VALUE
5996 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997
Arun Menon906de572013-06-18 17:01:40 -07005998 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005999OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6000{
6001#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006002 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006003 delete iDivXDrmDecrypt;
6004 iDivXDrmDecrypt=NULL;
6005 }
6006#endif //_ANDROID_
6007
Shalaj Jain286b0062013-02-21 20:35:48 -08006008 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006009 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006010 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006011 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006012 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006013 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006014 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015 }
6016
6017 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006018 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006019 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006020 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6021 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006022 }
6023#ifdef _ANDROID_ICS_
6024 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6025#endif
6026 }
6027
6028 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006029 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006030 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006031 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6032 if (m_inp_mem_ptr)
6033 free_input_buffer (i,&m_inp_mem_ptr[i]);
6034 else
6035 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036 }
6037 }
6038 free_input_buffer_header();
6039 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006040 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006041 free(h264_scratch.pBuffer);
6042 h264_scratch.pBuffer = NULL;
6043 }
6044
Arun Menon906de572013-06-18 17:01:40 -07006045 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006046 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006047 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048 }
6049
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006050 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006051 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006052 delete (m_frame_parser.mutils);
6053 m_frame_parser.mutils = NULL;
6054 }
6055
Arun Menon906de572013-06-18 17:01:40 -07006056 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057 free(m_platform_list);
6058 m_platform_list = NULL;
6059 }
Arun Menon906de572013-06-18 17:01:40 -07006060 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061 free(m_vendor_config.pData);
6062 m_vendor_config.pData = NULL;
6063 }
6064
6065 // Reset counters in mesg queues
6066 m_ftb_q.m_size=0;
6067 m_cmd_q.m_size=0;
6068 m_etb_q.m_size=0;
6069 m_ftb_q.m_read = m_ftb_q.m_write =0;
6070 m_cmd_q.m_read = m_cmd_q.m_write =0;
6071 m_etb_q.m_read = m_etb_q.m_write =0;
6072#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006073 if (m_debug_timestamp) {
6074 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006075 }
6076#endif
6077
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006078 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006080 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006081 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006082
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006083 if (m_debug.infile) {
6084 fclose(m_debug.infile);
6085 m_debug.infile = NULL;
6086 }
6087 if (m_debug.outfile) {
6088 fclose(m_debug.outfile);
6089 m_debug.outfile = NULL;
6090 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006091#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006092 if (outputExtradataFile)
6093 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006094#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006095 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006096 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006097}
6098
6099/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006100 FUNCTION
6101 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006102
Arun Menon906de572013-06-18 17:01:40 -07006103 DESCRIPTION
6104 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006105
Arun Menon906de572013-06-18 17:01:40 -07006106 PARAMETERS
6107 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108
Arun Menon906de572013-06-18 17:01:40 -07006109 RETURN VALUE
6110 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111
Arun Menon906de572013-06-18 17:01:40 -07006112 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006114 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6115 OMX_IN OMX_U32 port,
6116 OMX_IN OMX_PTR appData,
6117 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118{
Arun Menon906de572013-06-18 17:01:40 -07006119 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6120 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6121 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006122
6123#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006124 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6125 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006126#else
Arun Menon906de572013-06-18 17:01:40 -07006127 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006128#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006129 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006130 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006131 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006132 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006133#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006134 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006135 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006136 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006137 }
6138 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6139 eglGetProcAddress("eglQueryImageKHR");
6140 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6141 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6142 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006143#else //with OMX test app
6144 struct temp_egl {
6145 int pmem_fd;
6146 int offset;
6147 };
6148 struct temp_egl *temp_egl_id = NULL;
6149 void * pmemPtr = (void *) eglImage;
6150 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006151 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006152 fd = temp_egl_id->pmem_fd;
6153 offset = temp_egl_id->offset;
6154 }
6155#endif
6156 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006157 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006158 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006159 }
6160 pmem_info.pmem_fd = (OMX_U32) fd;
6161 pmem_info.offset = (OMX_U32) offset;
6162 pmem_entry.entry = (void *) &pmem_info;
6163 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6164 pmem_list.entryList = &pmem_entry;
6165 pmem_list.nEntries = 1;
6166 ouput_egl_buffers = true;
6167 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6168 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6169 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006170 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006171 return OMX_ErrorInsufficientResources;
6172 }
6173 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174}
6175
6176/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006177 FUNCTION
6178 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006179
Arun Menon906de572013-06-18 17:01:40 -07006180 DESCRIPTION
6181 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006182
Arun Menon906de572013-06-18 17:01:40 -07006183 PARAMETERS
6184 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006185
Arun Menon906de572013-06-18 17:01:40 -07006186 RETURN VALUE
6187 OMX Error None if everything is successful.
6188 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006189OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006190 OMX_OUT OMX_U8* role,
6191 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006192{
Arun Menon906de572013-06-18 17:01:40 -07006193 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006194
Arun Menon906de572013-06-18 17:01:40 -07006195 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6196 if ((0 == index) && role) {
6197 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006198 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006199 } else {
6200 eRet = OMX_ErrorNoMore;
6201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006202 }
Arun Menon906de572013-06-18 17:01:40 -07006203 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6204 if ((0 == index) && role) {
6205 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006206 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006207 } else {
6208 eRet = OMX_ErrorNoMore;
6209 }
6210 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6211 if ((0 == index) && role) {
6212 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006213 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006214 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006215 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006216 eRet = OMX_ErrorNoMore;
6217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006218 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219
Arun Menon906de572013-06-18 17:01:40 -07006220 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6221 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6222 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006223
Shalaj Jain273b3e02012-06-22 19:08:03 -07006224 {
Arun Menon906de572013-06-18 17:01:40 -07006225 if ((0 == index) && role) {
6226 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006227 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006228 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006229 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006230 eRet = OMX_ErrorNoMore;
6231 }
6232 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6233 if ((0 == index) && role) {
6234 strlcpy((char *)role, "video_decoder.avc",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 }
6240 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6241 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6242 ) {
6243 if ((0 == index) && role) {
6244 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006245 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006246 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006247 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006248 eRet = OMX_ErrorNoMore;
6249 }
6250 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6251 if ((0 == index) && role) {
6252 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006253 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006254 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006255 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006256 eRet = OMX_ErrorNoMore;
6257 }
6258 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006259 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006260 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006261 }
Arun Menon906de572013-06-18 17:01:40 -07006262 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006263}
6264
6265
6266
6267
6268/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006269 FUNCTION
6270 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271
Arun Menon906de572013-06-18 17:01:40 -07006272 DESCRIPTION
6273 Checks if entire buffer pool is allocated by IL Client or not.
6274 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006275
Arun Menon906de572013-06-18 17:01:40 -07006276 PARAMETERS
6277 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006278
Arun Menon906de572013-06-18 17:01:40 -07006279 RETURN VALUE
6280 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006281
Arun Menon906de572013-06-18 17:01:40 -07006282 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006283bool omx_vdec::allocate_done(void)
6284{
Arun Menon906de572013-06-18 17:01:40 -07006285 bool bRet = false;
6286 bool bRet_In = false;
6287 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006288
Arun Menon906de572013-06-18 17:01:40 -07006289 bRet_In = allocate_input_done();
6290 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006291
Arun Menon906de572013-06-18 17:01:40 -07006292 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006293 bRet = true;
6294 }
Arun Menon906de572013-06-18 17:01:40 -07006295
6296 return bRet;
6297}
6298/* ======================================================================
6299 FUNCTION
6300 omx_vdec::AllocateInputDone
6301
6302 DESCRIPTION
6303 Checks if I/P buffer pool is allocated by IL Client or not.
6304
6305 PARAMETERS
6306 None.
6307
6308 RETURN VALUE
6309 true/false.
6310
6311 ========================================================================== */
6312bool omx_vdec::allocate_input_done(void)
6313{
6314 bool bRet = false;
6315 unsigned i=0;
6316
6317 if (m_inp_mem_ptr == NULL) {
6318 return bRet;
6319 }
6320 if (m_inp_mem_ptr ) {
6321 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6322 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6323 break;
6324 }
6325 }
6326 }
6327 if (i == drv_ctx.ip_buf.actualcount) {
6328 bRet = true;
6329 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6330 }
6331 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6332 m_inp_bPopulated = OMX_TRUE;
6333 }
6334 return bRet;
6335}
6336/* ======================================================================
6337 FUNCTION
6338 omx_vdec::AllocateOutputDone
6339
6340 DESCRIPTION
6341 Checks if entire O/P buffer pool is allocated by IL Client or not.
6342
6343 PARAMETERS
6344 None.
6345
6346 RETURN VALUE
6347 true/false.
6348
6349 ========================================================================== */
6350bool omx_vdec::allocate_output_done(void)
6351{
6352 bool bRet = false;
6353 unsigned j=0;
6354
6355 if (m_out_mem_ptr == NULL) {
6356 return bRet;
6357 }
6358
6359 if (m_out_mem_ptr) {
6360 for (; j < drv_ctx.op_buf.actualcount; j++) {
6361 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6362 break;
6363 }
6364 }
6365 }
6366
6367 if (j == drv_ctx.op_buf.actualcount) {
6368 bRet = true;
6369 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6370 if (m_out_bEnabled)
6371 m_out_bPopulated = OMX_TRUE;
6372 }
6373
6374 return bRet;
6375}
6376
6377/* ======================================================================
6378 FUNCTION
6379 omx_vdec::ReleaseDone
6380
6381 DESCRIPTION
6382 Checks if IL client has released all the buffers.
6383
6384 PARAMETERS
6385 None.
6386
6387 RETURN VALUE
6388 true/false
6389
6390 ========================================================================== */
6391bool omx_vdec::release_done(void)
6392{
6393 bool bRet = false;
6394
6395 if (release_input_done()) {
6396 if (release_output_done()) {
6397 bRet = true;
6398 }
6399 }
6400 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006401}
6402
6403
6404/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006405 FUNCTION
6406 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006407
Arun Menon906de572013-06-18 17:01:40 -07006408 DESCRIPTION
6409 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006410
Arun Menon906de572013-06-18 17:01:40 -07006411 PARAMETERS
6412 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006413
Arun Menon906de572013-06-18 17:01:40 -07006414 RETURN VALUE
6415 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006416
Arun Menon906de572013-06-18 17:01:40 -07006417 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006418bool omx_vdec::release_output_done(void)
6419{
Arun Menon906de572013-06-18 17:01:40 -07006420 bool bRet = false;
6421 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006422
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006423 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006424 if (m_out_mem_ptr) {
6425 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6426 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6427 break;
6428 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006429 }
Arun Menon906de572013-06-18 17:01:40 -07006430 if (j == drv_ctx.op_buf.actualcount) {
6431 m_out_bm_count = 0;
6432 bRet = true;
6433 }
6434 } else {
6435 m_out_bm_count = 0;
6436 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006437 }
Arun Menon906de572013-06-18 17:01:40 -07006438 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006439}
6440/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006441 FUNCTION
6442 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006443
Arun Menon906de572013-06-18 17:01:40 -07006444 DESCRIPTION
6445 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006446
Arun Menon906de572013-06-18 17:01:40 -07006447 PARAMETERS
6448 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006449
Arun Menon906de572013-06-18 17:01:40 -07006450 RETURN VALUE
6451 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006452
Arun Menon906de572013-06-18 17:01:40 -07006453 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006454bool omx_vdec::release_input_done(void)
6455{
Arun Menon906de572013-06-18 17:01:40 -07006456 bool bRet = false;
6457 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006458
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006459 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006460 if (m_inp_mem_ptr) {
6461 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6462 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6463 break;
6464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006465 }
Arun Menon906de572013-06-18 17:01:40 -07006466 if (j==drv_ctx.ip_buf.actualcount) {
6467 bRet = true;
6468 }
6469 } else {
6470 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006471 }
Arun Menon906de572013-06-18 17:01:40 -07006472 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006473}
6474
6475OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006476 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006477{
Arun Menon906de572013-06-18 17:01:40 -07006478 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306479 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006480 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006481 return OMX_ErrorBadParameter;
6482 } else if (output_flush_progress) {
6483 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6484 buffer->nFilledLen = 0;
6485 buffer->nTimeStamp = 0;
6486 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6487 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6488 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006489 }
6490
Arun Menon906de572013-06-18 17:01:40 -07006491 if (m_debug_extradata) {
6492 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006493 DEBUG_PRINT_HIGH("");
6494 DEBUG_PRINT_HIGH("***************************************************");
6495 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6496 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006497 }
6498
6499 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006500 DEBUG_PRINT_HIGH("");
6501 DEBUG_PRINT_HIGH("***************************************************");
6502 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6503 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006504 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006505 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006506
6507
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006508 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006509 buffer, buffer->pBuffer);
6510 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006511
Arun Menon906de572013-06-18 17:01:40 -07006512 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006513 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006514 if (!output_flush_progress)
6515 post_event((unsigned)NULL, (unsigned)NULL,
6516 OMX_COMPONENT_GENERATE_EOS_DONE);
6517
6518 if (psource_frame) {
6519 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6520 psource_frame = NULL;
6521 }
6522 if (pdest_frame) {
6523 pdest_frame->nFilledLen = 0;
6524 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6525 (unsigned)NULL);
6526 pdest_frame = NULL;
6527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006528 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006529
Shalaj Jain273b3e02012-06-22 19:08:03 -07006530
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006531 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6532 DEBUG_PRINT_LOW("Processing extradata");
6533 handle_extradata(buffer);
6534 }
6535
Arun Menon906de572013-06-18 17:01:40 -07006536 /* For use buffer we need to copy the data */
6537 if (!output_flush_progress) {
6538 /* This is the error check for non-recoverable errros */
6539 bool is_duplicate_ts_valid = true;
6540 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006541
Arun Menon906de572013-06-18 17:01:40 -07006542 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6543 output_capability == V4L2_PIX_FMT_MPEG2 ||
6544 output_capability == V4L2_PIX_FMT_DIVX ||
6545 output_capability == V4L2_PIX_FMT_DIVX_311)
6546 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006547
Arun Menon906de572013-06-18 17:01:40 -07006548 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006549 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006550 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306551 }
Arun Menon906de572013-06-18 17:01:40 -07006552 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306553
Arun Menon906de572013-06-18 17:01:40 -07006554 if (buffer->nFilledLen > 0) {
6555 time_stamp_dts.get_next_timestamp(buffer,
6556 is_interlaced && is_duplicate_ts_valid);
6557 if (m_debug_timestamp) {
6558 {
6559 OMX_TICKS expected_ts = 0;
6560 m_timestamp_list.pop_min_ts(expected_ts);
6561 if (is_interlaced && is_duplicate_ts_valid) {
6562 m_timestamp_list.pop_min_ts(expected_ts);
6563 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006564 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006565 buffer->nTimeStamp, expected_ts);
6566
6567 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006568 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006569 }
6570 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306571 }
Arun Menon906de572013-06-18 17:01:40 -07006572 } else {
Arun Menon906de572013-06-18 17:01:40 -07006573 time_stamp_dts.remove_time_stamp(
6574 buffer->nTimeStamp,
6575 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306576 }
Arun Menon906de572013-06-18 17:01:40 -07006577
6578
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006579 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006580
Arun Menon906de572013-06-18 17:01:40 -07006581 if (m_cb.FillBufferDone) {
6582 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006583 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006584 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006585 else
6586 set_frame_rate(buffer->nTimeStamp);
6587
Arun Menon906de572013-06-18 17:01:40 -07006588 if (perf_flag) {
6589 if (!proc_frms) {
6590 dec_time.stop();
6591 latency = dec_time.processing_time_us() - latency;
6592 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6593 dec_time.start();
6594 fps_metrics.start();
6595 }
6596 proc_frms++;
6597 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6598 OMX_U64 proc_time = 0;
6599 fps_metrics.stop();
6600 proc_time = fps_metrics.processing_time_us();
6601 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006602 proc_frms, (float)proc_time / 1e6,
6603 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006604 proc_frms = 0;
6605 }
6606 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006607
6608#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006609 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006610
Arun Menon906de572013-06-18 17:01:40 -07006611 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6612 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6613 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6614 buffer->nFilledLen + 3)&(~3));
6615 while (p_extra &&
6616 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006617 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006618 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6619 if (p_extra->eType == OMX_ExtraDataNone) {
6620 break;
6621 }
6622 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6623 }
6624 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006625#endif
Arun Menon906de572013-06-18 17:01:40 -07006626 }
6627 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6628 prev_ts = LLONG_MAX;
6629 rst_prev_ts = true;
6630 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006631
Arun Menon906de572013-06-18 17:01:40 -07006632 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6633 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6634 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006635 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006636 OMX_BUFFERHEADERTYPE *il_buffer;
6637 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006638
vivek mehta79cff222014-01-22 12:17:07 -08006639 if (il_buffer && m_last_rendered_TS >= 0) {
6640 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306641 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006642
6643 // Current frame can be send for rendering if
6644 // (a) current FPS is <= 60
6645 // (b) is the next frame after the frame with TS 0
6646 // (c) is the first frame after seek
6647 // (d) the delta TS b\w two consecutive frames is > 16 ms
6648 // (e) its TS is equal to previous frame TS
6649 // (f) if marked EOS
6650
6651 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6652 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6653 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006654 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006655 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006656 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006657 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006658 }
6659
6660 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6661 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6662 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006663 }
6664
vivek mehta79cff222014-01-22 12:17:07 -08006665 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006666 log_output_buffers(il_buffer);
6667 if (dynamic_buf_mode) {
6668 unsigned int nPortIndex = 0;
6669 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6670
6671 if (!secure_mode) {
6672 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6673 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6674 }
6675
6676 //Clear graphic buffer handles in dynamic mode
6677 native_buffer[nPortIndex].privatehandle = NULL;
6678 native_buffer[nPortIndex].nativehandle = NULL;
6679 }
Arun Menon906de572013-06-18 17:01:40 -07006680 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006681 } else {
Arun Menon906de572013-06-18 17:01:40 -07006682 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6683 return OMX_ErrorBadParameter;
6684 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006685 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006686 } else {
6687 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006688 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006689
Praveen Chavancf924182013-12-06 23:16:23 -08006690#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6691 if (m_smoothstreaming_mode) {
6692 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6693 BufferDim_t dim;
6694 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6695 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6696 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6697 if (private_handle) {
6698 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6699 dim.sliceWidth, dim.sliceHeight);
6700 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6701 }
6702 }
6703#endif
6704
Arun Menon906de572013-06-18 17:01:40 -07006705 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006706}
6707
6708OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006709 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006710{
6711
Surajit Podderd2644d52013-08-28 17:59:06 +05306712 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006713 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006714 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006715 }
6716
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006717 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006718 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006719 pending_input_buffers--;
6720
Arun Menon906de572013-06-18 17:01:40 -07006721 if (arbitrary_bytes) {
6722 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006723 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006724 pdest_frame = buffer;
6725 buffer->nFilledLen = 0;
6726 buffer->nTimeStamp = LLONG_MAX;
6727 push_input_buffer (hComp);
6728 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006729 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006730 buffer->nFilledLen = 0;
6731 if (!m_input_free_q.insert_entry((unsigned)buffer,
6732 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006733 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006734 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006735 }
Arun Menon906de572013-06-18 17:01:40 -07006736 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006737 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006738 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006739 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6740 }
6741 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6742 }
6743 return OMX_ErrorNone;
6744}
6745
Shalaj Jain273b3e02012-06-22 19:08:03 -07006746int omx_vdec::async_message_process (void *context, void* message)
6747{
Arun Menon906de572013-06-18 17:01:40 -07006748 omx_vdec* omx = NULL;
6749 struct vdec_msginfo *vdec_msg = NULL;
6750 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6751 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6752 struct vdec_output_frameinfo *output_respbuf = NULL;
6753 int rc=1;
6754 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006755 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006756 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006757 }
Arun Menon906de572013-06-18 17:01:40 -07006758 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759
Arun Menon906de572013-06-18 17:01:40 -07006760 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006761
Arun Menon906de572013-06-18 17:01:40 -07006762 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006763
Arun Menon906de572013-06-18 17:01:40 -07006764 case VDEC_MSG_EVT_HW_ERROR:
6765 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6766 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6767 break;
6768
6769 case VDEC_MSG_RESP_START_DONE:
6770 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6771 OMX_COMPONENT_GENERATE_START_DONE);
6772 break;
6773
6774 case VDEC_MSG_RESP_STOP_DONE:
6775 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6776 OMX_COMPONENT_GENERATE_STOP_DONE);
6777 break;
6778
6779 case VDEC_MSG_RESP_RESUME_DONE:
6780 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6781 OMX_COMPONENT_GENERATE_RESUME_DONE);
6782 break;
6783
6784 case VDEC_MSG_RESP_PAUSE_DONE:
6785 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6786 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6787 break;
6788
6789 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6790 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6791 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6792 break;
6793 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6794 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6795 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6796 break;
6797 case VDEC_MSG_RESP_INPUT_FLUSHED:
6798 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6799
6800 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6801 vdec_msg->msgdata.input_frame_clientdata; */
6802
6803 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6804 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6805 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306806 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006807 omxhdr = NULL;
6808 vdec_msg->status_code = VDEC_S_EFATAL;
6809 }
6810 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6811 DEBUG_PRINT_HIGH("Unsupported input");
6812 omx->omx_report_error ();
6813 }
6814 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6815 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6816 }
6817 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6818 OMX_COMPONENT_GENERATE_EBD);
6819 break;
6820 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6821 int64_t *timestamp;
6822 timestamp = (int64_t *) malloc(sizeof(int64_t));
6823 if (timestamp) {
6824 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6825 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6826 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006827 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006828 vdec_msg->msgdata.output_frame.time_stamp);
6829 }
6830 break;
6831 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6832 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6833
6834 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6835 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6836 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6837 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6838 vdec_msg->msgdata.output_frame.pic_type);
6839
6840 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306841 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006842 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306843 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006844 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6845 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6846 }
Arun Menon906de572013-06-18 17:01:40 -07006847 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6848 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6849 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6850 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6851 omxhdr->nFlags = 0;
6852
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006853 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006854 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6855 //rc = -1;
6856 }
6857 if (omxhdr->nFilledLen) {
6858 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6859 }
6860 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6861 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6862 } else {
6863 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6864 }
6865 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6866 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6867 }
6868 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6869 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6870 }
Arun Menon7b6fd642014-02-13 16:48:36 -08006871
6872 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
6873 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
6874 }
6875
Arun Menonbdb80b02013-08-12 17:45:54 -07006876 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006877 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006878 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6879 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6880 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006881 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6882 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6883 omxhdr->nOffset);
6884 }
Arun Menon906de572013-06-18 17:01:40 -07006885 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6886 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006887 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006888 omx->time_stamp_dts.remove_time_stamp(
6889 omxhdr->nTimeStamp,
6890 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6891 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006892 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6893 OMX_COMPONENT_GENERATE_FTB);
6894 break;
6895 }
6896 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6897 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6898 }
6899 vdec_msg->msgdata.output_frame.bufferaddr =
6900 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6901 int format_notably_changed = 0;
6902 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306903 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006904 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6905 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006906 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006907 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6908 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6909 format_notably_changed = 1;
6910 }
6911 }
6912 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6913 vdec_msg->msgdata.output_frame.framesize.left)
6914 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6915 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6916 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6917 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6918 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6919 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6920 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006921 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006922 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6923 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6924 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006925 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006926 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6927 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006928 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6929 omx->drv_ctx.video_resolution.frame_width) {
6930 vdec_msg->msgdata.output_frame.framesize.left = 0;
6931 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6932 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6933 }
6934 }
6935 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6936 omx->drv_ctx.video_resolution.frame_height) {
6937 vdec_msg->msgdata.output_frame.framesize.top = 0;
6938 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6939 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6940 }
6941 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006942 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 -07006943 vdec_msg->msgdata.output_frame.framesize.left,
6944 vdec_msg->msgdata.output_frame.framesize.top,
6945 vdec_msg->msgdata.output_frame.framesize.right,
6946 vdec_msg->msgdata.output_frame.framesize.bottom,
6947 omx->drv_ctx.video_resolution.frame_width,
6948 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006949 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6950 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6951 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6952 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6953 format_notably_changed = 1;
6954 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006955 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006956 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6957 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006958 if (format_notably_changed) {
6959 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306960 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006961 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6962 } else {
6963 if (!omx->client_buffers.update_buffer_req()) {
6964 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6965 }
6966 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6967 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6968 }
6969 }
6970 if (omxhdr->nFilledLen)
6971 omx->prev_n_filled_len = omxhdr->nFilledLen;
6972
6973 output_respbuf = (struct vdec_output_frameinfo *)\
6974 omxhdr->pOutputPortPrivate;
6975 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6976 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6977 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6978 output_respbuf->pic_type = PICTURE_TYPE_I;
6979 }
6980 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6981 output_respbuf->pic_type = PICTURE_TYPE_P;
6982 }
6983 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6984 output_respbuf->pic_type = PICTURE_TYPE_B;
6985 }
6986
6987 if (omx->output_use_buffer)
6988 memcpy ( omxhdr->pBuffer, (void *)
6989 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6990 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6991 vdec_msg->msgdata.output_frame.len);
6992 } else
6993 omxhdr->nFilledLen = 0;
6994 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6995 OMX_COMPONENT_GENERATE_FBD);
6996 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6997 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6998 OMX_COMPONENT_GENERATE_EOS_DONE);
6999 else
7000 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7001 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7002 break;
7003 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007004 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007005 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7006 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7007 break;
7008 default:
7009 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007010 }
Arun Menon906de572013-06-18 17:01:40 -07007011 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007012}
7013
7014OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007015 OMX_HANDLETYPE hComp,
7016 OMX_BUFFERHEADERTYPE *buffer
7017 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007018{
Arun Menon906de572013-06-18 17:01:40 -07007019 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007020 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007021
Arun Menon906de572013-06-18 17:01:40 -07007022 if (buffer == NULL) {
7023 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007025 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7026 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007027 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7028
7029 /* return zero length and not an EOS buffer */
7030 /* return buffer if input flush in progress */
7031 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7032 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007033 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007034 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7035 return OMX_ErrorNone;
7036 }
7037
7038 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007039 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007040 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007041 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007042 push_input_buffer (hComp);
7043 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007044 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007045 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7046 (unsigned)NULL)) {
7047 return OMX_ErrorBadParameter;
7048 }
7049 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007050
7051
Arun Menon906de572013-06-18 17:01:40 -07007052 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007053}
7054
7055OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7056{
Arun Menon906de572013-06-18 17:01:40 -07007057 unsigned address,p2,id;
7058 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007059
Arun Menon906de572013-06-18 17:01:40 -07007060 if (pdest_frame == NULL || psource_frame == NULL) {
7061 /*Check if we have a destination buffer*/
7062 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007063 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007064 if (m_input_free_q.m_size) {
7065 m_input_free_q.pop_entry(&address,&p2,&id);
7066 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7067 pdest_frame->nFilledLen = 0;
7068 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007069 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007070 }
7071 }
7072
7073 /*Check if we have a destination buffer*/
7074 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007075 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007076 if (m_input_pending_q.m_size) {
7077 m_input_pending_q.pop_entry(&address,&p2,&id);
7078 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007079 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007080 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007081 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007082 psource_frame->nFlags,psource_frame->nFilledLen);
7083
7084 }
7085 }
7086
Shalaj Jain273b3e02012-06-22 19:08:03 -07007087 }
7088
Arun Menon906de572013-06-18 17:01:40 -07007089 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7090 switch (codec_type_parse) {
7091 case CODEC_TYPE_MPEG4:
7092 case CODEC_TYPE_H263:
7093 case CODEC_TYPE_MPEG2:
7094 ret = push_input_sc_codec(hComp);
7095 break;
7096 case CODEC_TYPE_H264:
7097 ret = push_input_h264(hComp);
7098 break;
7099 case CODEC_TYPE_VC1:
7100 ret = push_input_vc1(hComp);
7101 break;
7102 default:
7103 break;
7104 }
7105 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007106 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007107 omx_report_error ();
7108 break;
7109 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007110 }
7111
Arun Menon906de572013-06-18 17:01:40 -07007112 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007113}
7114
7115OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7116{
Arun Menon906de572013-06-18 17:01:40 -07007117 OMX_U32 partial_frame = 1;
7118 OMX_BOOL generate_ebd = OMX_TRUE;
7119 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007120
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007121 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007122 psource_frame,psource_frame->nTimeStamp);
7123 if (m_frame_parser.parse_sc_frame(psource_frame,
7124 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007125 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007126 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007127 }
Arun Menon906de572013-06-18 17:01:40 -07007128
7129 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007130 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007131 pdest_frame->nFilledLen,psource_frame,frame_count);
7132
7133
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007134 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007135 /*First Parsed buffer will have only header Hence skip*/
7136 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007137 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007138
7139 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7140 codec_type_parse == CODEC_TYPE_DIVX) {
7141 mp4StreamType psBits;
7142 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7143 psBits.numBytes = pdest_frame->nFilledLen;
7144 mp4_headerparser.parseHeader(&psBits);
7145 }
7146
7147 frame_count++;
7148 } else {
7149 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7150 if (pdest_frame->nFilledLen) {
7151 /*Push the frame to the Decoder*/
7152 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7153 return OMX_ErrorBadParameter;
7154 }
7155 frame_count++;
7156 pdest_frame = NULL;
7157
7158 if (m_input_free_q.m_size) {
7159 m_input_free_q.pop_entry(&address,&p2,&id);
7160 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7161 pdest_frame->nFilledLen = 0;
7162 }
7163 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007164 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007165 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7166 (unsigned)NULL);
7167 pdest_frame = NULL;
7168 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007169 }
Arun Menon906de572013-06-18 17:01:40 -07007170 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007171 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007172 /*Check if Destination Buffer is full*/
7173 if (pdest_frame->nAllocLen ==
7174 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007175 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007176 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007177 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007178 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007179
Arun Menon906de572013-06-18 17:01:40 -07007180 if (psource_frame->nFilledLen == 0) {
7181 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7182 if (pdest_frame) {
7183 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007184 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007185 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007186 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007187 pdest_frame->nFilledLen,frame_count++);
7188 /*Push the frame to the Decoder*/
7189 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7190 return OMX_ErrorBadParameter;
7191 }
7192 frame_count++;
7193 pdest_frame = NULL;
7194 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007195 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007196 generate_ebd = OMX_FALSE;
7197 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007198 }
Arun Menon906de572013-06-18 17:01:40 -07007199 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007200 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007201 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7202 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203
Arun Menon906de572013-06-18 17:01:40 -07007204 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007205 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007206 m_input_pending_q.pop_entry(&address,&p2,&id);
7207 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007208 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007209 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007210 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007211 psource_frame->nFlags,psource_frame->nFilledLen);
7212 }
7213 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007214 }
Arun Menon906de572013-06-18 17:01:40 -07007215 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007216}
7217
7218OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7219{
Arun Menon906de572013-06-18 17:01:40 -07007220 OMX_U32 partial_frame = 1;
7221 unsigned address = 0, p2 = 0, id = 0;
7222 OMX_BOOL isNewFrame = OMX_FALSE;
7223 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007224
Arun Menon906de572013-06-18 17:01:40 -07007225 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007226 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007227 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007228 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007229 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007230 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007231 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007232 if (h264_scratch.nFilledLen && look_ahead_nal) {
7233 look_ahead_nal = false;
7234 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7235 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007236 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7237 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7238 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007240 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007241 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007242 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007243 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007244 }
Arun Menon906de572013-06-18 17:01:40 -07007245 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007246
7247 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7248 in EOS flag getting associated with the destination
7249 */
7250 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7251 pdest_frame->nFilledLen) {
7252 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7253 generate_ebd = OMX_FALSE;
7254 }
7255
Arun Menon906de572013-06-18 17:01:40 -07007256 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007257 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007258 if (m_frame_parser.parse_sc_frame(psource_frame,
7259 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007260 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007261 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007262 }
Arun Menon906de572013-06-18 17:01:40 -07007263 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007264 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007265 if (m_frame_parser.parse_h264_nallength(psource_frame,
7266 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007267 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007268 return OMX_ErrorBadParameter;
7269 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007270 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007271
Arun Menon906de572013-06-18 17:01:40 -07007272 if (partial_frame == 0) {
7273 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007274 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007275 nal_count++;
7276 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7277 h264_scratch.nFlags = psource_frame->nFlags;
7278 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007279 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007280 if (h264_scratch.nFilledLen) {
7281 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7282 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007284 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7285 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7286 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7287 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7288 // If timeinfo is present frame info from SEI is already processed
7289 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7290 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007291#endif
Arun Menon906de572013-06-18 17:01:40 -07007292 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7293 nal_count++;
7294 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7295 pdest_frame->nTimeStamp = h264_last_au_ts;
7296 pdest_frame->nFlags = h264_last_au_flags;
7297#ifdef PANSCAN_HDLR
7298 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7299 h264_parser->update_panscan_data(h264_last_au_ts);
7300#endif
7301 }
7302 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7303 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7304 h264_last_au_ts = h264_scratch.nTimeStamp;
7305 h264_last_au_flags = h264_scratch.nFlags;
7306#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7307 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7308 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7309 if (!VALID_TS(h264_last_au_ts))
7310 h264_last_au_ts = ts_in_sei;
7311 }
7312#endif
7313 } else
7314 h264_last_au_ts = LLONG_MAX;
7315 }
7316
7317 if (!isNewFrame) {
7318 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7319 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007320 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007321 h264_scratch.nFilledLen);
7322 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7323 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7324 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7325 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7326 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7327 h264_scratch.nFilledLen = 0;
7328 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007329 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007330 return OMX_ErrorBadParameter;
7331 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007332 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007333 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007334 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007335 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007336 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007337 pdest_frame->nFilledLen,frame_count++);
7338
7339 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007340 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007341 look_ahead_nal = false;
7342 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7343 h264_scratch.nFilledLen) {
7344 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7345 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7346 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7347 h264_scratch.nFilledLen = 0;
7348 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007349 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007350 return OMX_ErrorBadParameter;
7351 }
7352 } else {
7353 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007354 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007355 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7356 }
7357 /*Push the frame to the Decoder*/
7358 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7359 return OMX_ErrorBadParameter;
7360 }
7361 //frame_count++;
7362 pdest_frame = NULL;
7363 if (m_input_free_q.m_size) {
7364 m_input_free_q.pop_entry(&address,&p2,&id);
7365 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007366 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007367 pdest_frame->nFilledLen = 0;
7368 pdest_frame->nFlags = 0;
7369 pdest_frame->nTimeStamp = LLONG_MAX;
7370 }
7371 }
7372 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007373 }
Arun Menon906de572013-06-18 17:01:40 -07007374 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007375 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007376 /*Check if Destination Buffer is full*/
7377 if (h264_scratch.nAllocLen ==
7378 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007379 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007380 return OMX_ErrorStreamCorrupt;
7381 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007382 }
Arun Menon906de572013-06-18 17:01:40 -07007383
7384 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007385 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007386
7387 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7388 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007389 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007390 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7391 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007392 if(pdest_frame->nFilledLen == 0) {
7393 /* No residual frame from before, send whatever
7394 * we have left */
7395 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7396 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7397 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7398 h264_scratch.nFilledLen = 0;
7399 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7400 } else {
7401 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7402 if(!isNewFrame) {
7403 /* Have a residual frame, but we know that the
7404 * AU in this frame is belonging to whatever
7405 * frame we had left over. So append it */
7406 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7407 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7408 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7409 h264_scratch.nFilledLen = 0;
7410 pdest_frame->nTimeStamp = h264_last_au_ts;
7411 } else {
7412 /* Completely new frame, let's just push what
7413 * we have now. The resulting EBD would trigger
7414 * another push */
7415 generate_ebd = OMX_FALSE;
7416 pdest_frame->nTimeStamp = h264_last_au_ts;
7417 h264_last_au_ts = h264_scratch.nTimeStamp;
7418 }
7419 }
Arun Menon906de572013-06-18 17:01:40 -07007420 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007421 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007422 return OMX_ErrorBadParameter;
7423 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007424
7425 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7426 if(generate_ebd == OMX_TRUE) {
7427 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7428 }
Arun Menon906de572013-06-18 17:01:40 -07007429
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007430 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007431 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007432 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007433#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7434 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7435 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7436 if (!VALID_TS(pdest_frame->nTimeStamp))
7437 pdest_frame->nTimeStamp = ts_in_sei;
7438 }
7439#endif
7440 /*Push the frame to the Decoder*/
7441 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7442 return OMX_ErrorBadParameter;
7443 }
7444 frame_count++;
7445 pdest_frame = NULL;
7446 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007447 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007448 pdest_frame,h264_scratch.nFilledLen);
7449 generate_ebd = OMX_FALSE;
7450 }
7451 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007452 }
Arun Menon906de572013-06-18 17:01:40 -07007453 if (generate_ebd && !psource_frame->nFilledLen) {
7454 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7455 psource_frame = NULL;
7456 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007457 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007458 m_input_pending_q.pop_entry(&address,&p2,&id);
7459 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007460 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007461 psource_frame->nFlags,psource_frame->nFilledLen);
7462 }
7463 }
7464 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007465}
7466
7467OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7468{
7469 OMX_U8 *buf, *pdest;
7470 OMX_U32 partial_frame = 1;
7471 OMX_U32 buf_len, dest_len;
7472
Arun Menon906de572013-06-18 17:01:40 -07007473 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007474 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007475 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007476 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007477 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007478 buf = psource_frame->pBuffer;
7479 buf_len = psource_frame->nFilledLen;
7480
7481 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007482 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007483 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007484 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007485 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007486 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007487 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 return OMX_ErrorStreamCorrupt;
7489 }
Arun Menon906de572013-06-18 17:01:40 -07007490 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007491 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7492 pdest_frame->nOffset;
7493 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007494 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007495
Arun Menon906de572013-06-18 17:01:40 -07007496 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007497 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007498 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007499 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007500 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7501 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7502 }
7503 }
7504 }
7505
Arun Menon906de572013-06-18 17:01:40 -07007506 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007507 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007508 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007509 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007510 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007511 return OMX_ErrorBadParameter;
7512 }
Arun Menon906de572013-06-18 17:01:40 -07007513 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007514
7515 case VC1_SP_MP_RCV:
7516 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007517 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518 return OMX_ErrorBadParameter;
7519 }
7520 return OMX_ErrorNone;
7521}
7522
David Ng38e2d232013-03-15 20:05:58 -07007523#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007524bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007525 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007526{
Arun Menon906de572013-06-18 17:01:40 -07007527 struct pmem_allocation allocation;
7528 allocation.size = buffer_size;
7529 allocation.align = clip2(alignment);
7530 if (allocation.align < 4096) {
7531 allocation.align = 4096;
7532 }
7533 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007534 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007535 allocation.align, allocation.size);
7536 return false;
7537 }
7538 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007539}
David Ng38e2d232013-03-15 20:05:58 -07007540#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007541#ifdef USE_ION
7542int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007543 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7544 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007545{
Arun Menon906de572013-06-18 17:01:40 -07007546 int fd = -EINVAL;
7547 int rc = -EINVAL;
7548 int ion_dev_flag;
7549 struct vdec_ion ion_buf_info;
7550 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007551 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007552 return -EINVAL;
7553 }
7554 ion_dev_flag = O_RDONLY;
7555 fd = open (MEM_DEVICE, ion_dev_flag);
7556 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007557 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007558 return fd;
7559 }
7560 alloc_data->flags = 0;
7561 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7562 alloc_data->flags |= ION_FLAG_CACHED;
7563 }
7564 alloc_data->len = buffer_size;
7565 alloc_data->align = clip2(alignment);
7566 if (alloc_data->align < 4096) {
7567 alloc_data->align = 4096;
7568 }
7569 if ((secure_mode) && (flag & ION_SECURE))
7570 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007571
Arun Menon906de572013-06-18 17:01:40 -07007572 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307573 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007574 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7575 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7576 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007577 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007578 alloc_data->handle = NULL;
7579 close(fd);
7580 fd = -ENOMEM;
7581 return fd;
7582 }
7583 fd_data->handle = alloc_data->handle;
7584 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7585 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007586 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007587 ion_buf_info.ion_alloc_data = *alloc_data;
7588 ion_buf_info.ion_device_fd = fd;
7589 ion_buf_info.fd_ion_data = *fd_data;
7590 free_ion_memory(&ion_buf_info);
7591 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007592 fd = -ENOMEM;
7593 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007594
Arun Menon906de572013-06-18 17:01:40 -07007595 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007596}
7597
Arun Menon906de572013-06-18 17:01:40 -07007598void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7599{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007600
Arun Menon906de572013-06-18 17:01:40 -07007601 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007602 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007603 return;
7604 }
7605 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7606 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007607 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007608 }
7609 close(buf_ion_info->ion_device_fd);
7610 buf_ion_info->ion_device_fd = -1;
7611 buf_ion_info->ion_alloc_data.handle = NULL;
7612 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007613}
7614#endif
7615void omx_vdec::free_output_buffer_header()
7616{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007617 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007618 output_use_buffer = false;
7619 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007620
Arun Menon906de572013-06-18 17:01:40 -07007621 if (m_out_mem_ptr) {
7622 free (m_out_mem_ptr);
7623 m_out_mem_ptr = NULL;
7624 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007625
Arun Menon906de572013-06-18 17:01:40 -07007626 if (m_platform_list) {
7627 free(m_platform_list);
7628 m_platform_list = NULL;
7629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007630
Arun Menon906de572013-06-18 17:01:40 -07007631 if (drv_ctx.ptr_respbuffer) {
7632 free (drv_ctx.ptr_respbuffer);
7633 drv_ctx.ptr_respbuffer = NULL;
7634 }
7635 if (drv_ctx.ptr_outputbuffer) {
7636 free (drv_ctx.ptr_outputbuffer);
7637 drv_ctx.ptr_outputbuffer = NULL;
7638 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007639#ifdef USE_ION
7640 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007641 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007642 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007643 drv_ctx.op_buf_ion_info = NULL;
7644 }
7645#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007646 if (out_dynamic_list) {
7647 free(out_dynamic_list);
7648 out_dynamic_list = NULL;
7649 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007650}
7651
7652void omx_vdec::free_input_buffer_header()
7653{
7654 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007655 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007656 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007657 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007658 free (m_inp_heap_ptr);
7659 m_inp_heap_ptr = NULL;
7660 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007661
Arun Menon906de572013-06-18 17:01:40 -07007662 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007663 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007664 free (m_phdr_pmem_ptr);
7665 m_phdr_pmem_ptr = NULL;
7666 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007667 }
Arun Menon906de572013-06-18 17:01:40 -07007668 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007669 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007670 free (m_inp_mem_ptr);
7671 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007672 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007673 /* We just freed all the buffer headers, every thing in m_input_free_q,
7674 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007675 while (m_input_free_q.m_size) {
7676 unsigned address, p2, id;
7677 m_input_free_q.pop_entry(&address, &p2, &id);
7678 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007679 while (m_input_pending_q.m_size) {
7680 unsigned address, p2, id;
7681 m_input_pending_q.pop_entry(&address, &p2, &id);
7682 }
7683 pdest_frame = NULL;
7684 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007685 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007686 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007687 free (drv_ctx.ptr_inputbuffer);
7688 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007689 }
7690#ifdef USE_ION
7691 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007692 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007693 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007694 drv_ctx.ip_buf_ion_info = NULL;
7695 }
7696#endif
7697}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007698
7699int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007700{
Arun Menon906de572013-06-18 17:01:40 -07007701 enum v4l2_buf_type btype;
7702 int rc = 0;
7703 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007704
Arun Menon906de572013-06-18 17:01:40 -07007705 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7706 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7707 v4l2_port = OUTPUT_PORT;
7708 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7709 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7710 v4l2_port = CAPTURE_PORT;
7711 } else if (port == OMX_ALL) {
7712 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7713 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007714
Arun Menon906de572013-06-18 17:01:40 -07007715 if (!rc_input)
7716 return rc_input;
7717 else
7718 return rc_output;
7719 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007720
Arun Menon906de572013-06-18 17:01:40 -07007721 if (!streaming[v4l2_port]) {
7722 // already streamed off, warn and move on
7723 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7724 " which is already streamed off", v4l2_port);
7725 return 0;
7726 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007727
Arun Menon906de572013-06-18 17:01:40 -07007728 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007729
Arun Menon906de572013-06-18 17:01:40 -07007730 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7731 if (rc) {
7732 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007733 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007734 } else {
7735 streaming[v4l2_port] = false;
7736 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007737
Arun Menon906de572013-06-18 17:01:40 -07007738 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007739}
7740
7741OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7742{
Arun Menon906de572013-06-18 17:01:40 -07007743 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7744 struct v4l2_requestbuffers bufreq;
7745 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307746 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007747 struct v4l2_format fmt;
7748 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007749 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007750 buffer_prop->actualcount, buffer_prop->buffer_size);
7751 bufreq.memory = V4L2_MEMORY_USERPTR;
7752 bufreq.count = 1;
7753 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7754 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7755 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7756 fmt.fmt.pix_mp.pixelformat = output_capability;
7757 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7758 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7759 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7760 fmt.fmt.pix_mp.pixelformat = capture_capability;
7761 } else {
7762 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007763 }
Arun Menon906de572013-06-18 17:01:40 -07007764 if (eRet==OMX_ErrorNone) {
7765 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007766 }
Arun Menon906de572013-06-18 17:01:40 -07007767 if (ret) {
7768 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7769 /*TODO: How to handle this case */
7770 eRet = OMX_ErrorInsufficientResources;
7771 return eRet;
7772 } else {
7773 buffer_prop->actualcount = bufreq.count;
7774 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007775 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007776 }
Arun Menon906de572013-06-18 17:01:40 -07007777 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7778 buffer_prop->actualcount, buffer_prop->buffer_size);
7779
7780 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7781 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7782
7783 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7784
7785 update_resolution(fmt.fmt.pix_mp.width,
7786 fmt.fmt.pix_mp.height,
7787 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7788 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7789 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7790 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007791 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007792
7793 if (ret) {
7794 /*TODO: How to handle this case */
7795 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7796 eRet = OMX_ErrorInsufficientResources;
7797 } else {
7798 int extra_idx = 0;
7799
7800 eRet = is_video_session_supported();
7801 if (eRet)
7802 return eRet;
7803
7804 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7805 buf_size = buffer_prop->buffer_size;
7806 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7807 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7808 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7809 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007810 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007811 return OMX_ErrorBadParameter;
7812 }
7813 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7814 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7815 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7816 }
7817 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7818 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7819 }
7820 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7821 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007822 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007823 client_extra_data_size);
7824 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307825 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7826 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7827 DEBUG_PRINT_HIGH("framepack extradata enabled");
7828 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007829 if (client_extradata & OMX_QP_EXTRADATA) {
7830 client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
7831 DEBUG_PRINT_HIGH("QP extradata enabled");
7832 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08007833 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
7834 client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
7835 DEBUG_PRINT_HIGH("Input bits info extradata enabled");
7836 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007837
Arun Menon906de572013-06-18 17:01:40 -07007838 if (client_extra_data_size) {
7839 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7840 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7841 }
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307842 final_extra_data_size = (extra_data_size > client_extra_data_size ?
7843 extra_data_size : client_extra_data_size);
7844 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007845 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307846 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007847 buf_size += client_extra_data_size;
7848 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7849 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7850 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7851 if (in_reconfig) // BufReq will be set to driver when port is disabled
7852 buffer_prop->buffer_size = buf_size;
7853 else if (buf_size != buffer_prop->buffer_size) {
7854 buffer_prop->buffer_size = buf_size;
7855 eRet = set_buffer_req(buffer_prop);
7856 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007857 }
Arun Menon906de572013-06-18 17:01:40 -07007858 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7859 buffer_prop->actualcount, buffer_prop->buffer_size);
7860 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007861}
7862
7863OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7864{
Arun Menon906de572013-06-18 17:01:40 -07007865 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7866 unsigned buf_size = 0;
7867 struct v4l2_format fmt;
7868 struct v4l2_requestbuffers bufreq;
7869 int ret;
7870 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7871 buffer_prop->actualcount, buffer_prop->buffer_size);
7872 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7873 if (buf_size != buffer_prop->buffer_size) {
7874 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7875 buffer_prop->buffer_size, buf_size);
7876 eRet = OMX_ErrorBadParameter;
7877 } else {
7878 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7879 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007880
Arun Menon906de572013-06-18 17:01:40 -07007881 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7882 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7883 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007884 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007885 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7886 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7887 fmt.fmt.pix_mp.pixelformat = capture_capability;
7888 } else {
7889 eRet = OMX_ErrorBadParameter;
7890 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007891
Arun Menon906de572013-06-18 17:01:40 -07007892 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7893 if (ret) {
7894 /*TODO: How to handle this case */
7895 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7896 eRet = OMX_ErrorInsufficientResources;
7897 }
7898
7899 bufreq.memory = V4L2_MEMORY_USERPTR;
7900 bufreq.count = buffer_prop->actualcount;
7901 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7902 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7903 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7904 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7905 } else {
7906 eRet = OMX_ErrorBadParameter;
7907 }
7908
7909 if (eRet==OMX_ErrorNone) {
7910 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7911 }
7912
7913 if (ret) {
7914 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7915 /*TODO: How to handle this case */
7916 eRet = OMX_ErrorInsufficientResources;
7917 } else if (bufreq.count < buffer_prop->actualcount) {
7918 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7919 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7920 buffer_prop->actualcount, bufreq.count);
7921 eRet = OMX_ErrorInsufficientResources;
7922 } else {
7923 if (!client_buffers.update_buffer_req()) {
7924 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7925 eRet = OMX_ErrorInsufficientResources;
7926 }
7927 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007928 }
Arun Menon906de572013-06-18 17:01:40 -07007929 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007930}
7931
Shalaj Jain273b3e02012-06-22 19:08:03 -07007932OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7933{
Arun Menon906de572013-06-18 17:01:40 -07007934 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7935 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007936}
7937
7938OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7939{
Arun Menon906de572013-06-18 17:01:40 -07007940 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7941 if (!portDefn) {
7942 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007943 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007944 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007945 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7946 portDefn->nSize = sizeof(portDefn);
7947 portDefn->eDomain = OMX_PortDomainVideo;
7948 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08007949 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
7950 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07007951 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007952 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007953 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007954 }
Arun Menon906de572013-06-18 17:01:40 -07007955 if (0 == portDefn->nPortIndex) {
7956 portDefn->eDir = OMX_DirInput;
7957 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7958 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7959 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7960 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7961 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7962 portDefn->bEnabled = m_inp_bEnabled;
7963 portDefn->bPopulated = m_inp_bPopulated;
7964 } else if (1 == portDefn->nPortIndex) {
7965 unsigned int buf_size = 0;
7966 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007967 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007968 return OMX_ErrorHardware;
7969 }
7970 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007971 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007972 return OMX_ErrorHardware;
7973 }
7974 portDefn->nBufferSize = buf_size;
7975 portDefn->eDir = OMX_DirOutput;
7976 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7977 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7978 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7979 portDefn->bEnabled = m_out_bEnabled;
7980 portDefn->bPopulated = m_out_bPopulated;
7981 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007982 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007983 return OMX_ErrorHardware;
7984 }
7985 } else {
7986 portDefn->eDir = OMX_DirMax;
7987 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7988 (int)portDefn->nPortIndex);
7989 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007990 }
Arun Menon906de572013-06-18 17:01:40 -07007991 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7992 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7993 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7994 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307995 if (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) {
7996 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
7997 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
7998 }
7999 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8000 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8001 portDefn->nPortIndex,
8002 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008003 portDefn->format.video.nFrameHeight,
8004 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308005 portDefn->format.video.nSliceHeight,
8006 portDefn->format.video.eColorFormat,
8007 portDefn->nBufferSize,
8008 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308010 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008011}
8012
8013OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8014{
Arun Menon906de572013-06-18 17:01:40 -07008015 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8016 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8017 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008018
Arun Menon906de572013-06-18 17:01:40 -07008019 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008020 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008021 int nBufHdrSize = 0;
8022 int nPlatformEntrySize = 0;
8023 int nPlatformListSize = 0;
8024 int nPMEMInfoSize = 0;
8025 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8026 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8027 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008028
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008029 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008030 drv_ctx.op_buf.actualcount);
8031 nBufHdrSize = drv_ctx.op_buf.actualcount *
8032 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008033
Arun Menon906de572013-06-18 17:01:40 -07008034 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8035 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8036 nPlatformListSize = drv_ctx.op_buf.actualcount *
8037 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8038 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8039 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008040
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008041 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008042 sizeof(OMX_BUFFERHEADERTYPE),
8043 nPMEMInfoSize,
8044 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008045 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008046 m_out_bm_count);
8047 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8048 // Alloc mem for platform specific info
8049 char *pPtr=NULL;
8050 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8051 nPMEMInfoSize,1);
8052 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8053 calloc (sizeof(struct vdec_bufferpayload),
8054 drv_ctx.op_buf.actualcount);
8055 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8056 calloc (sizeof (struct vdec_output_frameinfo),
8057 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008058#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008059 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8060 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008061#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008062 if (dynamic_buf_mode) {
8063 out_dynamic_list = (struct dynamic_buf_list *) \
8064 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8065 }
Arun Menon906de572013-06-18 17:01:40 -07008066 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8067 && drv_ctx.ptr_respbuffer) {
8068 bufHdr = m_out_mem_ptr;
8069 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8070 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8071 (((char *) m_platform_list) + nPlatformListSize);
8072 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8073 (((char *) m_platform_entry) + nPlatformEntrySize);
8074 pPlatformList = m_platform_list;
8075 pPlatformEntry = m_platform_entry;
8076 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008077
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008078 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008079
Arun Menon906de572013-06-18 17:01:40 -07008080 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008081 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008082 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008083 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008084 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8085 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8086 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8087 // Set the values when we determine the right HxW param
8088 bufHdr->nAllocLen = 0;
8089 bufHdr->nFilledLen = 0;
8090 bufHdr->pAppPrivate = NULL;
8091 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8092 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8093 pPlatformEntry->entry = pPMEMInfo;
8094 // Initialize the Platform List
8095 pPlatformList->nEntries = 1;
8096 pPlatformList->entryList = pPlatformEntry;
8097 // Keep pBuffer NULL till vdec is opened
8098 bufHdr->pBuffer = NULL;
8099 pPMEMInfo->offset = 0;
8100 pPMEMInfo->pmem_fd = 0;
8101 bufHdr->pPlatformPrivate = pPlatformList;
8102 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008103#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008104 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008105#endif
Arun Menon906de572013-06-18 17:01:40 -07008106 /*Create a mapping between buffers*/
8107 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8108 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8109 &drv_ctx.ptr_outputbuffer[i];
8110 // Move the buffer and buffer header pointers
8111 bufHdr++;
8112 pPMEMInfo++;
8113 pPlatformEntry++;
8114 pPlatformList++;
8115 }
8116 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008117 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008118 m_out_mem_ptr, pPtr);
8119 if (m_out_mem_ptr) {
8120 free(m_out_mem_ptr);
8121 m_out_mem_ptr = NULL;
8122 }
8123 if (pPtr) {
8124 free(pPtr);
8125 pPtr = NULL;
8126 }
8127 if (drv_ctx.ptr_outputbuffer) {
8128 free(drv_ctx.ptr_outputbuffer);
8129 drv_ctx.ptr_outputbuffer = NULL;
8130 }
8131 if (drv_ctx.ptr_respbuffer) {
8132 free(drv_ctx.ptr_respbuffer);
8133 drv_ctx.ptr_respbuffer = NULL;
8134 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008135#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008136 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008137 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008138 free(drv_ctx.op_buf_ion_info);
8139 drv_ctx.op_buf_ion_info = NULL;
8140 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008141#endif
Arun Menon906de572013-06-18 17:01:40 -07008142 eRet = OMX_ErrorInsufficientResources;
8143 }
8144 } else {
8145 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008146 }
Arun Menon906de572013-06-18 17:01:40 -07008147 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008148}
8149
8150void omx_vdec::complete_pending_buffer_done_cbs()
8151{
Arun Menon906de572013-06-18 17:01:40 -07008152 unsigned p1;
8153 unsigned p2;
8154 unsigned ident;
8155 omx_cmd_queue tmp_q, pending_bd_q;
8156 pthread_mutex_lock(&m_lock);
8157 // pop all pending GENERATE FDB from ftb queue
8158 while (m_ftb_q.m_size) {
8159 m_ftb_q.pop_entry(&p1,&p2,&ident);
8160 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8161 pending_bd_q.insert_entry(p1,p2,ident);
8162 } else {
8163 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008164 }
Arun Menon906de572013-06-18 17:01:40 -07008165 }
8166 //return all non GENERATE FDB to ftb queue
8167 while (tmp_q.m_size) {
8168 tmp_q.pop_entry(&p1,&p2,&ident);
8169 m_ftb_q.insert_entry(p1,p2,ident);
8170 }
8171 // pop all pending GENERATE EDB from etb queue
8172 while (m_etb_q.m_size) {
8173 m_etb_q.pop_entry(&p1,&p2,&ident);
8174 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8175 pending_bd_q.insert_entry(p1,p2,ident);
8176 } else {
8177 tmp_q.insert_entry(p1,p2,ident);
8178 }
8179 }
8180 //return all non GENERATE FDB to etb queue
8181 while (tmp_q.m_size) {
8182 tmp_q.pop_entry(&p1,&p2,&ident);
8183 m_etb_q.insert_entry(p1,p2,ident);
8184 }
8185 pthread_mutex_unlock(&m_lock);
8186 // process all pending buffer dones
8187 while (pending_bd_q.m_size) {
8188 pending_bd_q.pop_entry(&p1,&p2,&ident);
8189 switch (ident) {
8190 case OMX_COMPONENT_GENERATE_EBD:
8191 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008192 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008193 omx_report_error ();
8194 }
8195 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008196
Arun Menon906de572013-06-18 17:01:40 -07008197 case OMX_COMPONENT_GENERATE_FBD:
8198 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008199 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008200 omx_report_error ();
8201 }
8202 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008203 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008204 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008205}
8206
8207void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8208{
Arun Menon906de572013-06-18 17:01:40 -07008209 OMX_U32 new_frame_interval = 0;
8210 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8211 && llabs(act_timestamp - prev_ts) > 2000) {
8212 new_frame_interval = client_set_fps ? frm_int :
8213 llabs(act_timestamp - prev_ts);
8214 if (new_frame_interval < frm_int || frm_int == 0) {
8215 frm_int = new_frame_interval;
8216 if (frm_int) {
8217 drv_ctx.frame_rate.fps_numerator = 1e6;
8218 drv_ctx.frame_rate.fps_denominator = frm_int;
8219 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8220 frm_int, drv_ctx.frame_rate.fps_numerator /
8221 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008222
Arun Menon906de572013-06-18 17:01:40 -07008223 /* We need to report the difference between this FBD and the previous FBD
8224 * back to the driver for clock scaling purposes. */
8225 struct v4l2_outputparm oparm;
8226 /*XXX: we're providing timing info as seconds per frame rather than frames
8227 * per second.*/
8228 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8229 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008230
Arun Menon906de572013-06-18 17:01:40 -07008231 struct v4l2_streamparm sparm;
8232 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8233 sparm.parm.output = oparm;
8234 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8235 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8236 performance might be affected");
8237 }
8238
8239 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008240 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008241 }
Arun Menon906de572013-06-18 17:01:40 -07008242 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008243}
8244
8245void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8246{
Arun Menon906de572013-06-18 17:01:40 -07008247 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8248 prev_ts = act_timestamp;
8249 rst_prev_ts = false;
8250 } else if (VALID_TS(prev_ts)) {
8251 bool codec_cond = (drv_ctx.timestamp_adjust)?
8252 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8253 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8254 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8255 if (frm_int > 0 && codec_cond) {
8256 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8257 act_timestamp = prev_ts + frm_int;
8258 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8259 prev_ts = act_timestamp;
8260 } else
8261 set_frame_rate(act_timestamp);
8262 } else if (frm_int > 0) // In this case the frame rate was set along
8263 { // with the port definition, start ts with 0
8264 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8265 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008266 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008267}
8268
8269void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8270{
Arun Menon906de572013-06-18 17:01:40 -07008271 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8272 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308273 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008274 OMX_U32 frame_rate = 0;
8275 int consumed_len = 0;
8276 OMX_U32 num_MB_in_frame;
8277 OMX_U32 recovery_sei_flags = 1;
8278 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008279
Arun Menon906de572013-06-18 17:01:40 -07008280 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008281 if (buf_index >= drv_ctx.extradata_info.count) {
8282 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8283 buf_index, drv_ctx.extradata_info.count);
8284 return;
8285 }
Arun Menon906de572013-06-18 17:01:40 -07008286 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8287 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8288 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308289
Arun Menon906de572013-06-18 17:01:40 -07008290 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308291 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008292 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008293 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308294 if (!secure_mode)
8295 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008296 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308297 else
8298 p_extra = m_other_extradata;
8299
Arun Menon906de572013-06-18 17:01:40 -07008300 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308301
8302 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008303 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308304 return;
8305 }
Arun Menon906de572013-06-18 17:01:40 -07008306 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8307 if (data) {
8308 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8309 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308310 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008311 DEBUG_PRINT_LOW("Invalid extra data size");
8312 break;
8313 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308314 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008315 switch ((unsigned long)data->eType) {
8316 case EXTRADATA_INTERLACE_VIDEO:
8317 struct msm_vidc_interlace_payload *payload;
8318 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008319 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008320 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008321 switch (payload->format) {
8322 case INTERLACE_FRAME_PROGRESSIVE:
8323 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8324 enable = 0;
8325 break;
8326 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8327 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8328 break;
8329 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8330 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8331 break;
8332 default:
8333 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8334 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8335 }
Arun Menon906de572013-06-18 17:01:40 -07008336 }
8337 if (m_enable_android_native_buffers)
8338 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8339 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308340 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008341 append_interlace_extradata(p_extra, payload->format,
8342 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008343 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8344 }
8345 break;
8346 case EXTRADATA_FRAME_RATE:
8347 struct msm_vidc_framerate_payload *frame_rate_payload;
8348 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8349 frame_rate = frame_rate_payload->frame_rate;
8350 break;
8351 case EXTRADATA_TIMESTAMP:
8352 struct msm_vidc_ts_payload *time_stamp_payload;
8353 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308354 time_stamp = time_stamp_payload->timestamp_lo;
8355 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8356 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008357 break;
8358 case EXTRADATA_NUM_CONCEALED_MB:
8359 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8360 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8361 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8362 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8363 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8364 break;
8365 case EXTRADATA_INDEX:
8366 int *etype;
8367 etype = (int *)(data->data);
8368 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8369 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8370 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8371 if (aspect_ratio_payload) {
8372 ((struct vdec_output_frameinfo *)
8373 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8374 ((struct vdec_output_frameinfo *)
8375 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8376 }
8377 }
8378 break;
8379 case EXTRADATA_RECOVERY_POINT_SEI:
8380 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8381 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8382 recovery_sei_flags = recovery_sei_payload->flags;
8383 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8384 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008385 DEBUG_PRINT_HIGH("");
8386 DEBUG_PRINT_HIGH("***************************************************");
8387 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8388 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008389 }
8390 break;
8391 case EXTRADATA_PANSCAN_WINDOW:
8392 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8393 break;
8394 case EXTRADATA_MPEG2_SEQDISP:
8395 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8396 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8397 if (seqdisp_payload) {
8398 m_disp_hor_size = seqdisp_payload->disp_width;
8399 m_disp_vert_size = seqdisp_payload->disp_height;
8400 }
8401 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308402 case EXTRADATA_S3D_FRAME_PACKING:
8403 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8404 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308405 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308406 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8407 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8408 }
8409 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008410 case EXTRADATA_FRAME_QP:
8411 struct msm_vidc_frame_qp_payload *qp_payload;
8412 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308413 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008414 append_qp_extradata(p_extra, qp_payload);
8415 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8416 }
8417 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008418 case EXTRADATA_FRAME_BITS_INFO:
8419 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8420 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308421 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008422 append_bitsinfo_extradata(p_extra, bits_info_payload);
8423 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8424 }
8425 break;
Arun Menon906de572013-06-18 17:01:40 -07008426 default:
8427 goto unrecognized_extradata;
8428 }
8429 consumed_len += data->nSize;
8430 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8431 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308432 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008433 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8434 append_frame_info_extradata(p_extra,
8435 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308436 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008437 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008438 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008439 }
8440 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008441unrecognized_extradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308442 if (client_extradata)
Arun Menon906de572013-06-18 17:01:40 -07008443 append_terminator_extradata(p_extra);
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308444 if (secure_mode) {
8445 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8446 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8447 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8448 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8449 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8450 }
Arun Menon906de572013-06-18 17:01:40 -07008451 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008452}
8453
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008454OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008455 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008456{
Arun Menon906de572013-06-18 17:01:40 -07008457 OMX_ERRORTYPE ret = OMX_ErrorNone;
8458 struct v4l2_control control;
8459 if (m_state != OMX_StateLoaded) {
8460 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8461 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008462 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008463 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008464 client_extradata, requested_extradata, enable, is_internal);
8465
8466 if (!is_internal) {
8467 if (enable)
8468 client_extradata |= requested_extradata;
8469 else
8470 client_extradata = client_extradata & ~requested_extradata;
8471 }
8472
8473 if (enable) {
8474 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8475 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8476 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8477 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8478 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008479 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008480 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308481 }
8482 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008483 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8484 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8485 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008486 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008487 }
8488 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8489 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8490 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008491 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008492 }
8493 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8494 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8495 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008496 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008497 }
8498 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8499 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8500 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008501 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008502 }
8503 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8504 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8505 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008506 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008507 }
8508 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8509 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8510 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8511 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008512 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008513 }
8514 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308515 }
8516 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008517 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8518 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
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 timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008521 }
8522 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308523 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8524 if (output_capability == V4L2_PIX_FMT_H264) {
8525 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8526 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8527 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8528 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8529 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8530 }
8531 } else {
8532 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8533 }
8534 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008535 if (requested_extradata & OMX_QP_EXTRADATA) {
8536 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8537 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8538 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8539 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8540 }
8541 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008542 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8543 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8544 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8545 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8546 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8547 }
8548 }
Arun Menon906de572013-06-18 17:01:40 -07008549 }
8550 ret = get_buffer_req(&drv_ctx.op_buf);
8551 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008552}
8553
8554OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8555{
Arun Menon906de572013-06-18 17:01:40 -07008556 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8557 OMX_U8 *data_ptr = extra->data, data = 0;
8558 while (byte_count < extra->nDataSize) {
8559 data = *data_ptr;
8560 while (data) {
8561 num_MB += (data&0x01);
8562 data >>= 1;
8563 }
8564 data_ptr++;
8565 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008566 }
Arun Menon906de572013-06-18 17:01:40 -07008567 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8568 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8569 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008570}
8571
8572void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8573{
Arun Menon906de572013-06-18 17:01:40 -07008574 if (!m_debug_extradata)
8575 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008576
8577 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308578 "============== Extra Data ==============\n"
8579 " Size: %lu\n"
8580 " Version: %lu\n"
8581 " PortIndex: %lu\n"
8582 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008583 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008584 extra->nSize, extra->nVersion.nVersion,
8585 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586
Arun Menon906de572013-06-18 17:01:40 -07008587 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8588 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8589 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308590 "------ Interlace Format ------\n"
8591 " Size: %lu\n"
8592 " Version: %lu\n"
8593 " PortIndex: %lu\n"
8594 " Is Interlace Format: %d\n"
8595 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008596 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008597 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8598 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8599 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8600 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8601
8602 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308603 "-------- Frame Format --------\n"
8604 " Picture Type: %d\n"
8605 " Interlace Type: %d\n"
8606 " Pan Scan Total Frame Num: %lu\n"
8607 " Concealed Macro Blocks: %lu\n"
8608 " frame rate: %lu\n"
8609 " Time Stamp: %llu\n"
8610 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008611 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008612 fminfo->ePicType,
8613 fminfo->interlaceType,
8614 fminfo->panScan.numWindows,
8615 fminfo->nConcealedMacroblocks,
8616 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308617 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008618 fminfo->aspectRatio.aspectRatioX,
8619 fminfo->aspectRatio.aspectRatioY);
8620
8621 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8622 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008623 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308624 " Pan Scan Frame Num: %lu\n"
8625 " Rectangle x: %ld\n"
8626 " Rectangle y: %ld\n"
8627 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008628 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008629 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8630 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8631 }
8632
8633 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308634 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8635 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8636 DEBUG_PRINT_HIGH(
8637 "------------------ Framepack Format ----------\n"
8638 " id: %lu \n"
8639 " cancel_flag: %lu \n"
8640 " type: %lu \n"
8641 " quincunx_sampling_flagFormat: %lu \n"
8642 " content_interpretation_type: %lu \n"
8643 " content_interpretation_type: %lu \n"
8644 " spatial_flipping_flag: %lu \n"
8645 " frame0_flipped_flag: %lu \n"
8646 " field_views_flag: %lu \n"
8647 " current_frame_is_frame0_flag: %lu \n"
8648 " frame0_self_contained_flag: %lu \n"
8649 " frame1_self_contained_flag: %lu \n"
8650 " frame0_grid_position_x: %lu \n"
8651 " frame0_grid_position_y: %lu \n"
8652 " frame1_grid_position_x: %lu \n"
8653 " frame1_grid_position_y: %lu \n"
8654 " reserved_byte: %lu \n"
8655 " repetition_period: %lu \n"
8656 " extension_flag: %lu \n"
8657 "================== End of Framepack ===========",
8658 framepack->id,
8659 framepack->cancel_flag,
8660 framepack->type,
8661 framepack->quincunx_sampling_flag,
8662 framepack->content_interpretation_type,
8663 framepack->spatial_flipping_flag,
8664 framepack->frame0_flipped_flag,
8665 framepack->field_views_flag,
8666 framepack->current_frame_is_frame0_flag,
8667 framepack->frame0_self_contained_flag,
8668 framepack->frame1_self_contained_flag,
8669 framepack->frame0_grid_position_x,
8670 framepack->frame0_grid_position_y,
8671 framepack->frame1_grid_position_x,
8672 framepack->frame1_grid_position_y,
8673 framepack->reserved_byte,
8674 framepack->repetition_period,
8675 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008676 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8677 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8678 DEBUG_PRINT_HIGH(
8679 "---- QP (Frame quantization parameter) ----\n"
8680 " Frame QP: %lu \n"
8681 "================ End of QP ================\n",
8682 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008683 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8684 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8685 DEBUG_PRINT_HIGH(
8686 "--------- Input bits information --------\n"
8687 " Header bits: %lu \n"
8688 " Frame bits: %lu \n"
8689 "===== End of Input bits information =====\n",
8690 bits->header_bits, bits->frame_bits);
Arun Menon906de572013-06-18 17:01:40 -07008691 } else if (extra->eType == OMX_ExtraDataNone) {
8692 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8693 } else {
8694 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008696}
8697
8698void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08008699 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008700{
Arun Menon906de572013-06-18 17:01:40 -07008701 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08008702
Arun Menon906de572013-06-18 17:01:40 -07008703 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8704 return;
8705 }
8706 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8707 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8708 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8709 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8710 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8711 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8712 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8713 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8714 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08008715
8716 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07008717 interlace_format->bInterlaceFormat = OMX_FALSE;
8718 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8719 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008720 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008721 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008722 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008723 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08008724 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008725 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08008726 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008727 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008728 } else {
8729 interlace_format->bInterlaceFormat = OMX_TRUE;
8730 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8731 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8732 }
8733 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008734}
8735
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008736void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008737 struct vdec_aspectratioinfo *aspect_ratio_info,
8738 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008739{
Arun Menon906de572013-06-18 17:01:40 -07008740 m_extradata = frame_info;
8741 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8742 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308743 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008744 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008745}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008746
8747void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008748 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308749 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008750 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008751{
Arun Menon906de572013-06-18 17:01:40 -07008752 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8753 struct msm_vidc_panscan_window *panscan_window;
8754 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008755 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008756 }
Arun Menon906de572013-06-18 17:01:40 -07008757 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8758 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8759 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8760 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8761 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8762 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8763 switch (picture_type) {
8764 case PICTURE_TYPE_I:
8765 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8766 break;
8767 case PICTURE_TYPE_P:
8768 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8769 break;
8770 case PICTURE_TYPE_B:
8771 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8772 break;
8773 default:
8774 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8775 }
8776 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8777 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8778 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8779 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8780 else
8781 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8782 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8783 frame_info->nConcealedMacroblocks = num_conceal_mb;
8784 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308785 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008786 frame_info->panScan.numWindows = 0;
8787 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8788 if (m_disp_hor_size && m_disp_vert_size) {
8789 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8790 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8791 }
8792 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008793
Arun Menon906de572013-06-18 17:01:40 -07008794 if (panscan_payload) {
8795 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8796 panscan_window = &panscan_payload->wnd[0];
8797 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8798 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8799 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8800 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8801 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8802 panscan_window++;
8803 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008804 }
Arun Menon906de572013-06-18 17:01:40 -07008805 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8806 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008807}
8808
8809void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8810{
Arun Menon906de572013-06-18 17:01:40 -07008811 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8812 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8813 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8814 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8815 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8816 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8817 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8818 *portDefn = m_port_def;
8819 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008820 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008821 portDefn->format.video.nFrameWidth,
8822 portDefn->format.video.nStride,
8823 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008824}
8825
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308826void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8827 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8828{
8829 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8830 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8831 DEBUG_PRINT_ERROR("frame packing size mismatch");
8832 return;
8833 }
8834 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8835 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8836 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8837 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8838 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8839 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8840 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8841 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8842 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8843 memcpy(&framepack->id, s3d_frame_packing_payload,
8844 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8845 memcpy(&m_frame_pack_arrangement, framepack,
8846 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8847 print_debug_extradata(extra);
8848}
8849
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008850void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8851 struct msm_vidc_frame_qp_payload *qp_payload)
8852{
8853 OMX_QCOM_EXTRADATA_QP * qp = NULL;
8854 if (!qp_payload) {
8855 DEBUG_PRINT_ERROR("QP payload is NULL");
8856 return;
8857 }
8858 extra->nSize = OMX_QP_EXTRADATA_SIZE;
8859 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8860 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8861 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
8862 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
8863 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8864 qp->nQP = qp_payload->frame_qp;
8865 print_debug_extradata(extra);
8866}
8867
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008868void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8869 struct msm_vidc_frame_bits_info_payload *bits_payload)
8870{
8871 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
8872 if (!bits_payload) {
8873 DEBUG_PRINT_ERROR("bits info payload is NULL");
8874 return;
8875 }
8876 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
8877 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8878 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8879 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
8880 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
8881 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
8882 bits->frame_bits = bits_payload->frame_bits;
8883 bits->header_bits = bits_payload->header_bits;
8884 print_debug_extradata(extra);
8885}
8886
Shalaj Jain273b3e02012-06-22 19:08:03 -07008887void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8888{
Arun Menon906de572013-06-18 17:01:40 -07008889 if (!client_extradata) {
8890 return;
8891 }
8892 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8893 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8894 extra->eType = OMX_ExtraDataNone;
8895 extra->nDataSize = 0;
8896 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008897
Arun Menon906de572013-06-18 17:01:40 -07008898 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008899}
8900
8901OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8902{
Arun Menon906de572013-06-18 17:01:40 -07008903 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8904 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008905 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008906 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008907 }
Arun Menon906de572013-06-18 17:01:40 -07008908 if (m_desc_buffer_ptr == NULL) {
8909 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8910 calloc( (sizeof(desc_buffer_hdr)),
8911 drv_ctx.ip_buf.actualcount);
8912 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008913 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008914 return OMX_ErrorInsufficientResources;
8915 }
8916 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008917
Arun Menon906de572013-06-18 17:01:40 -07008918 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8919 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008920 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008921 return OMX_ErrorInsufficientResources;
8922 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008923
Arun Menon906de572013-06-18 17:01:40 -07008924 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008925}
8926
8927void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8928{
Arun Menon906de572013-06-18 17:01:40 -07008929 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8930 if (m_demux_entries < 8192) {
8931 m_demux_offsets[m_demux_entries++] = address_offset;
8932 }
8933 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008934}
8935
8936void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8937{
Arun Menon906de572013-06-18 17:01:40 -07008938 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8939 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8940 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008941
Arun Menon906de572013-06-18 17:01:40 -07008942 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008943
Arun Menon906de572013-06-18 17:01:40 -07008944 while (index < bytes_to_parse) {
8945 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8946 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8947 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8948 (buf[index+2] == 0x01)) ) {
8949 //Found start code, insert address offset
8950 insert_demux_addr_offset(index);
8951 if (buf[index+2] == 0x01) // 3 byte start code
8952 index += 3;
8953 else //4 byte start code
8954 index += 4;
8955 } else
8956 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008957 }
Arun Menon906de572013-06-18 17:01:40 -07008958 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8959 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008960}
8961
8962OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8963{
Arun Menon906de572013-06-18 17:01:40 -07008964 //fix this, handle 3 byte start code, vc1 terminator entry
8965 OMX_U8 *p_demux_data = NULL;
8966 OMX_U32 desc_data = 0;
8967 OMX_U32 start_addr = 0;
8968 OMX_U32 nal_size = 0;
8969 OMX_U32 suffix_byte = 0;
8970 OMX_U32 demux_index = 0;
8971 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008972
Arun Menon906de572013-06-18 17:01:40 -07008973 if (m_desc_buffer_ptr == NULL) {
8974 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8975 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008976 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008977
Arun Menon906de572013-06-18 17:01:40 -07008978 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8979 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8980 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8981 return OMX_ErrorBadParameter;
8982 }
8983
8984 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8985
8986 if ( ((OMX_U8*)p_demux_data == NULL) ||
8987 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8988 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8989 return OMX_ErrorBadParameter;
8990 } else {
8991 for (; demux_index < m_demux_entries; demux_index++) {
8992 desc_data = 0;
8993 start_addr = m_demux_offsets[demux_index];
8994 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8995 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8996 } else {
8997 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8998 }
8999 if (demux_index < (m_demux_entries - 1)) {
9000 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9001 } else {
9002 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9003 }
9004 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9005 (void *)start_addr,
9006 suffix_byte,
9007 nal_size,
9008 demux_index);
9009 desc_data = (start_addr >> 3) << 1;
9010 desc_data |= (start_addr & 7) << 21;
9011 desc_data |= suffix_byte << 24;
9012
9013 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9014 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9015 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9016 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9017
9018 p_demux_data += 16;
9019 }
9020 if (codec_type_parse == CODEC_TYPE_VC1) {
9021 DEBUG_PRINT_LOW("VC1 terminator entry");
9022 desc_data = 0;
9023 desc_data = 0x82 << 24;
9024 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9025 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9026 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9027 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9028 p_demux_data += 16;
9029 m_demux_entries++;
9030 }
9031 //Add zero word to indicate end of descriptors
9032 memset(p_demux_data, 0, sizeof(OMX_U32));
9033
9034 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9035 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9036 }
9037 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9038 m_demux_entries = 0;
9039 DEBUG_PRINT_LOW("Demux table complete!");
9040 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009041}
9042
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009043OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009044{
Arun Menon906de572013-06-18 17:01:40 -07009045 OMX_ERRORTYPE err = OMX_ErrorNone;
9046 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9047 if (iDivXDrmDecrypt) {
9048 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9049 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009050 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009051 delete iDivXDrmDecrypt;
9052 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009053 }
9054 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009055 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009056 err = OMX_ErrorUndefined;
9057 }
9058 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009059}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009060
Vinay Kaliada4f4422013-01-09 10:45:03 -08009061omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9062{
Arun Menon906de572013-06-18 17:01:40 -07009063 enabled = false;
9064 omx = NULL;
9065 init_members();
9066 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009067}
9068
9069void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9070{
Arun Menon906de572013-06-18 17:01:40 -07009071 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009072}
9073
Arun Menon906de572013-06-18 17:01:40 -07009074void omx_vdec::allocate_color_convert_buf::init_members()
9075{
9076 allocated_count = 0;
9077 buffer_size_req = 0;
9078 buffer_alignment_req = 0;
9079 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9080 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9081 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9082 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009083#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009084 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009085#endif
Arun Menon906de572013-06-18 17:01:40 -07009086 for (int i = 0; i < MAX_COUNT; i++)
9087 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009088}
9089
Arun Menon906de572013-06-18 17:01:40 -07009090omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9091{
9092 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009093}
9094
9095bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9096{
Arun Menon906de572013-06-18 17:01:40 -07009097 bool status = true;
9098 unsigned int src_size = 0, destination_size = 0;
9099 OMX_COLOR_FORMATTYPE drv_color_format;
9100 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009101 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009102 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009103 }
Arun Menon906de572013-06-18 17:01:40 -07009104 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009105 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009106 return status;
9107 }
9108 pthread_mutex_lock(&omx->c_lock);
9109 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9110 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009111 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009112 status = false;
9113 goto fail_update_buf_req;
9114 }
9115 c2d.close();
9116 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9117 omx->drv_ctx.video_resolution.frame_width,
9118 NV12_128m,YCbCr420P);
9119 if (status) {
9120 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9121 if (status)
9122 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9123 }
9124 if (status) {
9125 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9126 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009127 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009128 "driver size %d destination size %d",
9129 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9130 status = false;
9131 c2d.close();
9132 buffer_size_req = 0;
9133 } else {
9134 buffer_size_req = destination_size;
9135 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9136 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9137 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9138 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9139 }
9140 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009141fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009142 pthread_mutex_unlock(&omx->c_lock);
9143 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009144}
9145
9146bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009147 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009148{
Arun Menon906de572013-06-18 17:01:40 -07009149 bool status = true;
9150 OMX_COLOR_FORMATTYPE drv_color_format;
9151 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009152 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009153 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009154 }
Arun Menon906de572013-06-18 17:01:40 -07009155 pthread_mutex_lock(&omx->c_lock);
9156 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9157 drv_color_format = (OMX_COLOR_FORMATTYPE)
9158 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9159 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009160 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009161 status = false;
9162 }
9163 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009164 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07009165 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009166 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009167 status = false;
9168 } else {
9169 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9170 if (enabled)
9171 c2d.destroy();
9172 enabled = false;
9173 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009174 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009175 status = false;
9176 } else
9177 enabled = true;
9178 }
9179 } else {
9180 if (enabled)
9181 c2d.destroy();
9182 enabled = false;
9183 }
9184 pthread_mutex_unlock(&omx->c_lock);
9185 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009186}
9187
9188OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9189{
Arun Menon906de572013-06-18 17:01:40 -07009190 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009191 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009192 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009193 }
Arun Menon906de572013-06-18 17:01:40 -07009194 if (!enabled)
9195 return omx->m_out_mem_ptr;
9196 return m_out_mem_ptr_client;
9197}
9198
9199 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9200(OMX_BUFFERHEADERTYPE *bufadd)
9201{
9202 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009203 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009204 return NULL;
9205 }
9206 if (!enabled)
9207 return bufadd;
9208
9209 unsigned index = 0;
9210 index = bufadd - omx->m_out_mem_ptr;
9211 if (index < omx->drv_ctx.op_buf.actualcount) {
9212 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9213 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9214 bool status;
9215 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9216 pthread_mutex_lock(&omx->c_lock);
9217 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9218 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9219 pmem_baseaddress[index], pmem_baseaddress[index]);
9220 pthread_mutex_unlock(&omx->c_lock);
9221 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9222 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009223 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009224 m_out_mem_ptr_client[index].nFilledLen = 0;
9225 return &m_out_mem_ptr_client[index];
9226 }
9227 } else
9228 m_out_mem_ptr_client[index].nFilledLen = 0;
9229 return &m_out_mem_ptr_client[index];
9230 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009231 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009232 return NULL;
9233}
9234
9235 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9236(OMX_BUFFERHEADERTYPE *bufadd)
9237{
9238 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009239 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009240 return NULL;
9241 }
9242 if (!enabled)
9243 return bufadd;
9244 unsigned index = 0;
9245 index = bufadd - m_out_mem_ptr_client;
9246 if (index < omx->drv_ctx.op_buf.actualcount) {
9247 return &omx->m_out_mem_ptr[index];
9248 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009249 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009250 return NULL;
9251}
9252 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9253(unsigned int &buffer_size)
9254{
9255 bool status = true;
9256 pthread_mutex_lock(&omx->c_lock);
9257 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009258 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009259 else {
9260 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009261 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009262 status = false;
9263 goto fail_get_buffer_size;
9264 }
9265 }
9266 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9267 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9268 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9269 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009270fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009271 pthread_mutex_unlock(&omx->c_lock);
9272 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009273}
9274OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009275 OMX_BUFFERHEADERTYPE *bufhdr)
9276{
9277 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009278
Arun Menon906de572013-06-18 17:01:40 -07009279 if (!enabled)
9280 return omx->free_output_buffer(bufhdr);
9281 if (enabled && omx->is_component_secure())
9282 return OMX_ErrorNone;
9283 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009284 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009285 return OMX_ErrorBadParameter;
9286 }
9287 index = bufhdr - m_out_mem_ptr_client;
9288 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009289 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009290 return OMX_ErrorBadParameter;
9291 }
9292 if (pmem_fd[index] > 0) {
9293 munmap(pmem_baseaddress[index], buffer_size_req);
9294 close(pmem_fd[index]);
9295 }
9296 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009297#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009298 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009299#endif
Arun Menon906de572013-06-18 17:01:40 -07009300 m_heap_ptr[index].video_heap_ptr = NULL;
9301 if (allocated_count > 0)
9302 allocated_count--;
9303 else
9304 allocated_count = 0;
9305 if (!allocated_count) {
9306 pthread_mutex_lock(&omx->c_lock);
9307 c2d.close();
9308 init_members();
9309 pthread_mutex_unlock(&omx->c_lock);
9310 }
9311 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009312}
9313
9314OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009315 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009316{
Arun Menon906de572013-06-18 17:01:40 -07009317 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9318 if (!enabled) {
9319 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9320 return eRet;
9321 }
9322 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009323 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009324 omx->is_component_secure());
9325 return OMX_ErrorUnsupportedSetting;
9326 }
9327 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009328 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9329 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009330 buffer_size_req,bytes);
9331 return OMX_ErrorBadParameter;
9332 }
9333 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009334 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009335 return OMX_ErrorInsufficientResources;
9336 }
9337 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9338 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9339 port,appData,omx->drv_ctx.op_buf.buffer_size);
9340 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009341 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009342 return eRet;
9343 }
9344 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309345 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009346 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009347 (temp_bufferHdr - omx->m_out_mem_ptr));
9348 return OMX_ErrorUndefined;
9349 }
9350 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009351#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009352 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9353 buffer_size_req,buffer_alignment_req,
9354 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9355 0);
9356 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9357 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009358 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009359 return OMX_ErrorInsufficientResources;
9360 }
9361 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9362 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009363
Arun Menon906de572013-06-18 17:01:40 -07009364 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009365 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009366 close(pmem_fd[i]);
9367 omx->free_ion_memory(&op_buf_ion_info[i]);
9368 return OMX_ErrorInsufficientResources;
9369 }
9370 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9371 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9372 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009373#endif
Arun Menon906de572013-06-18 17:01:40 -07009374 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9375 m_pmem_info_client[i].offset = 0;
9376 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9377 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9378 m_platform_list_client[i].nEntries = 1;
9379 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9380 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9381 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9382 m_out_mem_ptr_client[i].nFilledLen = 0;
9383 m_out_mem_ptr_client[i].nFlags = 0;
9384 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9385 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9386 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9387 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9388 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9389 m_out_mem_ptr_client[i].pAppPrivate = appData;
9390 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009391 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009392 allocated_count++;
9393 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009394}
9395
9396bool omx_vdec::is_component_secure()
9397{
Arun Menon906de572013-06-18 17:01:40 -07009398 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009399}
9400
9401bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9402{
Arun Menon906de572013-06-18 17:01:40 -07009403 bool status = true;
9404 if (!enabled) {
9405 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9406 dest_color_format = (OMX_COLOR_FORMATTYPE)
9407 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9408 else
9409 status = false;
9410 } else {
9411 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9412 status = false;
9413 } else
9414 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9415 }
9416 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009417}
Arun Menonbdb80b02013-08-12 17:45:54 -07009418
Arun Menonbdb80b02013-08-12 17:45:54 -07009419void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9420{
9421 int i = 0;
9422 bool buf_present = false;
9423 pthread_mutex_lock(&m_lock);
9424 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9425 //check the buffer fd, offset, uv addr with list contents
9426 //If present increment reference.
9427 if ((out_dynamic_list[i].fd == fd) &&
9428 (out_dynamic_list[i].offset == offset)) {
9429 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009430 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009431 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9432 buf_present = true;
9433 break;
9434 }
9435 }
9436 if (!buf_present) {
9437 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9438 //search for a entry to insert details of the new buffer
9439 if (out_dynamic_list[i].dup_fd == 0) {
9440 out_dynamic_list[i].fd = fd;
9441 out_dynamic_list[i].offset = offset;
9442 out_dynamic_list[i].dup_fd = dup(fd);
9443 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009444 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009445 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9446 break;
9447 }
9448 }
9449 }
9450 pthread_mutex_unlock(&m_lock);
9451}
9452
9453void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9454{
9455 int i = 0;
9456 pthread_mutex_lock(&m_lock);
9457 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9458 //check the buffer fd, offset, uv addr with list contents
9459 //If present decrement reference.
9460 if ((out_dynamic_list[i].fd == fd) &&
9461 (out_dynamic_list[i].offset == offset)) {
9462 out_dynamic_list[i].ref_count--;
9463 if (out_dynamic_list[i].ref_count == 0) {
9464 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009465 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009466 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9467 out_dynamic_list[i].dup_fd = 0;
9468 out_dynamic_list[i].fd = 0;
9469 out_dynamic_list[i].offset = 0;
9470 }
9471 break;
9472 }
9473 }
9474 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009475 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009476 }
9477 pthread_mutex_unlock(&m_lock);
9478}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009479
9480#ifdef _MSM8974_
9481void omx_vdec::send_codec_config() {
9482 if (codec_config_flag) {
9483 unsigned p1 = 0; // Parameter - 1
9484 unsigned p2 = 0; // Parameter - 2
9485 unsigned ident = 0;
9486 pthread_mutex_lock(&m_lock);
9487 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9488 while (m_etb_q.m_size) {
9489 m_etb_q.pop_entry(&p1,&p2,&ident);
9490 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9491 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9492 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9493 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9494 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9495 omx_report_error();
9496 }
9497 } else {
9498 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9499 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9500 }
9501 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9502 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9503 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9504 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9505 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9506 omx_report_error ();
9507 }
9508 } else {
9509 pending_input_buffers++;
9510 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9511 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9512 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9513 }
9514 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9515 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9516 (OMX_BUFFERHEADERTYPE *)p1);
9517 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9518 }
9519 }
9520 pthread_mutex_unlock(&m_lock);
9521 }
9522}
9523#endif