blob: ad47c7cc7fba66a8336e0c706f02b72cc9b6b5ac [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;
Deepak Verma24720fb2014-01-29 16:57:40 +0530231 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
232 struct vdec_msginfo vdec_msg;
233 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
234 vdec_msg.status_code=VDEC_S_SUCCESS;
235 DEBUG_PRINT_ERROR("HW Overload received");
236 if (omx->async_message_process(input,&vdec_msg) < 0) {
237 DEBUG_PRINT_HIGH("async_message_thread Exited");
238 break;
239 }
240 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_MAX_CLIENTS) {
241 struct vdec_msginfo vdec_msg;
242 vdec_msg.msgcode=VDEC_MSG_EVT_MAX_CLIENTS;
243 vdec_msg.status_code=VDEC_S_SUCCESS;
244 DEBUG_PRINT_ERROR("Max Client Reached");
245 if (omx->async_message_process(input,&vdec_msg) < 0) {
246 DEBUG_PRINT_HIGH("async_message_thread Exited");
247 break;
248 }
Arun Menon906de572013-06-18 17:01:40 -0700249 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
250 struct vdec_msginfo vdec_msg;
251 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
252 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700253 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700254 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700255 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700256 break;
257 }
Arun Menon45346052013-11-13 12:40:08 -0800258 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700259 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700260 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700261 omx->buf_ref_remove(ptr[0], ptr[1]);
262 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
263 unsigned int *ptr = (unsigned int *)dqevent.u.data;
264 struct vdec_msginfo vdec_msg;
265
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700266 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700267
268 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
269 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
270 v4l2_buf.length = omx->drv_ctx.num_planes;
271 v4l2_buf.m.planes = plane;
272 v4l2_buf.index = ptr[5];
273 v4l2_buf.flags = 0;
274
275 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
276 vdec_msg.status_code = VDEC_S_SUCCESS;
277 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
278 vdec_msg.msgdata.output_frame.len = 0;
279 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
280 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
281 (uint64_t)ptr[4];
282 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700283 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700284 break;
285 }
286 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700287 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700288 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700289 continue;
290 }
291 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700292 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700293 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700294 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700295}
296
297void* message_thread(void *input)
298{
Arun Menon906de572013-06-18 17:01:40 -0700299 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
300 unsigned char id;
301 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700303 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700304 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
305 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700306
Arun Menon906de572013-06-18 17:01:40 -0700307 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700308
Arun Menon906de572013-06-18 17:01:40 -0700309 if (0 == n) {
310 break;
311 }
312
313 if (1 == n) {
314 omx->process_event_cb(omx, id);
315 }
316 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700317 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700318 break;
319 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700320 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700321 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700322 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700323}
324
325void post_message(omx_vdec *omx, unsigned char id)
326{
Arun Menon906de572013-06-18 17:01:40 -0700327 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700328 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700329 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700330 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700331}
332
333// omx_cmd_queue destructor
334omx_vdec::omx_cmd_queue::~omx_cmd_queue()
335{
Arun Menon906de572013-06-18 17:01:40 -0700336 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700337}
338
339// omx cmd queue constructor
340omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
341{
342 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
343}
344
345// omx cmd queue insert
346bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
347{
Arun Menon906de572013-06-18 17:01:40 -0700348 bool ret = true;
349 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
350 m_q[m_write].id = id;
351 m_q[m_write].param1 = p1;
352 m_q[m_write].param2 = p2;
353 m_write++;
354 m_size ++;
355 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
356 m_write = 0;
357 }
358 } else {
359 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700360 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700361 }
Arun Menon906de572013-06-18 17:01:40 -0700362 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700363}
364
365// omx cmd queue pop
366bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
367{
Arun Menon906de572013-06-18 17:01:40 -0700368 bool ret = true;
369 if (m_size > 0) {
370 *id = m_q[m_read].id;
371 *p1 = m_q[m_read].param1;
372 *p2 = m_q[m_read].param2;
373 // Move the read pointer ahead
374 ++m_read;
375 --m_size;
376 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
377 m_read = 0;
378 }
379 } else {
380 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700381 }
Arun Menon906de572013-06-18 17:01:40 -0700382 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700383}
384
385// Retrieve the first mesg type in the queue
386unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
387{
388 return m_q[m_read].id;
389}
390
391#ifdef _ANDROID_
392omx_vdec::ts_arr_list::ts_arr_list()
393{
Arun Menon906de572013-06-18 17:01:40 -0700394 //initialize timestamps array
395 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700396}
397omx_vdec::ts_arr_list::~ts_arr_list()
398{
Arun Menon906de572013-06-18 17:01:40 -0700399 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400}
401
402bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
403{
Arun Menon906de572013-06-18 17:01:40 -0700404 bool ret = true;
405 bool duplicate_ts = false;
406 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700407
Arun Menon906de572013-06-18 17:01:40 -0700408 //insert at the first available empty location
409 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
410 if (!m_ts_arr_list[idx].valid) {
411 //found invalid or empty entry, save timestamp
412 m_ts_arr_list[idx].valid = true;
413 m_ts_arr_list[idx].timestamp = ts;
414 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
415 ts, idx);
416 break;
417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700418 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700419
Arun Menon906de572013-06-18 17:01:40 -0700420 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
421 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
422 ret = false;
423 }
424 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700425}
426
427bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
428{
Arun Menon906de572013-06-18 17:01:40 -0700429 bool ret = true;
430 int min_idx = -1;
431 OMX_TICKS min_ts = 0;
432 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700433
Arun Menon906de572013-06-18 17:01:40 -0700434 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700435
Arun Menon906de572013-06-18 17:01:40 -0700436 if (m_ts_arr_list[idx].valid) {
437 //found valid entry, save index
438 if (min_idx < 0) {
439 //first valid entry
440 min_ts = m_ts_arr_list[idx].timestamp;
441 min_idx = idx;
442 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
443 min_ts = m_ts_arr_list[idx].timestamp;
444 min_idx = idx;
445 }
446 }
447
Shalaj Jain273b3e02012-06-22 19:08:03 -0700448 }
449
Arun Menon906de572013-06-18 17:01:40 -0700450 if (min_idx < 0) {
451 //no valid entries found
452 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
453 ts = 0;
454 ret = false;
455 } else {
456 ts = m_ts_arr_list[min_idx].timestamp;
457 m_ts_arr_list[min_idx].valid = false;
458 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
459 ts, min_idx);
460 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700461
Arun Menon906de572013-06-18 17:01:40 -0700462 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700463
464}
465
466
467bool omx_vdec::ts_arr_list::reset_ts_list()
468{
Arun Menon906de572013-06-18 17:01:40 -0700469 bool ret = true;
470 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471
Arun Menon906de572013-06-18 17:01:40 -0700472 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
473 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
474 m_ts_arr_list[idx].valid = false;
475 }
476 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700477}
478#endif
479
480// factory function executed by the core to create instances
481void *get_omx_component_factory_fn(void)
482{
Arun Menon906de572013-06-18 17:01:40 -0700483 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700484}
485
486#ifdef _ANDROID_
487#ifdef USE_ION
488VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700489 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700490{
Arun Menon906de572013-06-18 17:01:40 -0700491 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700492}
493#else
494VideoHeap::VideoHeap(int fd, size_t size, void* base)
495{
496 // dup file descriptor, map once, use pmem
497 init(dup(fd), base, size, 0 , MEM_DEVICE);
498}
499#endif
500#endif // _ANDROID_
501/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700502 FUNCTION
503 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700504
Arun Menon906de572013-06-18 17:01:40 -0700505 DESCRIPTION
506 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700507
Arun Menon906de572013-06-18 17:01:40 -0700508 PARAMETERS
509 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700510
Arun Menon906de572013-06-18 17:01:40 -0700511 RETURN VALUE
512 None.
513 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800514omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700515 m_state(OMX_StateInvalid),
516 m_app_data(NULL),
517 m_inp_mem_ptr(NULL),
518 m_out_mem_ptr(NULL),
519 m_inp_err_count(0),
520 input_flush_progress (false),
521 output_flush_progress (false),
522 input_use_buffer (false),
523 output_use_buffer (false),
524 ouput_egl_buffers(false),
525 m_use_output_pmem(OMX_FALSE),
526 m_out_mem_region_smi(OMX_FALSE),
527 m_out_pvt_entry_pmem(OMX_FALSE),
528 pending_input_buffers(0),
529 pending_output_buffers(0),
530 m_out_bm_count(0),
531 m_inp_bm_count(0),
532 m_inp_bPopulated(OMX_FALSE),
533 m_out_bPopulated(OMX_FALSE),
534 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700535#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700536 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700537#endif
Arun Menon906de572013-06-18 17:01:40 -0700538 m_inp_bEnabled(OMX_TRUE),
539 m_out_bEnabled(OMX_TRUE),
540 m_in_alloc_cnt(0),
541 m_platform_list(NULL),
542 m_platform_entry(NULL),
543 m_pmem_info(NULL),
544 arbitrary_bytes (true),
545 psource_frame (NULL),
546 pdest_frame (NULL),
547 m_inp_heap_ptr (NULL),
548 m_phdr_pmem_ptr(NULL),
549 m_heap_inp_bm_count (0),
550 codec_type_parse ((codec_type)0),
551 first_frame_meta (true),
552 frame_count (0),
553 nal_count (0),
554 nal_length(0),
555 look_ahead_nal (false),
556 first_frame(0),
557 first_buffer(NULL),
558 first_frame_size (0),
559 m_device_file_ptr(NULL),
560 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700561 h264_last_au_ts(LLONG_MAX),
562 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530563 m_disp_hor_size(0),
564 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700565 prev_ts(LLONG_MAX),
566 rst_prev_ts(true),
567 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700568 in_reconfig(false),
569 m_display_id(NULL),
570 h264_parser(NULL),
571 client_extradata(0),
572 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530573 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700574#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700575 m_enable_android_native_buffers(OMX_FALSE),
576 m_use_android_native_buffers(OMX_FALSE),
577 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700578#endif
Arun Menon906de572013-06-18 17:01:40 -0700579 m_desc_buffer_ptr(NULL),
580 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530581 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800582 client_set_fps(false),
583 m_last_rendered_TS(-1)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700584{
Arun Menon906de572013-06-18 17:01:40 -0700585 /* Assumption is that , to begin with , we have all the frames with decoder */
586 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700587 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700588#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700589 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700590 property_get("vidc.debug.level", property_value, "0");
591 debug_level = atoi(property_value);
592 property_value[0] = '\0';
593
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700594 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
595
Arun Menon906de572013-06-18 17:01:40 -0700596 property_get("vidc.dec.debug.perf", property_value, "0");
597 perf_flag = atoi(property_value);
598 if (perf_flag) {
599 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
600 dec_time.start();
601 proc_frms = latency = 0;
602 }
603 prev_n_filled_len = 0;
604 property_value[0] = '\0';
605 property_get("vidc.dec.debug.ts", property_value, "0");
606 m_debug_timestamp = atoi(property_value);
607 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
608 if (m_debug_timestamp) {
609 time_stamp_dts.set_timestamp_reorder_mode(true);
610 time_stamp_dts.enable_debug_print(true);
611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700612
Arun Menon906de572013-06-18 17:01:40 -0700613 property_value[0] = '\0';
614 property_get("vidc.dec.debug.concealedmb", property_value, "0");
615 m_debug_concealedmb = atoi(property_value);
616 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700617
Arun Menon906de572013-06-18 17:01:40 -0700618 property_value[0] = '\0';
619 property_get("vidc.dec.profile.check", property_value, "0");
620 m_reject_avc_1080p_mp = atoi(property_value);
621 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530622
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700623 property_value[0] = '\0';
624 property_get("vidc.dec.log.in", property_value, "0");
625 m_debug.in_buffer_log = atoi(property_value);
626
627 property_value[0] = '\0';
628 property_get("vidc.dec.log.out", property_value, "0");
629 m_debug.out_buffer_log = atoi(property_value);
630 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
631
632 property_value[0] = '\0';
633 property_get("vidc.log.loc", property_value, "");
634 if (*property_value)
635 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800636
637 property_value[0] = '\0';
638 property_get("vidc.dec.120fps.enabled", property_value, "0");
639
640 //if this feature is not enabled then reset this value -ve
641 if(atoi(property_value)) {
642 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
643 m_last_rendered_TS = 0;
644 }
645
Shalaj Jain273b3e02012-06-22 19:08:03 -0700646#endif
Arun Menon906de572013-06-18 17:01:40 -0700647 memset(&m_cmp,0,sizeof(m_cmp));
648 memset(&m_cb,0,sizeof(m_cb));
649 memset (&drv_ctx,0,sizeof(drv_ctx));
650 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
651 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
652 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
653 m_demux_entries = 0;
654 msg_thread_id = 0;
655 async_thread_id = 0;
656 msg_thread_created = false;
657 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700658#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700659 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700660#endif
Arun Menon906de572013-06-18 17:01:40 -0700661 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530662 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700663 drv_ctx.timestamp_adjust = false;
664 drv_ctx.video_driver_fd = -1;
665 m_vendor_config.pData = NULL;
666 pthread_mutex_init(&m_lock, NULL);
667 pthread_mutex_init(&c_lock, NULL);
668 sem_init(&m_cmd_lock,0,0);
669 streaming[CAPTURE_PORT] =
670 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700671#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700672 char extradata_value[PROPERTY_VALUE_MAX] = {0};
673 property_get("vidc.dec.debug.extradata", extradata_value, "0");
674 m_debug_extradata = atoi(extradata_value);
675 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700676#endif
Arun Menon906de572013-06-18 17:01:40 -0700677 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
678 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700679 dynamic_buf_mode = false;
680 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800681 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800682 m_smoothstreaming_mode = false;
683 m_smoothstreaming_width = 0;
684 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530685 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700686}
687
Vinay Kalia85793762012-06-14 19:12:34 -0700688static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700689 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
690 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
691 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700692 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
693 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700694 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
695 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700696};
697
698static OMX_ERRORTYPE subscribe_to_events(int fd)
699{
Arun Menon906de572013-06-18 17:01:40 -0700700 OMX_ERRORTYPE eRet = OMX_ErrorNone;
701 struct v4l2_event_subscription sub;
702 int array_sz = sizeof(event_type)/sizeof(int);
703 int i,rc;
704 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700705 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700706 return OMX_ErrorBadParameter;
707 }
Vinay Kalia85793762012-06-14 19:12:34 -0700708
Arun Menon906de572013-06-18 17:01:40 -0700709 for (i = 0; i < array_sz; ++i) {
710 memset(&sub, 0, sizeof(sub));
711 sub.type = event_type[i];
712 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
713 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700714 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700715 break;
716 }
717 }
718 if (i < array_sz) {
719 for (--i; i >=0 ; i--) {
720 memset(&sub, 0, sizeof(sub));
721 sub.type = event_type[i];
722 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
723 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700724 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700725 }
726 eRet = OMX_ErrorNotImplemented;
727 }
728 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700729}
730
731
732static OMX_ERRORTYPE unsubscribe_to_events(int fd)
733{
Arun Menon906de572013-06-18 17:01:40 -0700734 OMX_ERRORTYPE eRet = OMX_ErrorNone;
735 struct v4l2_event_subscription sub;
736 int array_sz = sizeof(event_type)/sizeof(int);
737 int i,rc;
738 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700739 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700740 return OMX_ErrorBadParameter;
741 }
Vinay Kalia85793762012-06-14 19:12:34 -0700742
Arun Menon906de572013-06-18 17:01:40 -0700743 for (i = 0; i < array_sz; ++i) {
744 memset(&sub, 0, sizeof(sub));
745 sub.type = event_type[i];
746 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
747 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700748 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700749 break;
750 }
751 }
752 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700753}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700754
755/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700756 FUNCTION
757 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700758
Arun Menon906de572013-06-18 17:01:40 -0700759 DESCRIPTION
760 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700761
Arun Menon906de572013-06-18 17:01:40 -0700762 PARAMETERS
763 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700764
Arun Menon906de572013-06-18 17:01:40 -0700765 RETURN VALUE
766 None.
767 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700768omx_vdec::~omx_vdec()
769{
Arun Menon906de572013-06-18 17:01:40 -0700770 m_pmem_info = NULL;
771 struct v4l2_decoder_cmd dec;
772 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
773 if (m_pipe_in) close(m_pipe_in);
774 if (m_pipe_out) close(m_pipe_out);
775 m_pipe_in = -1;
776 m_pipe_out = -1;
777 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
778 if (msg_thread_created)
779 pthread_join(msg_thread_id,NULL);
780 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
781 dec.cmd = V4L2_DEC_CMD_STOP;
782 if (drv_ctx.video_driver_fd >=0 ) {
783 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700784 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700785 }
786 if (async_thread_created)
787 pthread_join(async_thread_id,NULL);
788 unsubscribe_to_events(drv_ctx.video_driver_fd);
789 close(drv_ctx.video_driver_fd);
790 pthread_mutex_destroy(&m_lock);
791 pthread_mutex_destroy(&c_lock);
792 sem_destroy(&m_cmd_lock);
793 if (perf_flag) {
794 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
795 dec_time.end();
796 }
797 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700798}
799
Arun Menon906de572013-06-18 17:01:40 -0700800int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
801{
802 struct v4l2_requestbuffers bufreq;
803 int rc = 0;
804 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
805 bufreq.memory = V4L2_MEMORY_USERPTR;
806 bufreq.count = 0;
807 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
808 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530809 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
810 bufreq.memory = V4L2_MEMORY_USERPTR;
811 bufreq.count = 0;
812 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
813 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700814 }
815 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700816}
817
Shalaj Jain273b3e02012-06-22 19:08:03 -0700818/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700819 FUNCTION
820 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700821
Arun Menon906de572013-06-18 17:01:40 -0700822 DESCRIPTION
823 IL Client callbacks are generated through this routine. The decoder
824 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700825
Arun Menon906de572013-06-18 17:01:40 -0700826 PARAMETERS
827 ctxt -- Context information related to the self.
828 id -- Event identifier. This could be any of the following:
829 1. Command completion event
830 2. Buffer done callback event
831 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700832
Arun Menon906de572013-06-18 17:01:40 -0700833 RETURN VALUE
834 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700835
Arun Menon906de572013-06-18 17:01:40 -0700836 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700837void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
838{
Arun Menon906de572013-06-18 17:01:40 -0700839 signed p1; // Parameter - 1
840 signed p2; // Parameter - 2
841 unsigned ident;
842 unsigned qsize=0; // qsize
843 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700844
Arun Menon906de572013-06-18 17:01:40 -0700845 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700846 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700847 __func__);
848 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700849 }
850
Arun Menon906de572013-06-18 17:01:40 -0700851 // Protect the shared queue data structure
852 do {
853 /*Read the message id's from the queue*/
854 pthread_mutex_lock(&pThis->m_lock);
855 qsize = pThis->m_cmd_q.m_size;
856 if (qsize) {
857 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700858 }
Arun Menon906de572013-06-18 17:01:40 -0700859
860 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
861 qsize = pThis->m_ftb_q.m_size;
862 if (qsize) {
863 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700865 }
Arun Menon906de572013-06-18 17:01:40 -0700866
867 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
868 qsize = pThis->m_etb_q.m_size;
869 if (qsize) {
870 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
871 }
872 }
873 pthread_mutex_unlock(&pThis->m_lock);
874
875 /*process message if we have one*/
876 if (qsize > 0) {
877 id = ident;
878 switch (id) {
879 case OMX_COMPONENT_GENERATE_EVENT:
880 if (pThis->m_cb.EventHandler) {
881 switch (p1) {
882 case OMX_CommandStateSet:
883 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700884 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700885 pThis->m_state);
886 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
887 OMX_EventCmdComplete, p1, p2, NULL);
888 break;
889
890 case OMX_EventError:
891 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700892 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700893 pThis->m_state = (OMX_STATETYPE) p2;
894 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
895 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
896 } else if (p2 == OMX_ErrorHardware) {
897 pThis->omx_report_error();
898 } else {
899 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
900 OMX_EventError, p2, (OMX_U32)NULL, NULL );
901 }
902 break;
903
904 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700905 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700906 if (BITMASK_PRESENT(&pThis->m_flags,
907 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
908 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
909 break;
910 }
911 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
912 OMX_ERRORTYPE eRet = OMX_ErrorNone;
913 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
914 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700915 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700916 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
917 pThis->in_reconfig = false;
918 if (eRet != OMX_ErrorNone) {
919 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
920 pThis->omx_report_error();
921 break;
922 }
923 }
924 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
925 OMX_EventCmdComplete, p1, p2, NULL );
926 break;
927 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
930 OMX_EventCmdComplete, p1, p2, NULL );
931 break;
932
933 default:
934 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
935 OMX_EventCmdComplete, p1, p2, NULL );
936 break;
937
938 }
939 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700940 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700941 }
942 break;
943 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
944 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
945 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700946 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700947 pThis->omx_report_error ();
948 }
949 break;
950 case OMX_COMPONENT_GENERATE_ETB:
951 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
952 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700953 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700954 pThis->omx_report_error ();
955 }
956 break;
957
958 case OMX_COMPONENT_GENERATE_FTB:
959 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
960 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700961 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700962 pThis->omx_report_error ();
963 }
964 break;
965
966 case OMX_COMPONENT_GENERATE_COMMAND:
967 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
968 (OMX_U32)p2,(OMX_PTR)NULL);
969 break;
970
971 case OMX_COMPONENT_GENERATE_EBD:
972
973 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700974 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700975 pThis->omx_report_error ();
976 } else {
977 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
978 pThis->m_inp_err_count++;
979 pThis->time_stamp_dts.remove_time_stamp(
980 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
981 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
982 ?true:false);
983 } else {
984 pThis->m_inp_err_count = 0;
985 }
986 if ( pThis->empty_buffer_done(&pThis->m_cmp,
987 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700988 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700989 pThis->omx_report_error ();
990 }
991 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700992 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700993 pThis->omx_report_error ();
994 }
995 }
996 break;
997 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
998 int64_t *timestamp = (int64_t *)p1;
999 if (p1) {
1000 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
1001 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1002 ?true:false);
1003 free(timestamp);
1004 }
1005 }
1006 break;
1007 case OMX_COMPONENT_GENERATE_FBD:
1008 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001009 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -07001010 pThis->omx_report_error ();
1011 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1012 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001013 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -07001014 pThis->omx_report_error ();
1015 }
1016 break;
1017
1018 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001019 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001020 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001021 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001022 } else {
1023 pThis->execute_input_flush();
1024 if (pThis->m_cb.EventHandler) {
1025 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001026 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001027 pThis->omx_report_error ();
1028 } else {
1029 /*Check if we need generate event for Flush done*/
1030 if (BITMASK_PRESENT(&pThis->m_flags,
1031 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1032 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001033 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001034 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1035 OMX_EventCmdComplete,OMX_CommandFlush,
1036 OMX_CORE_INPUT_PORT_INDEX,NULL );
1037 }
1038 if (BITMASK_PRESENT(&pThis->m_flags,
1039 OMX_COMPONENT_IDLE_PENDING)) {
1040 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001041 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001042 pThis->omx_report_error ();
1043 } else {
1044 pThis->streaming[OUTPUT_PORT] = false;
1045 }
1046 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001047 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001048 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1049 OMX_COMPONENT_GENERATE_STOP_DONE);
1050 }
1051 }
1052 }
1053 } else {
1054 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1055 }
1056 }
1057 break;
1058
1059 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001060 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001061 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001062 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001063 } else {
1064 pThis->execute_output_flush();
1065 if (pThis->m_cb.EventHandler) {
1066 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001067 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001068 pThis->omx_report_error ();
1069 } else {
1070 /*Check if we need generate event for Flush done*/
1071 if (BITMASK_PRESENT(&pThis->m_flags,
1072 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001073 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001074 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1075 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1076 OMX_EventCmdComplete,OMX_CommandFlush,
1077 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1078 }
1079 if (BITMASK_PRESENT(&pThis->m_flags,
1080 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001081 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001082 BITMASK_CLEAR (&pThis->m_flags,
1083 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1084 if (BITMASK_PRESENT(&pThis->m_flags,
1085 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1086 pThis->post_event(OMX_CommandPortDisable,
1087 OMX_CORE_OUTPUT_PORT_INDEX,
1088 OMX_COMPONENT_GENERATE_EVENT);
1089 BITMASK_CLEAR (&pThis->m_flags,
1090 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001091 BITMASK_CLEAR (&pThis->m_flags,
1092 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001093
1094 }
1095 }
1096
1097 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1098 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001099 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001100 pThis->omx_report_error ();
1101 break;
1102 }
1103 pThis->streaming[CAPTURE_PORT] = false;
1104 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001105 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001106 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1107 OMX_COMPONENT_GENERATE_STOP_DONE);
1108 }
1109 }
1110 }
1111 } else {
1112 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1113 }
1114 }
1115 break;
1116
1117 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001118 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001119
1120 if (pThis->m_cb.EventHandler) {
1121 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001122 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001123 pThis->omx_report_error ();
1124 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001125 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001126 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001127 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001128 // Send the callback now
1129 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1130 pThis->m_state = OMX_StateExecuting;
1131 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1132 OMX_EventCmdComplete,OMX_CommandStateSet,
1133 OMX_StateExecuting, NULL);
1134 } else if (BITMASK_PRESENT(&pThis->m_flags,
1135 OMX_COMPONENT_PAUSE_PENDING)) {
1136 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1137 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001138 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001139 pThis->omx_report_error ();
1140 }
1141 }
1142 }
1143 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001144 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001145 }
1146 break;
1147
1148 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001149 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001150 if (pThis->m_cb.EventHandler) {
1151 if (p2 != VDEC_S_SUCCESS) {
1152 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1153 pThis->omx_report_error ();
1154 } else {
1155 pThis->complete_pending_buffer_done_cbs();
1156 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001157 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001158 //Send the callback now
1159 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1160 pThis->m_state = OMX_StatePause;
1161 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1162 OMX_EventCmdComplete,OMX_CommandStateSet,
1163 OMX_StatePause, NULL);
1164 }
1165 }
1166 } else {
1167 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1168 }
1169
1170 break;
1171
1172 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001173 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001174 if (pThis->m_cb.EventHandler) {
1175 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001176 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001177 pThis->omx_report_error ();
1178 } else {
1179 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001180 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001181 // Send the callback now
1182 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1183 pThis->m_state = OMX_StateExecuting;
1184 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1185 OMX_EventCmdComplete,OMX_CommandStateSet,
1186 OMX_StateExecuting,NULL);
1187 }
1188 }
1189 } else {
1190 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1191 }
1192
1193 break;
1194
1195 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001196 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001197 if (pThis->m_cb.EventHandler) {
1198 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001199 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001200 pThis->omx_report_error ();
1201 } else {
1202 pThis->complete_pending_buffer_done_cbs();
1203 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001204 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001205 // Send the callback now
1206 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1207 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001208 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001209 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1210 OMX_EventCmdComplete,OMX_CommandStateSet,
1211 OMX_StateIdle,NULL);
1212 }
1213 }
1214 } else {
1215 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1216 }
1217
1218 break;
1219
1220 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001221 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001222
1223 if (p2 == OMX_IndexParamPortDefinition) {
1224 pThis->in_reconfig = true;
1225 }
1226 if (pThis->m_cb.EventHandler) {
1227 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1228 OMX_EventPortSettingsChanged, p1, p2, NULL );
1229 } else {
1230 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1231 }
1232
Arun Menon906de572013-06-18 17:01:40 -07001233 break;
1234
1235 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001236 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001237 if (pThis->m_cb.EventHandler) {
1238 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1239 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1240 } else {
1241 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1242 }
1243 pThis->prev_ts = LLONG_MAX;
1244 pThis->rst_prev_ts = true;
1245 break;
1246
1247 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001248 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001249 pThis->omx_report_error ();
1250 break;
1251
1252 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001253 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001254 pThis->omx_report_unsupported_setting();
1255 break;
1256
Deepak Verma24720fb2014-01-29 16:57:40 +05301257 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1258 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1259 pThis->omx_report_hw_overload();
1260 break;
1261
1262 case OMX_COMPONENT_GENERATE_MAX_CLIENTS_ERROR:
1263 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_MAX_CLIENTS_ERROR");
1264 pThis->omx_report_max_clients_reached();
1265 break;
1266
Arun Menon906de572013-06-18 17:01:40 -07001267 default:
1268 break;
1269 }
1270 }
1271 pthread_mutex_lock(&pThis->m_lock);
1272 qsize = pThis->m_cmd_q.m_size;
1273 if (pThis->m_state != OMX_StatePause)
1274 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1275 pthread_mutex_unlock(&pThis->m_lock);
1276 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001277
1278}
1279
Vinay Kaliab9e98102013-04-02 19:31:43 -07001280int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001281{
Arun Menon906de572013-06-18 17:01:40 -07001282 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301283 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1284 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001285 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001286 width, drv_ctx.video_resolution.frame_width,
1287 height,drv_ctx.video_resolution.frame_height);
1288 format_changed = 1;
1289 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001290 drv_ctx.video_resolution.frame_height = height;
1291 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001292 drv_ctx.video_resolution.scan_lines = scan_lines;
1293 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001294 rectangle.nLeft = 0;
1295 rectangle.nTop = 0;
1296 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1297 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001298 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001299}
1300
Arun Menon6836ba02013-02-19 20:37:40 -08001301OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1302{
Arun Menon906de572013-06-18 17:01:40 -07001303 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1304 OMX_MAX_STRINGNAME_SIZE) &&
1305 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1306 m_decoder_capability.max_width = 1280;
1307 m_decoder_capability.max_height = 720;
1308 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1309 }
Arun Menon888aa852013-05-30 11:24:42 -07001310
Arun Menon906de572013-06-18 17:01:40 -07001311 if ((drv_ctx.video_resolution.frame_width *
1312 drv_ctx.video_resolution.frame_height >
1313 m_decoder_capability.max_width *
1314 m_decoder_capability.max_height) ||
1315 (drv_ctx.video_resolution.frame_width*
1316 drv_ctx.video_resolution.frame_height <
1317 m_decoder_capability.min_width *
1318 m_decoder_capability.min_height)) {
1319 DEBUG_PRINT_ERROR(
1320 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1321 drv_ctx.video_resolution.frame_width,
1322 drv_ctx.video_resolution.frame_height,
1323 m_decoder_capability.min_width,
1324 m_decoder_capability.min_height,
1325 m_decoder_capability.max_width,
1326 m_decoder_capability.max_height);
1327 return OMX_ErrorUnsupportedSetting;
1328 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001329 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001330 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001331}
1332
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001333int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1334{
1335 if (m_debug.in_buffer_log && !m_debug.infile) {
1336 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1337 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1338 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1339 }
1340 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1341 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); }
1342 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1343 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1344 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1345 }
1346 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1347 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1348 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1349 }
1350 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1351 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1352 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1353 }
1354 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1355 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1356 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1357 }
1358 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1359 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1360 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1361 }
1362 m_debug.infile = fopen (m_debug.infile_name, "ab");
1363 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001364 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001365 m_debug.infile_name[0] = '\0';
1366 return -1;
1367 }
1368 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1369 struct ivf_file_header {
1370 OMX_U8 signature[4]; //='DKIF';
1371 OMX_U8 version ; //= 0;
1372 OMX_U8 headersize ; //= 32;
1373 OMX_U32 FourCC;
1374 OMX_U8 width;
1375 OMX_U8 height;
1376 OMX_U32 rate;
1377 OMX_U32 scale;
1378 OMX_U32 length;
1379 OMX_U8 unused[4];
1380 } file_header;
1381
1382 memset((void *)&file_header,0,sizeof(file_header));
1383 file_header.signature[0] = 'D';
1384 file_header.signature[1] = 'K';
1385 file_header.signature[2] = 'I';
1386 file_header.signature[3] = 'F';
1387 file_header.version = 0;
1388 file_header.headersize = 32;
1389 file_header.FourCC = 0x30385056;
1390 fwrite((const char *)&file_header,
1391 sizeof(file_header),1,m_debug.infile);
1392 }
1393 }
1394 if (m_debug.infile && buffer_addr && buffer_len) {
1395 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1396 struct vp8_ivf_frame_header {
1397 OMX_U32 framesize;
1398 OMX_U32 timestamp_lo;
1399 OMX_U32 timestamp_hi;
1400 } vp8_frame_header;
1401 vp8_frame_header.framesize = buffer_len;
1402 /* Currently FW doesn't use timestamp values */
1403 vp8_frame_header.timestamp_lo = 0;
1404 vp8_frame_header.timestamp_hi = 0;
1405 fwrite((const char *)&vp8_frame_header,
1406 sizeof(vp8_frame_header),1,m_debug.infile);
1407 }
1408 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1409 }
1410 return 0;
1411}
1412
1413int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1414 if (m_debug.out_buffer_log && !m_debug.outfile) {
1415 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1416 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1417 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1418 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001419 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001420 m_debug.outfile_name[0] = '\0';
1421 return -1;
1422 }
1423 }
1424 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1425 int buf_index = buffer - m_out_mem_ptr;
1426 int stride = drv_ctx.video_resolution.stride;
1427 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301428 if (m_smoothstreaming_mode) {
1429 stride = drv_ctx.video_resolution.frame_width;
1430 scanlines = drv_ctx.video_resolution.frame_height;
1431 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1432 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1433 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001434 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1435 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301436 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1437 drv_ctx.video_resolution.frame_width,
1438 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001439 int bytes_written = 0;
1440 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1441 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1442 temp += stride;
1443 }
1444 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1445 int stride_c = stride;
1446 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1447 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1448 temp += stride_c;
1449 }
1450 }
1451 return 0;
1452}
1453
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001455 FUNCTION
1456 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457
Arun Menon906de572013-06-18 17:01:40 -07001458 DESCRIPTION
1459 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001460
Arun Menon906de572013-06-18 17:01:40 -07001461 PARAMETERS
1462 ctxt -- Context information related to the self.
1463 id -- Event identifier. This could be any of the following:
1464 1. Command completion event
1465 2. Buffer done callback event
1466 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001467
Arun Menon906de572013-06-18 17:01:40 -07001468 RETURN VALUE
1469 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001470
Arun Menon906de572013-06-18 17:01:40 -07001471 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001472OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1473{
1474
Arun Menon906de572013-06-18 17:01:40 -07001475 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1476 struct v4l2_fmtdesc fdesc;
1477 struct v4l2_format fmt;
1478 struct v4l2_requestbuffers bufreq;
1479 struct v4l2_control control;
1480 struct v4l2_frmsizeenum frmsize;
1481 unsigned int alignment = 0,buffer_size = 0;
1482 int fds[2];
1483 int r,ret=0;
1484 bool codec_ambiguous = false;
1485 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001486 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001487
1488#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001489 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001490 property_get("ro.board.platform", platform_name, "0");
1491 if (!strncmp(platform_name, "msm8610", 7)) {
1492 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301493 is_q6_platform = true;
1494 maxSmoothStreamingWidth = 1280;
1495 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001496 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001497#endif
1498
Arun Menon906de572013-06-18 17:01:40 -07001499 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1500 struct v4l2_control control;
1501 secure_mode = true;
1502 arbitrary_bytes = false;
1503 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301504 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1505 OMX_MAX_STRINGNAME_SIZE)){
1506 secure_mode = true;
1507 arbitrary_bytes = false;
1508 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001509 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001510
Arun Menon906de572013-06-18 17:01:40 -07001511 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001512
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001513 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001514 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001515
Arun Menon906de572013-06-18 17:01:40 -07001516 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001517 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001518 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1519 close(0);
1520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001521
Arun Menon906de572013-06-18 17:01:40 -07001522 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001523 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001524 return OMX_ErrorInsufficientResources;
1525 }
1526 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1527 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001528
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001529 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001530 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001531 async_thread_created = true;
1532 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1533 }
1534 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001535 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001536 async_thread_created = false;
1537 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001538 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001539
Shalaj Jain273b3e02012-06-22 19:08:03 -07001540#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001541 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001542#endif
1543
Arun Menon906de572013-06-18 17:01:40 -07001544 // Copy the role information which provides the decoder kind
1545 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001546
Arun Menon906de572013-06-18 17:01:40 -07001547 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1548 OMX_MAX_STRINGNAME_SIZE)) {
1549 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1550 OMX_MAX_STRINGNAME_SIZE);
1551 drv_ctx.timestamp_adjust = true;
1552 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1553 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1554 output_capability=V4L2_PIX_FMT_MPEG4;
1555 /*Initialize Start Code for MPEG4*/
1556 codec_type_parse = CODEC_TYPE_MPEG4;
1557 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001558 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1559 OMX_MAX_STRINGNAME_SIZE)) {
1560 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1561 OMX_MAX_STRINGNAME_SIZE);
1562 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1563 output_capability = V4L2_PIX_FMT_MPEG2;
1564 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1565 /*Initialize Start Code for MPEG2*/
1566 codec_type_parse = CODEC_TYPE_MPEG2;
1567 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001568 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1569 OMX_MAX_STRINGNAME_SIZE)) {
1570 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001571 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001572 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1573 eCompressionFormat = OMX_VIDEO_CodingH263;
1574 output_capability = V4L2_PIX_FMT_H263;
1575 codec_type_parse = CODEC_TYPE_H263;
1576 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001577 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1578 OMX_MAX_STRINGNAME_SIZE)) {
1579 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001580 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001581 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1582 output_capability = V4L2_PIX_FMT_DIVX_311;
1583 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1584 codec_type_parse = CODEC_TYPE_DIVX;
1585 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001586
Arun Menon906de572013-06-18 17:01:40 -07001587 eRet = createDivxDrmContext();
1588 if (eRet != OMX_ErrorNone) {
1589 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1590 return eRet;
1591 }
1592 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1593 OMX_MAX_STRINGNAME_SIZE)) {
1594 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001595 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001596 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1597 output_capability = V4L2_PIX_FMT_DIVX;
1598 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1599 codec_type_parse = CODEC_TYPE_DIVX;
1600 codec_ambiguous = true;
1601 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001602
Arun Menon906de572013-06-18 17:01:40 -07001603 eRet = createDivxDrmContext();
1604 if (eRet != OMX_ErrorNone) {
1605 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1606 return eRet;
1607 }
1608 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1609 OMX_MAX_STRINGNAME_SIZE)) {
1610 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001611 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001612 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1613 output_capability = V4L2_PIX_FMT_DIVX;
1614 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1615 codec_type_parse = CODEC_TYPE_DIVX;
1616 codec_ambiguous = true;
1617 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001618
Arun Menon906de572013-06-18 17:01:40 -07001619 eRet = createDivxDrmContext();
1620 if (eRet != OMX_ErrorNone) {
1621 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1622 return eRet;
1623 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001624
Arun Menon906de572013-06-18 17:01:40 -07001625 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1626 OMX_MAX_STRINGNAME_SIZE)) {
1627 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1628 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1629 output_capability=V4L2_PIX_FMT_H264;
1630 eCompressionFormat = OMX_VIDEO_CodingAVC;
1631 codec_type_parse = CODEC_TYPE_H264;
1632 m_frame_parser.init_start_codes (codec_type_parse);
1633 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001634 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1635 OMX_MAX_STRINGNAME_SIZE)) {
1636 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1637 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1638 eCompressionFormat = OMX_VIDEO_CodingWMV;
1639 codec_type_parse = CODEC_TYPE_VC1;
1640 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1641 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001642 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1643 OMX_MAX_STRINGNAME_SIZE)) {
1644 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1645 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1646 eCompressionFormat = OMX_VIDEO_CodingWMV;
1647 codec_type_parse = CODEC_TYPE_VC1;
1648 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1649 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001650 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1651 OMX_MAX_STRINGNAME_SIZE)) {
1652 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1653 output_capability=V4L2_PIX_FMT_VP8;
1654 eCompressionFormat = OMX_VIDEO_CodingVPX;
1655 codec_type_parse = CODEC_TYPE_VP8;
1656 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001657
Arun Menon906de572013-06-18 17:01:40 -07001658 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001659 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001660 eRet = OMX_ErrorInvalidComponentName;
1661 }
Arun Menon906de572013-06-18 17:01:40 -07001662 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001663
Arun Menon906de572013-06-18 17:01:40 -07001664 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001665 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1666 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1667 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001668 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001669 eRet = OMX_ErrorInsufficientResources;
1670 }
1671
Arun Menon906de572013-06-18 17:01:40 -07001672 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673
Arun Menon906de572013-06-18 17:01:40 -07001674 struct v4l2_capability cap;
1675 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1676 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001677 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001678 /*TODO: How to handle this case */
1679 } else {
1680 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001681 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001682 cap.bus_info, cap.version, cap.capabilities);
1683 }
1684 ret=0;
1685 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1686 fdesc.index=0;
1687 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001688 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001689 fdesc.pixelformat, fdesc.flags);
1690 fdesc.index++;
1691 }
1692 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1693 fdesc.index=0;
1694 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001695
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001696 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001697 fdesc.pixelformat, fdesc.flags);
1698 fdesc.index++;
1699 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001700 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001701 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1702 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1703 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1704 fmt.fmt.pix_mp.pixelformat = output_capability;
1705 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1706 if (ret) {
1707 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001708 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001709 return OMX_ErrorInsufficientResources;
1710 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001711 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001712 if (codec_ambiguous) {
1713 if (output_capability == V4L2_PIX_FMT_DIVX) {
1714 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001715
Arun Menon906de572013-06-18 17:01:40 -07001716 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1717 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1718 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1719 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1720 } else {
1721 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1722 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001723
Arun Menon906de572013-06-18 17:01:40 -07001724 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1725 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1726 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001727 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001728 }
1729 } else {
1730 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1731 }
1732 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001733
Jia Meng3a3c6492013-12-19 17:16:52 +08001734 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1735 m_conceal_color= atoi(property_value);
1736 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1737 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1738 control.value = m_conceal_color;
1739 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1740 if (ret) {
1741 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1742 }
1743
Arun Menon906de572013-06-18 17:01:40 -07001744 //Get the hardware capabilities
1745 memset((void *)&frmsize,0,sizeof(frmsize));
1746 frmsize.index = 0;
1747 frmsize.pixel_format = output_capability;
1748 ret = ioctl(drv_ctx.video_driver_fd,
1749 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1750 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001751 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001752 return OMX_ErrorHardware;
1753 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001754
Arun Menon906de572013-06-18 17:01:40 -07001755 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1756 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1757 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1758 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1759 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1760 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001761
Arun Menon906de572013-06-18 17:01:40 -07001762 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1763 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1764 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1765 fmt.fmt.pix_mp.pixelformat = capture_capability;
1766 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1767 if (ret) {
1768 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001769 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001770 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001771 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001772 if (secure_mode) {
1773 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1774 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001775 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001776 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1777 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001778 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001779 return OMX_ErrorInsufficientResources;
1780 }
1781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001782
Arun Menon906de572013-06-18 17:01:40 -07001783 /*Get the Buffer requirements for input and output ports*/
1784 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1785 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1786 if (secure_mode) {
1787 drv_ctx.op_buf.alignment=SZ_1M;
1788 drv_ctx.ip_buf.alignment=SZ_1M;
1789 } else {
1790 drv_ctx.op_buf.alignment=SZ_4K;
1791 drv_ctx.ip_buf.alignment=SZ_4K;
1792 }
1793 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1794 drv_ctx.extradata = 0;
1795 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1796 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1797 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1798 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1799 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800
Vinay Kalia5713bb32013-01-16 18:39:59 -08001801 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001802#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001803 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1804 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1805 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001806#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001807 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001808 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001809 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001810 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1811 if (m_frame_parser.mutils == NULL) {
1812 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001813
Arun Menon906de572013-06-18 17:01:40 -07001814 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001815 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001816 eRet = OMX_ErrorInsufficientResources;
1817 } else {
1818 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1819 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1820 h264_scratch.nFilledLen = 0;
1821 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001822
Arun Menon906de572013-06-18 17:01:40 -07001823 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001824 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001825 return OMX_ErrorInsufficientResources;
1826 }
1827 m_frame_parser.mutils->initialize_frame_checking_environment();
1828 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1829 }
1830 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001831
Arun Menon906de572013-06-18 17:01:40 -07001832 h264_parser = new h264_stream_parser();
1833 if (!h264_parser) {
1834 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1835 eRet = OMX_ErrorInsufficientResources;
1836 }
1837 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001838
Arun Menon906de572013-06-18 17:01:40 -07001839 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001840 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001841 eRet = OMX_ErrorInsufficientResources;
1842 } else {
1843 int temp1[2];
1844 if (fds[0] == 0 || fds[1] == 0) {
1845 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001846 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001847 return OMX_ErrorInsufficientResources;
1848 }
1849 //close (fds[0]);
1850 //close (fds[1]);
1851 fds[0] = temp1 [0];
1852 fds[1] = temp1 [1];
1853 }
1854 m_pipe_in = fds[0];
1855 m_pipe_out = fds[1];
1856 msg_thread_created = true;
1857 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001858
Arun Menon906de572013-06-18 17:01:40 -07001859 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001860 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001861 msg_thread_created = false;
1862 eRet = OMX_ErrorInsufficientResources;
1863 }
1864 }
1865 }
1866
1867 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001868 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001869 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001870 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001871 }
1872 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1873 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001874}
1875
1876/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001877 FUNCTION
1878 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001879
Arun Menon906de572013-06-18 17:01:40 -07001880 DESCRIPTION
1881 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001882
Arun Menon906de572013-06-18 17:01:40 -07001883 PARAMETERS
1884 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001885
Arun Menon906de572013-06-18 17:01:40 -07001886 RETURN VALUE
1887 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001888
Arun Menon906de572013-06-18 17:01:40 -07001889 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001890OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001891(
1892 OMX_IN OMX_HANDLETYPE hComp,
1893 OMX_OUT OMX_STRING componentName,
1894 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1895 OMX_OUT OMX_VERSIONTYPE* specVersion,
1896 OMX_OUT OMX_UUIDTYPE* componentUUID
1897 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001898{
Arun Menon906de572013-06-18 17:01:40 -07001899 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001900 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001901 return OMX_ErrorInvalidState;
1902 }
Arun Menon906de572013-06-18 17:01:40 -07001903 /* TBD -- Return the proper version */
1904 if (specVersion) {
1905 specVersion->nVersion = OMX_SPEC_VERSION;
1906 }
1907 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001908}
1909/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001910 FUNCTION
1911 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001912
Arun Menon906de572013-06-18 17:01:40 -07001913 DESCRIPTION
1914 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001915
Arun Menon906de572013-06-18 17:01:40 -07001916 PARAMETERS
1917 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001918
Arun Menon906de572013-06-18 17:01:40 -07001919 RETURN VALUE
1920 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001921
Arun Menon906de572013-06-18 17:01:40 -07001922 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001923OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001924 OMX_IN OMX_COMMANDTYPE cmd,
1925 OMX_IN OMX_U32 param1,
1926 OMX_IN OMX_PTR cmdData
1927 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001928{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001929 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001930 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001931 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001932 return OMX_ErrorInvalidState;
1933 }
1934 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001935 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001936 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001937 "to invalid port: %lu", param1);
1938 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001939 }
1940 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1941 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001942 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001943 return OMX_ErrorNone;
1944}
1945
1946/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001947 FUNCTION
1948 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001949
Arun Menon906de572013-06-18 17:01:40 -07001950 DESCRIPTION
1951 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001952
Arun Menon906de572013-06-18 17:01:40 -07001953 PARAMETERS
1954 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001955
Arun Menon906de572013-06-18 17:01:40 -07001956 RETURN VALUE
1957 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001958
Arun Menon906de572013-06-18 17:01:40 -07001959 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001960OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001961 OMX_IN OMX_COMMANDTYPE cmd,
1962 OMX_IN OMX_U32 param1,
1963 OMX_IN OMX_PTR cmdData
1964 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001965{
Arun Menon906de572013-06-18 17:01:40 -07001966 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1967 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1968 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001969
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001970 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1971 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001972 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001973
Arun Menon906de572013-06-18 17:01:40 -07001974 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001975 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1976 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001977 /***************************/
1978 /* Current State is Loaded */
1979 /***************************/
1980 if (m_state == OMX_StateLoaded) {
1981 if (eState == OMX_StateIdle) {
1982 //if all buffers are allocated or all ports disabled
1983 if (allocate_done() ||
1984 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001985 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001986 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001987 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001988 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1989 // Skip the event notification
1990 bFlag = 0;
1991 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001992 }
Arun Menon906de572013-06-18 17:01:40 -07001993 /* Requesting transition from Loaded to Loaded */
1994 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001995 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001996 post_event(OMX_EventError,OMX_ErrorSameState,\
1997 OMX_COMPONENT_GENERATE_EVENT);
1998 eRet = OMX_ErrorSameState;
1999 }
2000 /* Requesting transition from Loaded to WaitForResources */
2001 else if (eState == OMX_StateWaitForResources) {
2002 /* Since error is None , we will post an event
2003 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002004 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002005 }
2006 /* Requesting transition from Loaded to Executing */
2007 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002008 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002009 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2010 OMX_COMPONENT_GENERATE_EVENT);
2011 eRet = OMX_ErrorIncorrectStateTransition;
2012 }
2013 /* Requesting transition from Loaded to Pause */
2014 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002015 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002016 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2017 OMX_COMPONENT_GENERATE_EVENT);
2018 eRet = OMX_ErrorIncorrectStateTransition;
2019 }
2020 /* Requesting transition from Loaded to Invalid */
2021 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002022 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002023 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2024 eRet = OMX_ErrorInvalidState;
2025 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002026 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002027 eState);
2028 eRet = OMX_ErrorBadParameter;
2029 }
2030 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002031
Arun Menon906de572013-06-18 17:01:40 -07002032 /***************************/
2033 /* Current State is IDLE */
2034 /***************************/
2035 else if (m_state == OMX_StateIdle) {
2036 if (eState == OMX_StateLoaded) {
2037 if (release_done()) {
2038 /*
2039 Since error is None , we will post an event at the end
2040 of this function definition
2041 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002042 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002043 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002044 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002045 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2046 // Skip the event notification
2047 bFlag = 0;
2048 }
2049 }
2050 /* Requesting transition from Idle to Executing */
2051 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002052 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002053 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2054 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002055 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002056 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002057 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002058 }
2059 /* Requesting transition from Idle to Idle */
2060 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002061 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002062 post_event(OMX_EventError,OMX_ErrorSameState,\
2063 OMX_COMPONENT_GENERATE_EVENT);
2064 eRet = OMX_ErrorSameState;
2065 }
2066 /* Requesting transition from Idle to WaitForResources */
2067 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002068 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002069 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2070 OMX_COMPONENT_GENERATE_EVENT);
2071 eRet = OMX_ErrorIncorrectStateTransition;
2072 }
2073 /* Requesting transition from Idle to Pause */
2074 else if (eState == OMX_StatePause) {
2075 /*To pause the Video core we need to start the driver*/
2076 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2077 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002078 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002079 omx_report_error ();
2080 eRet = OMX_ErrorHardware;
2081 } else {
2082 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002083 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002084 bFlag = 0;
2085 }
2086 }
2087 /* Requesting transition from Idle to Invalid */
2088 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002089 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002090 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2091 eRet = OMX_ErrorInvalidState;
2092 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002093 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002094 eRet = OMX_ErrorBadParameter;
2095 }
2096 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002097
Arun Menon906de572013-06-18 17:01:40 -07002098 /******************************/
2099 /* Current State is Executing */
2100 /******************************/
2101 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002102 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002103 /* Requesting transition from Executing to Idle */
2104 if (eState == OMX_StateIdle) {
2105 /* Since error is None , we will post an event
2106 at the end of this function definition
2107 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002108 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002109 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2110 if (!sem_posted) {
2111 sem_posted = 1;
2112 sem_post (&m_cmd_lock);
2113 execute_omx_flush(OMX_ALL);
2114 }
2115 bFlag = 0;
2116 }
2117 /* Requesting transition from Executing to Paused */
2118 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002119 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002120 m_state = OMX_StatePause;
2121 bFlag = 1;
2122 }
2123 /* Requesting transition from Executing to Loaded */
2124 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002125 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002126 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2127 OMX_COMPONENT_GENERATE_EVENT);
2128 eRet = OMX_ErrorIncorrectStateTransition;
2129 }
2130 /* Requesting transition from Executing to WaitForResources */
2131 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002132 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002133 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2134 OMX_COMPONENT_GENERATE_EVENT);
2135 eRet = OMX_ErrorIncorrectStateTransition;
2136 }
2137 /* Requesting transition from Executing to Executing */
2138 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002139 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002140 post_event(OMX_EventError,OMX_ErrorSameState,\
2141 OMX_COMPONENT_GENERATE_EVENT);
2142 eRet = OMX_ErrorSameState;
2143 }
2144 /* Requesting transition from Executing to Invalid */
2145 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002146 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002147 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2148 eRet = OMX_ErrorInvalidState;
2149 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002150 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002151 eRet = OMX_ErrorBadParameter;
2152 }
2153 }
2154 /***************************/
2155 /* Current State is Pause */
2156 /***************************/
2157 else if (m_state == OMX_StatePause) {
2158 /* Requesting transition from Pause to Executing */
2159 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002160 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002161 m_state = OMX_StateExecuting;
2162 bFlag = 1;
2163 }
2164 /* Requesting transition from Pause to Idle */
2165 else if (eState == OMX_StateIdle) {
2166 /* Since error is None , we will post an event
2167 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002168 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002169 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2170 if (!sem_posted) {
2171 sem_posted = 1;
2172 sem_post (&m_cmd_lock);
2173 execute_omx_flush(OMX_ALL);
2174 }
2175 bFlag = 0;
2176 }
2177 /* Requesting transition from Pause to loaded */
2178 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002179 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002180 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2181 OMX_COMPONENT_GENERATE_EVENT);
2182 eRet = OMX_ErrorIncorrectStateTransition;
2183 }
2184 /* Requesting transition from Pause to WaitForResources */
2185 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002186 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002187 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2188 OMX_COMPONENT_GENERATE_EVENT);
2189 eRet = OMX_ErrorIncorrectStateTransition;
2190 }
2191 /* Requesting transition from Pause to Pause */
2192 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002193 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002194 post_event(OMX_EventError,OMX_ErrorSameState,\
2195 OMX_COMPONENT_GENERATE_EVENT);
2196 eRet = OMX_ErrorSameState;
2197 }
2198 /* Requesting transition from Pause to Invalid */
2199 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002200 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002201 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2202 eRet = OMX_ErrorInvalidState;
2203 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002204 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002205 eRet = OMX_ErrorBadParameter;
2206 }
2207 }
2208 /***************************/
2209 /* Current State is WaitForResources */
2210 /***************************/
2211 else if (m_state == OMX_StateWaitForResources) {
2212 /* Requesting transition from WaitForResources to Loaded */
2213 if (eState == OMX_StateLoaded) {
2214 /* Since error is None , we will post an event
2215 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002216 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002217 }
2218 /* Requesting transition from WaitForResources to WaitForResources */
2219 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002220 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002221 post_event(OMX_EventError,OMX_ErrorSameState,
2222 OMX_COMPONENT_GENERATE_EVENT);
2223 eRet = OMX_ErrorSameState;
2224 }
2225 /* Requesting transition from WaitForResources to Executing */
2226 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002227 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002228 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2229 OMX_COMPONENT_GENERATE_EVENT);
2230 eRet = OMX_ErrorIncorrectStateTransition;
2231 }
2232 /* Requesting transition from WaitForResources to Pause */
2233 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002234 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002235 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2236 OMX_COMPONENT_GENERATE_EVENT);
2237 eRet = OMX_ErrorIncorrectStateTransition;
2238 }
2239 /* Requesting transition from WaitForResources to Invalid */
2240 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002241 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002242 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2243 eRet = OMX_ErrorInvalidState;
2244 }
2245 /* Requesting transition from WaitForResources to Loaded -
2246 is NOT tested by Khronos TS */
2247
2248 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002249 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002250 eRet = OMX_ErrorBadParameter;
2251 }
2252 }
2253 /********************************/
2254 /* Current State is Invalid */
2255 /*******************************/
2256 else if (m_state == OMX_StateInvalid) {
2257 /* State Transition from Inavlid to any state */
2258 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2259 || OMX_StateIdle || OMX_StateExecuting
2260 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002261 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002262 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2263 OMX_COMPONENT_GENERATE_EVENT);
2264 eRet = OMX_ErrorInvalidState;
2265 }
2266 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002267 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002268 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002269#ifdef _MSM8974_
2270 send_codec_config();
2271#endif
Arun Menon906de572013-06-18 17:01:40 -07002272 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2273 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2274 }
2275 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2276 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2277 }
2278 if (!sem_posted) {
2279 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002280 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002281 sem_post (&m_cmd_lock);
2282 execute_omx_flush(param1);
2283 }
2284 bFlag = 0;
2285 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002286 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002287 "with param1: %lu", param1);
2288 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2289 m_inp_bEnabled = OMX_TRUE;
2290
2291 if ( (m_state == OMX_StateLoaded &&
2292 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2293 || allocate_input_done()) {
2294 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2295 OMX_COMPONENT_GENERATE_EVENT);
2296 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002297 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002298 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2299 // Skip the event notification
2300 bFlag = 0;
2301 }
2302 }
2303 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002304 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002305 m_out_bEnabled = OMX_TRUE;
2306
2307 if ( (m_state == OMX_StateLoaded &&
2308 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2309 || (allocate_output_done())) {
2310 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2311 OMX_COMPONENT_GENERATE_EVENT);
2312
2313 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002314 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002315 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2316 // Skip the event notification
2317 bFlag = 0;
2318 }
2319 }
2320 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002321 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002322 "with param1: %lu", param1);
2323 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002324 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002325 m_inp_bEnabled = OMX_FALSE;
2326 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2327 && release_input_done()) {
2328 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2329 OMX_COMPONENT_GENERATE_EVENT);
2330 } else {
2331 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2332 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2333 if (!sem_posted) {
2334 sem_posted = 1;
2335 sem_post (&m_cmd_lock);
2336 }
2337 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2338 }
2339
2340 // Skip the event notification
2341 bFlag = 0;
2342 }
2343 }
2344 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2345 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002346 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002347 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2348 && release_output_done()) {
2349 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2350 OMX_COMPONENT_GENERATE_EVENT);
2351 } else {
2352 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2353 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2354 if (!sem_posted) {
2355 sem_posted = 1;
2356 sem_post (&m_cmd_lock);
2357 }
2358 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2359 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2360 }
2361 // Skip the event notification
2362 bFlag = 0;
2363
2364 }
2365 }
2366 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002367 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002368 eRet = OMX_ErrorNotImplemented;
2369 }
2370 if (eRet == OMX_ErrorNone && bFlag) {
2371 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2372 }
2373 if (!sem_posted) {
2374 sem_post(&m_cmd_lock);
2375 }
2376
2377 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002378}
2379
2380/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002381 FUNCTION
2382 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002383
Arun Menon906de572013-06-18 17:01:40 -07002384 DESCRIPTION
2385 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002386
Arun Menon906de572013-06-18 17:01:40 -07002387 PARAMETERS
2388 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002389
Arun Menon906de572013-06-18 17:01:40 -07002390 RETURN VALUE
2391 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002392
Arun Menon906de572013-06-18 17:01:40 -07002393 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002394bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2395{
Arun Menon906de572013-06-18 17:01:40 -07002396 bool bRet = false;
2397 struct v4l2_plane plane;
2398 struct v4l2_buffer v4l2_buf;
2399 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302400 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002401 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2402 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002403
Arun Menon906de572013-06-18 17:01:40 -07002404 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002405
Arun Menon906de572013-06-18 17:01:40 -07002406 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2407 output_flush_progress = true;
2408 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2409 } else {
2410 /* XXX: The driver/hardware does not support flushing of individual ports
2411 * in all states. So we pretty much need to flush both ports internally,
2412 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2413 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2414 * we automatically omit sending the FLUSH done for the "opposite" port. */
2415 input_flush_progress = true;
2416 output_flush_progress = true;
2417 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2418 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002419
Arun Menon906de572013-06-18 17:01:40 -07002420 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002421 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002422 bRet = false;
2423 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002424
Arun Menon906de572013-06-18 17:01:40 -07002425 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002426}
2427/*=========================================================================
2428FUNCTION : execute_output_flush
2429
2430DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002431Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002432
2433PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002434None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002435
2436RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002437true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002438==========================================================================*/
2439bool omx_vdec::execute_output_flush()
2440{
Arun Menon906de572013-06-18 17:01:40 -07002441 unsigned p1 = 0; // Parameter - 1
2442 unsigned p2 = 0; // Parameter - 2
2443 unsigned ident = 0;
2444 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002445
Arun Menon906de572013-06-18 17:01:40 -07002446 /*Generate FBD for all Buffers in the FTBq*/
2447 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002448 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002449
2450 //reset last render TS
2451 if(m_last_rendered_TS > 0) {
2452 m_last_rendered_TS = 0;
2453 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002454
Arun Menon906de572013-06-18 17:01:40 -07002455 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002456 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002457 m_ftb_q.m_size,pending_output_buffers);
2458 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002459 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002460 if (ident == m_fill_output_msg ) {
2461 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2462 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2463 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002465 }
Arun Menon906de572013-06-18 17:01:40 -07002466 pthread_mutex_unlock(&m_lock);
2467 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002468
Arun Menon906de572013-06-18 17:01:40 -07002469 if (arbitrary_bytes) {
2470 prev_ts = LLONG_MAX;
2471 rst_prev_ts = true;
2472 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002473 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002474 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002475}
2476/*=========================================================================
2477FUNCTION : execute_input_flush
2478
2479DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002480Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002481
2482PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002483None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002484
2485RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002486true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487==========================================================================*/
2488bool omx_vdec::execute_input_flush()
2489{
Arun Menon906de572013-06-18 17:01:40 -07002490 unsigned i =0;
2491 unsigned p1 = 0; // Parameter - 1
2492 unsigned p2 = 0; // Parameter - 2
2493 unsigned ident = 0;
2494 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002495
Arun Menon906de572013-06-18 17:01:40 -07002496 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002497 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002498
Arun Menon906de572013-06-18 17:01:40 -07002499 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002500 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002501 while (m_etb_q.m_size) {
2502 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503
Arun Menon906de572013-06-18 17:01:40 -07002504 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002505 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002506 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2507 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2508 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002509 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002510 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2511 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2512 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002513 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002514 (OMX_BUFFERHEADERTYPE *)p1);
2515 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2516 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002517 }
Arun Menon906de572013-06-18 17:01:40 -07002518 time_stamp_dts.flush_timestamp();
2519 /*Check if Heap Buffers are to be flushed*/
2520 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002521 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002522 h264_scratch.nFilledLen = 0;
2523 nal_count = 0;
2524 look_ahead_nal = false;
2525 frame_count = 0;
2526 h264_last_au_ts = LLONG_MAX;
2527 h264_last_au_flags = 0;
2528 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2529 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002530 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002531 if (m_frame_parser.mutils) {
2532 m_frame_parser.mutils->initialize_frame_checking_environment();
2533 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002534
Arun Menon906de572013-06-18 17:01:40 -07002535 while (m_input_pending_q.m_size) {
2536 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2537 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2538 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002539
Arun Menon906de572013-06-18 17:01:40 -07002540 if (psource_frame) {
2541 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2542 psource_frame = NULL;
2543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002544
Arun Menon906de572013-06-18 17:01:40 -07002545 if (pdest_frame) {
2546 pdest_frame->nFilledLen = 0;
2547 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2548 (unsigned int)NULL);
2549 pdest_frame = NULL;
2550 }
2551 m_frame_parser.flush();
2552 } else if (codec_config_flag) {
2553 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2554 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002555 }
Arun Menon906de572013-06-18 17:01:40 -07002556 pthread_mutex_unlock(&m_lock);
2557 input_flush_progress = false;
2558 if (!arbitrary_bytes) {
2559 prev_ts = LLONG_MAX;
2560 rst_prev_ts = true;
2561 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002562#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002563 if (m_debug_timestamp) {
2564 m_timestamp_list.reset_ts_list();
2565 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002566#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002567 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002568 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002569}
2570
2571
2572/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002573 FUNCTION
2574 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002575
Arun Menon906de572013-06-18 17:01:40 -07002576 DESCRIPTION
2577 Send the event to decoder pipe. This is needed to generate the callbacks
2578 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002579
Arun Menon906de572013-06-18 17:01:40 -07002580 PARAMETERS
2581 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002582
Arun Menon906de572013-06-18 17:01:40 -07002583 RETURN VALUE
2584 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002585
Arun Menon906de572013-06-18 17:01:40 -07002586 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002587bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002588 unsigned int p2,
2589 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002590{
Arun Menon906de572013-06-18 17:01:40 -07002591 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002592
2593
Arun Menon906de572013-06-18 17:01:40 -07002594 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002595
Arun Menon906de572013-06-18 17:01:40 -07002596 if (id == m_fill_output_msg ||
2597 id == OMX_COMPONENT_GENERATE_FBD) {
2598 m_ftb_q.insert_entry(p1,p2,id);
2599 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2600 id == OMX_COMPONENT_GENERATE_EBD ||
2601 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2602 m_etb_q.insert_entry(p1,p2,id);
2603 } else {
2604 m_cmd_q.insert_entry(p1,p2,id);
2605 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002606
Arun Menon906de572013-06-18 17:01:40 -07002607 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002608 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002609 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002612
Arun Menon906de572013-06-18 17:01:40 -07002613 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002614}
2615
2616OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2617{
Arun Menon906de572013-06-18 17:01:40 -07002618 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2619 if (!profileLevelType)
2620 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002621
Arun Menon906de572013-06-18 17:01:40 -07002622 if (profileLevelType->nPortIndex == 0) {
2623 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2624 if (profileLevelType->nProfileIndex == 0) {
2625 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2626 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002627
Arun Menon906de572013-06-18 17:01:40 -07002628 } else if (profileLevelType->nProfileIndex == 1) {
2629 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2630 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2631 } else if (profileLevelType->nProfileIndex == 2) {
2632 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2633 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2634 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002635 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002636 profileLevelType->nProfileIndex);
2637 eRet = OMX_ErrorNoMore;
2638 }
2639 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2640 if (profileLevelType->nProfileIndex == 0) {
2641 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2642 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2643 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002644 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002645 eRet = OMX_ErrorNoMore;
2646 }
2647 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2648 if (profileLevelType->nProfileIndex == 0) {
2649 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2650 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2651 } else if (profileLevelType->nProfileIndex == 1) {
2652 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2653 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2654 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002655 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002656 eRet = OMX_ErrorNoMore;
2657 }
2658 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2659 eRet = OMX_ErrorNoMore;
2660 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2661 if (profileLevelType->nProfileIndex == 0) {
2662 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2663 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2664 } else if (profileLevelType->nProfileIndex == 1) {
2665 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2666 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2667 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002668 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002669 eRet = OMX_ErrorNoMore;
2670 }
2671 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002672 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002673 eRet = OMX_ErrorNoMore;
2674 }
2675 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002676 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002677 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002678 }
Arun Menon906de572013-06-18 17:01:40 -07002679 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002680}
2681
2682/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002683 FUNCTION
2684 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002685
Arun Menon906de572013-06-18 17:01:40 -07002686 DESCRIPTION
2687 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002688
Arun Menon906de572013-06-18 17:01:40 -07002689 PARAMETERS
2690 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002691
Arun Menon906de572013-06-18 17:01:40 -07002692 RETURN VALUE
2693 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002694
Arun Menon906de572013-06-18 17:01:40 -07002695 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002696OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002697 OMX_IN OMX_INDEXTYPE paramIndex,
2698 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002699{
2700 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2701
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002702 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002703 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002704 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002705 return OMX_ErrorInvalidState;
2706 }
Arun Menon906de572013-06-18 17:01:40 -07002707 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002708 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002709 return OMX_ErrorBadParameter;
2710 }
Arun Menon906de572013-06-18 17:01:40 -07002711 switch ((unsigned long)paramIndex) {
2712 case OMX_IndexParamPortDefinition: {
2713 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2714 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002715 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002716 eRet = update_portdef(portDefn);
2717 if (eRet == OMX_ErrorNone)
2718 m_port_def = *portDefn;
2719 break;
2720 }
2721 case OMX_IndexParamVideoInit: {
2722 OMX_PORT_PARAM_TYPE *portParamType =
2723 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002724 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002725
Arun Menon906de572013-06-18 17:01:40 -07002726 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2727 portParamType->nSize = sizeof(portParamType);
2728 portParamType->nPorts = 2;
2729 portParamType->nStartPortNumber = 0;
2730 break;
2731 }
2732 case OMX_IndexParamVideoPortFormat: {
2733 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2734 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002735 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002736
Arun Menon906de572013-06-18 17:01:40 -07002737 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2738 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002739
Arun Menon906de572013-06-18 17:01:40 -07002740 if (0 == portFmt->nPortIndex) {
2741 if (0 == portFmt->nIndex) {
2742 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2743 portFmt->eCompressionFormat = eCompressionFormat;
2744 } else {
2745 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002746 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002747 eRet = OMX_ErrorNoMore;
2748 }
2749 } else if (1 == portFmt->nPortIndex) {
2750 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Praveen Chavandb7776f2014-02-06 18:17:25 -08002751 //On Android, we default to standard YUV formats for non-surface use-cases
2752 //where apps prefer known color formats.
2753 OMX_COLOR_FORMATTYPE formatsNonSurfaceMode[] = {
2754 [0] = OMX_COLOR_FormatYUV420SemiPlanar,
2755 [1] = OMX_COLOR_FormatYUV420Planar,
2756 [2] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2757 };
2758 //for surface mode (normal playback), advertise native/accelerated formats first
2759 OMX_COLOR_FORMATTYPE formatsDefault[] = {
2760 [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2761 [1] = OMX_COLOR_FormatYUV420Planar,
2762 [2] = OMX_COLOR_FormatYUV420SemiPlanar,
2763 };
2764#if _ANDROID_
2765 //Distinguish non-surface mode from normal playback use-case based on
2766 //usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2767 OMX_COLOR_FORMATTYPE *colorFormats =
2768 m_enable_android_native_buffers ? formatsDefault : formatsNonSurfaceMode;
2769 OMX_U32 maxIndex =
2770 m_enable_android_native_buffers ? sizeof(formatsDefault) : sizeof(formatsNonSurfaceMode);
2771 maxIndex /= sizeof(OMX_COLOR_FORMATTYPE);
2772#else
2773 OMX_COLOR_FORMATTYPE *colorFormats = formatsDefault;
2774 OMX_U32 maxIndex = sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE);
2775#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07002776
Praveen Chavandb7776f2014-02-06 18:17:25 -08002777 if (portFmt->nIndex < maxIndex) {
2778 portFmt->eColorFormat = colorFormats[portFmt->nIndex];
2779 } else {
2780 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002781 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002782 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002783 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002784 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002785 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002786 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002787 (int)portFmt->nPortIndex);
2788 eRet = OMX_ErrorBadPortIndex;
2789 }
2790 break;
2791 }
2792 /*Component should support this port definition*/
2793 case OMX_IndexParamAudioInit: {
2794 OMX_PORT_PARAM_TYPE *audioPortParamType =
2795 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002796 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002797 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2798 audioPortParamType->nSize = sizeof(audioPortParamType);
2799 audioPortParamType->nPorts = 0;
2800 audioPortParamType->nStartPortNumber = 0;
2801 break;
2802 }
2803 /*Component should support this port definition*/
2804 case OMX_IndexParamImageInit: {
2805 OMX_PORT_PARAM_TYPE *imagePortParamType =
2806 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002807 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002808 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2809 imagePortParamType->nSize = sizeof(imagePortParamType);
2810 imagePortParamType->nPorts = 0;
2811 imagePortParamType->nStartPortNumber = 0;
2812 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813
Arun Menon906de572013-06-18 17:01:40 -07002814 }
2815 /*Component should support this port definition*/
2816 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002817 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002818 paramIndex);
2819 eRet =OMX_ErrorUnsupportedIndex;
2820 break;
2821 }
2822 case OMX_IndexParamStandardComponentRole: {
2823 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2824 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2825 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2826 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002827
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002828 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002829 paramIndex);
2830 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2831 OMX_MAX_STRINGNAME_SIZE);
2832 break;
2833 }
2834 /* Added for parameter test */
2835 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002836
Arun Menon906de572013-06-18 17:01:40 -07002837 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2838 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002839 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002840 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2841 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842
Arun Menon906de572013-06-18 17:01:40 -07002843 break;
2844 }
2845 /* Added for parameter test */
2846 case OMX_IndexParamCompBufferSupplier: {
2847 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2848 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002849 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002850
Arun Menon906de572013-06-18 17:01:40 -07002851 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2852 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2853 if (0 == bufferSupplierType->nPortIndex)
2854 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2855 else if (1 == bufferSupplierType->nPortIndex)
2856 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2857 else
2858 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002859
2860
Arun Menon906de572013-06-18 17:01:40 -07002861 break;
2862 }
2863 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002864 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002865 paramIndex);
2866 break;
2867 }
2868 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002869 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002870 paramIndex);
2871 break;
2872 }
2873 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002874 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002875 paramIndex);
2876 break;
2877 }
2878 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002879 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002880 paramIndex);
2881 break;
2882 }
2883 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002884 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002885 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2886 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2887 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2888 break;
2889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002890#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002891 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002892 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002893 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2894 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002895
Arun Menon906de572013-06-18 17:01:40 -07002896 if (secure_mode) {
2897 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2898 GRALLOC_USAGE_PRIVATE_UNCACHED);
2899 } else {
2900 nativeBuffersUsage->nUsage =
2901 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2902 GRALLOC_USAGE_PRIVATE_UNCACHED);
2903 }
2904 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002905 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002906 eRet = OMX_ErrorBadParameter;
2907 }
2908 }
2909 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002910#endif
2911
Arun Menon906de572013-06-18 17:01:40 -07002912 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002913 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002914 eRet =OMX_ErrorUnsupportedIndex;
2915 }
2916
Shalaj Jain273b3e02012-06-22 19:08:03 -07002917 }
2918
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002919 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002920 drv_ctx.video_resolution.frame_width,
2921 drv_ctx.video_resolution.frame_height,
2922 drv_ctx.video_resolution.stride,
2923 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002924
Arun Menon906de572013-06-18 17:01:40 -07002925 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002926}
2927
2928#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2929OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2930{
2931 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2932 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2933 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2934
Arun Menon906de572013-06-18 17:01:40 -07002935 if ((params == NULL) ||
2936 (params->nativeBuffer == NULL) ||
2937 (params->nativeBuffer->handle == NULL) ||
2938 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002939 return OMX_ErrorBadParameter;
2940 m_use_android_native_buffers = OMX_TRUE;
2941 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2942 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002943 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 -07002944 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002945 if (!secure_mode) {
2946 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002947 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002948 if (buffer == MAP_FAILED) {
2949 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2950 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002951 }
2952 }
2953 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2954 } else {
2955 eRet = OMX_ErrorBadParameter;
2956 }
2957 return eRet;
2958}
2959#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002960
2961OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2962 struct v4l2_control control;
2963 struct v4l2_format fmt;
2964 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2965 control.value = 1;
2966 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2967 if (rc < 0) {
2968 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2969 return OMX_ErrorHardware;
2970 }
2971 m_smoothstreaming_mode = true;
2972 return OMX_ErrorNone;
2973}
2974
Shalaj Jain273b3e02012-06-22 19:08:03 -07002975/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002976 FUNCTION
2977 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002978
Arun Menon906de572013-06-18 17:01:40 -07002979 DESCRIPTION
2980 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002981
Arun Menon906de572013-06-18 17:01:40 -07002982 PARAMETERS
2983 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002984
Arun Menon906de572013-06-18 17:01:40 -07002985 RETURN VALUE
2986 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002987
Arun Menon906de572013-06-18 17:01:40 -07002988 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002989OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002990 OMX_IN OMX_INDEXTYPE paramIndex,
2991 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002992{
2993 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002994 int ret=0;
2995 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002996 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002997 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002998 return OMX_ErrorInvalidState;
2999 }
Arun Menon906de572013-06-18 17:01:40 -07003000 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003001 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07003002 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003003 }
Arun Menon906de572013-06-18 17:01:40 -07003004 if ((m_state != OMX_StateLoaded) &&
3005 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3006 (m_out_bEnabled == OMX_TRUE) &&
3007 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3008 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003009 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003010 return OMX_ErrorIncorrectStateOperation;
3011 }
Arun Menon906de572013-06-18 17:01:40 -07003012 switch ((unsigned long)paramIndex) {
3013 case OMX_IndexParamPortDefinition: {
3014 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3015 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3016 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3017 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003018 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07003019 (int)portDefn->format.video.nFrameHeight,
3020 (int)portDefn->format.video.nFrameWidth);
3021 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003022 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07003023 m_display_id = portDefn->format.video.pNativeWindow;
3024 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08003025 /* update output port resolution with client supplied dimensions
3026 in case scaling is enabled, else it follows input resolution set
3027 */
3028 if (is_down_scalar_enabled) {
3029 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003030 portDefn->format.video.nFrameWidth,
3031 portDefn->format.video.nFrameHeight);
3032 if (portDefn->format.video.nFrameHeight != 0x0 &&
3033 portDefn->format.video.nFrameWidth != 0x0) {
3034 update_resolution(portDefn->format.video.nFrameWidth,
3035 portDefn->format.video.nFrameHeight,
3036 portDefn->format.video.nFrameWidth,
3037 portDefn->format.video.nFrameHeight);
3038 eRet = is_video_session_supported();
3039 if (eRet)
3040 break;
3041 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3042 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3043 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3044 fmt.fmt.pix_mp.pixelformat = capture_capability;
3045 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);
3046 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3047 if (ret) {
3048 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3049 eRet = OMX_ErrorUnsupportedSetting;
3050 } else
3051 eRet = get_buffer_req(&drv_ctx.op_buf);
3052 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003053 }
Arun Menon906de572013-06-18 17:01:40 -07003054 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003055 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003056 eRet = OMX_ErrorBadParameter;
3057 } else {
3058 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3059 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3060 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3061 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3062 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3063 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3064 drv_ctx.extradata_info.buffer_size;
3065 eRet = set_buffer_req(&drv_ctx.op_buf);
3066 if (eRet == OMX_ErrorNone)
3067 m_port_def = *portDefn;
3068 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003069 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003070 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3071 portDefn->nBufferCountActual, portDefn->nBufferSize);
3072 eRet = OMX_ErrorBadParameter;
3073 }
3074 }
3075 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003076 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003077 bool port_format_changed = false;
3078 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3079 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3080 // Frame rate only should be set if this is a "known value" or to
3081 // activate ts prediction logic (arbitrary mode only) sending input
3082 // timestamps with max value (LLONG_MAX).
3083 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3084 portDefn->format.video.xFramerate >> 16);
3085 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3086 drv_ctx.frame_rate.fps_denominator);
3087 if (!drv_ctx.frame_rate.fps_numerator) {
3088 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3089 drv_ctx.frame_rate.fps_numerator = 30;
3090 }
3091 if (drv_ctx.frame_rate.fps_denominator)
3092 drv_ctx.frame_rate.fps_numerator = (int)
3093 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3094 drv_ctx.frame_rate.fps_denominator = 1;
3095 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3096 drv_ctx.frame_rate.fps_numerator;
3097 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3098 frm_int, drv_ctx.frame_rate.fps_numerator /
3099 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003100
3101 struct v4l2_outputparm oparm;
3102 /*XXX: we're providing timing info as seconds per frame rather than frames
3103 * per second.*/
3104 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3105 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3106
3107 struct v4l2_streamparm sparm;
3108 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3109 sparm.parm.output = oparm;
3110 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3111 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3112 eRet = OMX_ErrorHardware;
3113 break;
3114 }
Arun Menon906de572013-06-18 17:01:40 -07003115 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003116
Arun Menon906de572013-06-18 17:01:40 -07003117 if (drv_ctx.video_resolution.frame_height !=
3118 portDefn->format.video.nFrameHeight ||
3119 drv_ctx.video_resolution.frame_width !=
3120 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003121 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003122 portDefn->format.video.nFrameWidth,
3123 portDefn->format.video.nFrameHeight);
3124 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003125 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3126 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3127 if (frameHeight != 0x0 && frameWidth != 0x0) {
3128 if (m_smoothstreaming_mode &&
3129 ((frameWidth * frameHeight) <
3130 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3131 frameWidth = m_smoothstreaming_width;
3132 frameHeight = m_smoothstreaming_height;
3133 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3134 frameWidth, frameHeight);
3135 }
3136 update_resolution(frameWidth, frameHeight,
3137 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003138 eRet = is_video_session_supported();
3139 if (eRet)
3140 break;
3141 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3142 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3143 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3144 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003145 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 -07003146 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3147 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003148 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003149 eRet = OMX_ErrorUnsupportedSetting;
3150 } else
3151 eRet = get_buffer_req(&drv_ctx.op_buf);
3152 }
3153 }
3154 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3155 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3156 port_format_changed = true;
3157 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3158 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3159 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3160 (~(buffer_prop->alignment - 1));
3161 eRet = set_buffer_req(buffer_prop);
3162 }
3163 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003164 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003165 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3166 portDefn->nBufferCountActual, portDefn->nBufferSize);
3167 eRet = OMX_ErrorBadParameter;
3168 }
3169 } else if (portDefn->eDir == OMX_DirMax) {
3170 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3171 (int)portDefn->nPortIndex);
3172 eRet = OMX_ErrorBadPortIndex;
3173 }
3174 }
3175 break;
3176 case OMX_IndexParamVideoPortFormat: {
3177 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3178 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3179 int ret=0;
3180 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003181 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003182 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003183
Arun Menon906de572013-06-18 17:01:40 -07003184 if (1 == portFmt->nPortIndex) {
3185 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3186 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3187 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3188 fmt.fmt.pix_mp.pixelformat = capture_capability;
3189 enum vdec_output_fromat op_format;
3190 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3191 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003192 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3193 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003194 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003195 else
3196 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003197
Arun Menon906de572013-06-18 17:01:40 -07003198 if (eRet == OMX_ErrorNone) {
3199 drv_ctx.output_format = op_format;
3200 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3201 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003202 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003203 eRet = OMX_ErrorUnsupportedSetting;
3204 /*TODO: How to handle this case */
3205 } else {
3206 eRet = get_buffer_req(&drv_ctx.op_buf);
3207 }
3208 }
3209 if (eRet == OMX_ErrorNone) {
3210 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003211 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003212 eRet = OMX_ErrorBadParameter;
3213 }
3214 }
3215 }
3216 }
3217 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003218
Arun Menon906de572013-06-18 17:01:40 -07003219 case OMX_QcomIndexPortDefn: {
3220 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3221 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003222 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003223 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003224
Arun Menon906de572013-06-18 17:01:40 -07003225 /* Input port */
3226 if (portFmt->nPortIndex == 0) {
3227 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3228 if (secure_mode) {
3229 arbitrary_bytes = false;
3230 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3231 eRet = OMX_ErrorUnsupportedSetting;
3232 } else {
3233 arbitrary_bytes = true;
3234 }
3235 } else if (portFmt->nFramePackingFormat ==
3236 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3237 arbitrary_bytes = false;
3238 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003239 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003240 portFmt->nFramePackingFormat);
3241 eRet = OMX_ErrorUnsupportedSetting;
3242 }
3243 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003244 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003245 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3246 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3247 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3248 m_out_mem_region_smi = OMX_TRUE;
3249 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003250 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003251 m_use_output_pmem = OMX_TRUE;
3252 }
3253 }
3254 }
3255 }
3256 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003257
Arun Menon906de572013-06-18 17:01:40 -07003258 case OMX_IndexParamStandardComponentRole: {
3259 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3260 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003261 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003262 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003263
Arun Menon906de572013-06-18 17:01:40 -07003264 if ((m_state == OMX_StateLoaded)&&
3265 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3266 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3267 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003268 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003269 return OMX_ErrorIncorrectStateOperation;
3270 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003271
Arun Menon906de572013-06-18 17:01:40 -07003272 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3273 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3274 strlcpy((char*)m_cRole,"video_decoder.avc",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 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3280 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3281 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3282 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003283 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003284 eRet = OMX_ErrorUnsupportedSetting;
3285 }
3286 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3287 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3288 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3289 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003290 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003291 eRet =OMX_ErrorUnsupportedSetting;
3292 }
3293 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3294 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3295 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3296 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003297 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003298 eRet = OMX_ErrorUnsupportedSetting;
3299 }
3300 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3301 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3302 ) {
3303 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3304 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3305 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003306 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003307 eRet =OMX_ErrorUnsupportedSetting;
3308 }
3309 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3310 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3311 ) {
3312 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3313 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3314 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003315 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003316 eRet =OMX_ErrorUnsupportedSetting;
3317 }
3318 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3319 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3320 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3321 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3322 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003323 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003324 eRet = OMX_ErrorUnsupportedSetting;
3325 }
3326 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003327 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003328 eRet = OMX_ErrorInvalidComponentName;
3329 }
3330 break;
3331 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003332
Arun Menon906de572013-06-18 17:01:40 -07003333 case OMX_IndexParamPriorityMgmt: {
3334 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003335 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003336 return OMX_ErrorIncorrectStateOperation;
3337 }
3338 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003339 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003340 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003341
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003342 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003343 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003344
Arun Menon906de572013-06-18 17:01:40 -07003345 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3346 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003347
Arun Menon906de572013-06-18 17:01:40 -07003348 break;
3349 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003350
Arun Menon906de572013-06-18 17:01:40 -07003351 case OMX_IndexParamCompBufferSupplier: {
3352 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003353 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003354 bufferSupplierType->eBufferSupplier);
3355 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3356 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003357
Arun Menon906de572013-06-18 17:01:40 -07003358 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003359
Arun Menon906de572013-06-18 17:01:40 -07003360 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003361
Arun Menon906de572013-06-18 17:01:40 -07003362 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003363
Arun Menon906de572013-06-18 17:01:40 -07003364 }
3365 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003366 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003367 paramIndex);
3368 break;
3369 }
3370 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003371 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003372 paramIndex);
3373 break;
3374 }
3375 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003376 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003377 paramIndex);
3378 break;
3379 }
3380 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003381 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003382 paramIndex);
3383 break;
3384 }
3385 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3386 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3387 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3388 struct v4l2_control control;
3389 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003390 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003391 pictureOrder->eOutputPictureOrder);
3392 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3393 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3394 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3395 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3396 time_stamp_dts.set_timestamp_reorder_mode(false);
3397 } else
3398 eRet = OMX_ErrorBadParameter;
3399 if (eRet == OMX_ErrorNone) {
3400 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3401 control.value = pic_order;
3402 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3403 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003404 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003405 eRet = OMX_ErrorUnsupportedSetting;
3406 }
3407 }
3408 break;
3409 }
3410 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303411 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3412 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3413 break;
3414 case OMX_QcomIndexParamFrameInfoExtraData:
3415 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3416 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3417 break;
Arun Menon906de572013-06-18 17:01:40 -07003418 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303419 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3420 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3421 break;
Arun Menon906de572013-06-18 17:01:40 -07003422 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303423 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3424 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3425 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303426 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303427 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3428 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3429 break;
3430 case OMX_QcomIndexParamVideoQPExtraData:
3431 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3432 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3433 break;
3434 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3435 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3436 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3437 break;
Arun Menon906de572013-06-18 17:01:40 -07003438 case OMX_QcomIndexParamVideoDivx: {
3439 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3440 }
3441 break;
3442 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003443 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003444 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3445 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3446 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3447 eRet = OMX_ErrorUnsupportedSetting;
3448 } else {
3449 m_out_pvt_entry_pmem = OMX_TRUE;
3450 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003451 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003452 m_use_output_pmem = OMX_TRUE;
3453 }
3454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003455
Arun Menon906de572013-06-18 17:01:40 -07003456 }
3457 break;
3458 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3459 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3460 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3461 struct v4l2_control control;
3462 int rc;
3463 drv_ctx.idr_only_decoding = 1;
3464 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3465 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3466 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3467 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003468 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003469 eRet = OMX_ErrorUnsupportedSetting;
3470 } else {
3471 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3472 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3473 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3474 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003475 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003476 eRet = OMX_ErrorUnsupportedSetting;
3477 }
3478 /*Setting sync frame decoding on driver might change buffer
3479 * requirements so update them here*/
3480 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003481 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003482 eRet = OMX_ErrorUnsupportedSetting;
3483 }
3484 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003485 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003486 eRet = OMX_ErrorUnsupportedSetting;
3487 }
3488 }
3489 }
3490 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003491
Arun Menon906de572013-06-18 17:01:40 -07003492 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303493 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3494 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3495 (extradataIndexType->bEnabled == OMX_TRUE) &&
3496 (extradataIndexType->nPortIndex == 1)) {
3497 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3498 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3499 }
3500 }
Arun Menon906de572013-06-18 17:01:40 -07003501 break;
3502 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003503#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003504 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003505#else
Arun Menon906de572013-06-18 17:01:40 -07003506 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003507#endif
Arun Menon906de572013-06-18 17:01:40 -07003508 }
3509 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003510#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003511 /* Need to allow following two set_parameters even in Idle
3512 * state. This is ANDROID architecture which is not in sync
3513 * with openmax standard. */
3514 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3515 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3516 if (enableNativeBuffers) {
3517 m_enable_android_native_buffers = enableNativeBuffers->enable;
3518 }
3519 }
3520 break;
3521 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3522 eRet = use_android_native_buffer(hComp, paramData);
3523 }
3524 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003525#endif
Arun Menon906de572013-06-18 17:01:40 -07003526 case OMX_QcomIndexParamEnableTimeStampReorder: {
3527 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3528 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3529 if (reorder->bEnable == OMX_TRUE) {
3530 frm_int =0;
3531 time_stamp_dts.set_timestamp_reorder_mode(true);
3532 } else
3533 time_stamp_dts.set_timestamp_reorder_mode(false);
3534 } else {
3535 time_stamp_dts.set_timestamp_reorder_mode(false);
3536 if (reorder->bEnable == OMX_TRUE) {
3537 eRet = OMX_ErrorUnsupportedSetting;
3538 }
3539 }
3540 }
3541 break;
3542 case OMX_IndexParamVideoProfileLevelCurrent: {
3543 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3544 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3545 if (pParam) {
3546 m_profile_lvl.eProfile = pParam->eProfile;
3547 m_profile_lvl.eLevel = pParam->eLevel;
3548 }
3549 break;
Arun Menon888aa852013-05-30 11:24:42 -07003550
Arun Menon906de572013-06-18 17:01:40 -07003551 }
Arun Menone5652482013-08-04 13:33:05 -07003552 case OMX_QcomIndexParamVideoMetaBufferMode:
3553 {
3554 StoreMetaDataInBuffersParams *metabuffer =
3555 (StoreMetaDataInBuffersParams *)paramData;
3556 if (!metabuffer) {
3557 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3558 eRet = OMX_ErrorBadParameter;
3559 break;
3560 }
3561 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3562 //set property dynamic buffer mode to driver.
3563 struct v4l2_control control;
3564 struct v4l2_format fmt;
3565 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3566 if (metabuffer->bStoreMetaData == true) {
3567 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3568 } else {
3569 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3570 }
3571 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3572 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003573 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003574 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003575 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003576 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003577 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003578 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3579 eRet = OMX_ErrorUnsupportedSetting;
3580 }
3581 } else {
3582 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003583 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003584 metabuffer->nPortIndex);
3585 eRet = OMX_ErrorUnsupportedSetting;
3586 }
3587 break;
3588 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003589 case OMX_QcomIndexParamVideoDownScalar: {
3590 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3591 struct v4l2_control control;
3592 int rc;
3593 if (pParam) {
3594 is_down_scalar_enabled = pParam->bEnable;
3595 if (is_down_scalar_enabled) {
3596 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3597 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3598 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3599 pParam->bEnable);
3600 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3601 if (rc < 0) {
3602 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3603 eRet = OMX_ErrorUnsupportedSetting;
3604 }
3605 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3606 control.value = 1;
3607 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3608 if (rc < 0) {
3609 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3610 eRet = OMX_ErrorUnsupportedSetting;
3611 }
3612 }
3613 }
3614 break;
3615 }
Praveen Chavancf924182013-12-06 23:16:23 -08003616#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3617 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3618 {
3619 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3620 PrepareForAdaptivePlaybackParams* pParams =
3621 (PrepareForAdaptivePlaybackParams *) paramData;
3622 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3623 if (!pParams->bEnable) {
3624 return OMX_ErrorNone;
3625 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303626 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3627 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003628 DEBUG_PRINT_ERROR(
3629 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3630 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303631 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003632 eRet = OMX_ErrorBadParameter;
3633 } else {
3634 eRet = enable_smoothstreaming();
3635 if (eRet != OMX_ErrorNone) {
3636 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3637 eRet = OMX_ErrorHardware;
3638 } else {
3639 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3640 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3641 m_smoothstreaming_mode = true;
3642 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3643 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3644 }
Deepak Vermaf8771292014-02-03 12:22:50 +05303645 struct v4l2_format fmt;
3646 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
3647 m_smoothstreaming_width, m_smoothstreaming_height);
3648 eRet = is_video_session_supported();
3649 if (eRet)
3650 break;
3651 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3652 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3653 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3654 fmt.fmt.pix_mp.pixelformat = output_capability;
3655 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
3656 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
3657 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3658 if (ret) {
3659 DEBUG_PRINT_ERROR("Set Resolution failed");
3660 eRet = OMX_ErrorUnsupportedSetting;
3661 } else
3662 eRet = get_buffer_req(&drv_ctx.op_buf);
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303663 }
Praveen Chavancf924182013-12-06 23:16:23 -08003664 } else {
3665 DEBUG_PRINT_ERROR(
3666 "Prepare for adaptive playback supported only on output port");
3667 eRet = OMX_ErrorBadParameter;
3668 }
3669 break;
3670 }
3671
3672#endif
Arun Menon906de572013-06-18 17:01:40 -07003673 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003674 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003675 eRet = OMX_ErrorUnsupportedIndex;
3676 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003677 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003678 if (eRet != OMX_ErrorNone)
3679 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003680 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003681}
3682
3683/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003684 FUNCTION
3685 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003686
Arun Menon906de572013-06-18 17:01:40 -07003687 DESCRIPTION
3688 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003689
Arun Menon906de572013-06-18 17:01:40 -07003690 PARAMETERS
3691 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003692
Arun Menon906de572013-06-18 17:01:40 -07003693 RETURN VALUE
3694 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003695
Arun Menon906de572013-06-18 17:01:40 -07003696 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003697OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003698 OMX_IN OMX_INDEXTYPE configIndex,
3699 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003700{
Arun Menon906de572013-06-18 17:01:40 -07003701 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003702
Arun Menon906de572013-06-18 17:01:40 -07003703 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003704 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003705 return OMX_ErrorInvalidState;
3706 }
Arun Menon906de572013-06-18 17:01:40 -07003707
3708 switch ((unsigned long)configIndex) {
3709 case OMX_QcomIndexConfigInterlaced: {
3710 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3711 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3712 if (configFmt->nPortIndex == 1) {
3713 if (configFmt->nIndex == 0) {
3714 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3715 } else if (configFmt->nIndex == 1) {
3716 configFmt->eInterlaceType =
3717 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3718 } else if (configFmt->nIndex == 2) {
3719 configFmt->eInterlaceType =
3720 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3721 } else {
3722 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003723 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003724 eRet = OMX_ErrorNoMore;
3725 }
3726
3727 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003728 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003729 (int)configFmt->nPortIndex);
3730 eRet = OMX_ErrorBadPortIndex;
3731 }
3732 break;
3733 }
3734 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3735 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3736 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3737 decoderinstances->nNumOfInstances = 16;
3738 /*TODO: How to handle this case */
3739 break;
3740 }
3741 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3742 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3743 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3744 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303745 memcpy(configFmt, &m_frame_pack_arrangement,
3746 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003747 } else {
3748 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3749 }
3750 break;
3751 }
3752 case OMX_IndexConfigCommonOutputCrop: {
3753 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3754 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3755 break;
3756 }
3757 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003758 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003759 eRet = OMX_ErrorBadParameter;
3760 }
3761
Shalaj Jain273b3e02012-06-22 19:08:03 -07003762 }
Arun Menon906de572013-06-18 17:01:40 -07003763
3764 return eRet;
3765}
3766
3767/* ======================================================================
3768 FUNCTION
3769 omx_vdec::SetConfig
3770
3771 DESCRIPTION
3772 OMX Set Config method implementation
3773
3774 PARAMETERS
3775 <TBD>.
3776
3777 RETURN VALUE
3778 OMX Error None if successful.
3779 ========================================================================== */
3780OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3781 OMX_IN OMX_INDEXTYPE configIndex,
3782 OMX_IN OMX_PTR configData)
3783{
3784 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003785 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003786 return OMX_ErrorInvalidState;
3787 }
3788
3789 OMX_ERRORTYPE ret = OMX_ErrorNone;
3790 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3791
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003792 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003793
3794 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3795 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003796 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003797 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003798 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003799 OMX_U32 extra_size;
3800 // Parsing done here for the AVC atom is definitely not generic
3801 // Currently this piece of code is working, but certainly
3802 // not tested with all .mp4 files.
3803 // Incase of failure, we might need to revisit this
3804 // for a generic piece of code.
3805
3806 // Retrieve size of NAL length field
3807 // byte #4 contains the size of NAL lenght field
3808 nal_length = (config->pData[4] & 0x03) + 1;
3809
3810 extra_size = 0;
3811 if (nal_length > 2) {
3812 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3813 extra_size = (nal_length - 2) * 2;
3814 }
3815
3816 // SPS starts from byte #6
3817 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3818 OMX_U8 *pDestBuf;
3819 m_vendor_config.nPortIndex = config->nPortIndex;
3820
3821 // minus 6 --> SPS starts from byte #6
3822 // minus 1 --> picture param set byte to be ignored from avcatom
3823 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3824 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3825 OMX_U32 len;
3826 OMX_U8 index = 0;
3827 // case where SPS+PPS is sent as part of set_config
3828 pDestBuf = m_vendor_config.pData;
3829
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003830 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003831 m_vendor_config.nPortIndex,
3832 m_vendor_config.nDataSize,
3833 m_vendor_config.pData);
3834 while (index < 2) {
3835 uint8 *psize;
3836 len = *pSrcBuf;
3837 len = len << 8;
3838 len |= *(pSrcBuf + 1);
3839 psize = (uint8 *) & len;
3840 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3841 for (unsigned int i = 0; i < nal_length; i++) {
3842 pDestBuf[i] = psize[nal_length - 1 - i];
3843 }
3844 //memcpy(pDestBuf,pSrcBuf,(len+2));
3845 pDestBuf += len + nal_length;
3846 pSrcBuf += len + 2;
3847 index++;
3848 pSrcBuf++; // skip picture param set
3849 len = 0;
3850 }
3851 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3852 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3853 m_vendor_config.nPortIndex = config->nPortIndex;
3854 m_vendor_config.nDataSize = config->nDataSize;
3855 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3856 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3857 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3858 if (m_vendor_config.pData) {
3859 free(m_vendor_config.pData);
3860 m_vendor_config.pData = NULL;
3861 m_vendor_config.nDataSize = 0;
3862 }
3863
3864 if (((*((OMX_U32 *) config->pData)) &
3865 VC1_SP_MP_START_CODE_MASK) ==
3866 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003867 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003868 m_vendor_config.nPortIndex = config->nPortIndex;
3869 m_vendor_config.nDataSize = config->nDataSize;
3870 m_vendor_config.pData =
3871 (OMX_U8 *) malloc(config->nDataSize);
3872 memcpy(m_vendor_config.pData, config->pData,
3873 config->nDataSize);
3874 m_vc1_profile = VC1_SP_MP_RCV;
3875 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003876 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003877 m_vendor_config.nPortIndex = config->nPortIndex;
3878 m_vendor_config.nDataSize = config->nDataSize;
3879 m_vendor_config.pData =
3880 (OMX_U8 *) malloc((config->nDataSize));
3881 memcpy(m_vendor_config.pData, config->pData,
3882 config->nDataSize);
3883 m_vc1_profile = VC1_AP;
3884 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003885 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003886 m_vendor_config.nPortIndex = config->nPortIndex;
3887 m_vendor_config.nDataSize = config->nDataSize;
3888 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3889 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3890 m_vc1_profile = VC1_SP_MP_RCV;
3891 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003892 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003893 }
3894 }
3895 return ret;
3896 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3897 struct v4l2_control temp;
3898 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3899
3900 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3901 switch (pNal->nNaluBytes) {
3902 case 0:
3903 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3904 break;
3905 case 2:
3906 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3907 break;
3908 case 4:
3909 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3910 break;
3911 default:
3912 return OMX_ErrorUnsupportedSetting;
3913 }
3914
3915 if (!arbitrary_bytes) {
3916 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3917 * with start code, so only need to notify driver in frame by frame mode */
3918 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3919 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3920 return OMX_ErrorHardware;
3921 }
3922 }
3923
3924 nal_length = pNal->nNaluBytes;
3925 m_frame_parser.init_nal_length(nal_length);
3926
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003927 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003928 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303929 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003930 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303931 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003932
3933 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3934 if (config->bEnabled) {
3935 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303936 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003937 config->nFps >> 16);
3938 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3939 drv_ctx.frame_rate.fps_denominator);
3940
3941 if (!drv_ctx.frame_rate.fps_numerator) {
3942 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3943 drv_ctx.frame_rate.fps_numerator = 30;
3944 }
3945
3946 if (drv_ctx.frame_rate.fps_denominator) {
3947 drv_ctx.frame_rate.fps_numerator = (int)
3948 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3949 }
3950
3951 drv_ctx.frame_rate.fps_denominator = 1;
3952 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3953 drv_ctx.frame_rate.fps_numerator;
3954
3955 struct v4l2_outputparm oparm;
3956 /*XXX: we're providing timing info as seconds per frame rather than frames
3957 * per second.*/
3958 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3959 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3960
3961 struct v4l2_streamparm sparm;
3962 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3963 sparm.parm.output = oparm;
3964 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3965 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3966 performance might be affected");
3967 ret = OMX_ErrorHardware;
3968 }
3969 client_set_fps = true;
3970 } else {
3971 DEBUG_PRINT_ERROR("Frame rate not supported.");
3972 ret = OMX_ErrorUnsupportedSetting;
3973 }
3974 } else {
3975 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3976 client_set_fps = false;
3977 }
3978 } else {
3979 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3980 (int)config->nPortIndex);
3981 ret = OMX_ErrorBadPortIndex;
3982 }
3983
3984 return ret;
3985 }
3986
3987 return OMX_ErrorNotImplemented;
3988}
3989
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303990#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3991
Arun Menon906de572013-06-18 17:01:40 -07003992/* ======================================================================
3993 FUNCTION
3994 omx_vdec::GetExtensionIndex
3995
3996 DESCRIPTION
3997 OMX GetExtensionIndex method implementaion. <TBD>
3998
3999 PARAMETERS
4000 <TBD>.
4001
4002 RETURN VALUE
4003 OMX Error None if everything successful.
4004
4005 ========================================================================== */
4006OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4007 OMX_IN OMX_STRING paramName,
4008 OMX_OUT OMX_INDEXTYPE* indexType)
4009{
4010 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004011 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004012 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304013 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004014 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304015 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004016 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304017 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4018 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4019 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4020 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004021 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4022 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004023 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4024 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004025 }
4026#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304027 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004028 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304029 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004030 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304031 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004032 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004033 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304034 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004035 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4036 }
4037#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304038 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004039 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4040 }
Praveen Chavancf924182013-12-06 23:16:23 -08004041#if ADAPTIVE_PLAYBACK_SUPPORTED
4042 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4043 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4044 }
4045#endif
Arun Menon906de572013-06-18 17:01:40 -07004046 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004047 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004048 return OMX_ErrorNotImplemented;
4049 }
4050 return OMX_ErrorNone;
4051}
4052
4053/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004054 FUNCTION
4055 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004056
Arun Menon906de572013-06-18 17:01:40 -07004057 DESCRIPTION
4058 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004059
Arun Menon906de572013-06-18 17:01:40 -07004060 PARAMETERS
4061 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004062
Arun Menon906de572013-06-18 17:01:40 -07004063 RETURN VALUE
4064 Error None if everything is successful.
4065 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004066OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004067 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004068{
Arun Menon906de572013-06-18 17:01:40 -07004069 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004070 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004071 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004072}
4073
4074/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004075 FUNCTION
4076 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004077
Arun Menon906de572013-06-18 17:01:40 -07004078 DESCRIPTION
4079 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004080
Arun Menon906de572013-06-18 17:01:40 -07004081 PARAMETERS
4082 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004083
Arun Menon906de572013-06-18 17:01:40 -07004084 RETURN VALUE
4085 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004086
Arun Menon906de572013-06-18 17:01:40 -07004087 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004088OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004089 OMX_IN OMX_U32 port,
4090 OMX_IN OMX_HANDLETYPE peerComponent,
4091 OMX_IN OMX_U32 peerPort,
4092 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004093{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004094 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004095 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004096}
4097
4098/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004099 FUNCTION
4100 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004101
Arun Menon906de572013-06-18 17:01:40 -07004102 DESCRIPTION
4103 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004104
Arun Menon906de572013-06-18 17:01:40 -07004105 PARAMETERS
4106 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004107
Arun Menon906de572013-06-18 17:01:40 -07004108 RETURN VALUE
4109 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004110
Arun Menon906de572013-06-18 17:01:40 -07004111 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004112OMX_ERRORTYPE omx_vdec::allocate_extradata()
4113{
4114#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004115 if (drv_ctx.extradata_info.buffer_size) {
4116 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4117 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4118 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4119 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004120 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004121 }
4122 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4123 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4124 drv_ctx.extradata_info.size, 4096,
4125 &drv_ctx.extradata_info.ion.ion_alloc_data,
4126 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4127 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004128 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004129 return OMX_ErrorInsufficientResources;
4130 }
4131 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4132 drv_ctx.extradata_info.size,
4133 PROT_READ|PROT_WRITE, MAP_SHARED,
4134 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4135 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004136 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004137 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4138 free_ion_memory(&drv_ctx.extradata_info.ion);
4139 return OMX_ErrorInsufficientResources;
4140 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004141 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004142#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304143 if (!m_other_extradata) {
4144 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4145 if (!m_other_extradata) {
4146 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4147 return OMX_ErrorInsufficientResources;
4148 }
4149 }
Arun Menon906de572013-06-18 17:01:40 -07004150 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004151}
4152
Arun Menon906de572013-06-18 17:01:40 -07004153void omx_vdec::free_extradata()
4154{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004155#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004156 if (drv_ctx.extradata_info.uaddr) {
4157 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4158 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4159 free_ion_memory(&drv_ctx.extradata_info.ion);
4160 }
4161 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004162#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304163 if (m_other_extradata) {
4164 free(m_other_extradata);
4165 m_other_extradata = NULL;
4166 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004167}
4168
Shalaj Jain273b3e02012-06-22 19:08:03 -07004169OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004170 OMX_IN OMX_HANDLETYPE hComp,
4171 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4172 OMX_IN OMX_U32 port,
4173 OMX_IN OMX_PTR appData,
4174 OMX_IN OMX_U32 bytes,
4175 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004176{
Arun Menon906de572013-06-18 17:01:40 -07004177 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4178 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4179 unsigned i= 0; // Temporary counter
4180 struct vdec_setbuffer_cmd setbuffers;
4181 OMX_PTR privateAppData = NULL;
4182 private_handle_t *handle = NULL;
4183 OMX_U8 *buff = buffer;
4184 struct v4l2_buffer buf;
4185 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4186 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004187
Arun Menon906de572013-06-18 17:01:40 -07004188 if (!m_out_mem_ptr) {
4189 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4190 eRet = allocate_output_headers();
4191 if (eRet == OMX_ErrorNone)
4192 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004193 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004194
Arun Menon906de572013-06-18 17:01:40 -07004195 if (eRet == OMX_ErrorNone) {
4196 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4197 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4198 break;
4199 }
4200 }
4201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004202
Arun Menon906de572013-06-18 17:01:40 -07004203 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004204 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004205 eRet = OMX_ErrorInsufficientResources;
4206 }
4207
Arun Menonbdb80b02013-08-12 17:45:54 -07004208 if (dynamic_buf_mode) {
4209 *bufferHdr = (m_out_mem_ptr + i );
4210 (*bufferHdr)->pBuffer = NULL;
4211 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4212 enum v4l2_buf_type buf_type;
4213 int rr = 0;
4214 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4215 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4216 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4217 return OMX_ErrorInsufficientResources;
4218 } else {
4219 streaming[CAPTURE_PORT] = true;
4220 DEBUG_PRINT_LOW("STREAMON Successful");
4221 }
4222 }
4223 BITMASK_SET(&m_out_bm_count,i);
4224 (*bufferHdr)->pAppPrivate = appData;
4225 (*bufferHdr)->pBuffer = buffer;
4226 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4227 return eRet;
4228 }
Arun Menon906de572013-06-18 17:01:40 -07004229 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004230#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004231 if (m_enable_android_native_buffers) {
4232 if (m_use_android_native_buffers) {
4233 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4234 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4235 handle = (private_handle_t *)nBuf->handle;
4236 privateAppData = params->pAppPrivate;
4237 } else {
4238 handle = (private_handle_t *)buff;
4239 privateAppData = appData;
4240 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004241
Arun Menon906de572013-06-18 17:01:40 -07004242 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4243 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4244 " expected %u, got %lu",
4245 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4246 return OMX_ErrorBadParameter;
4247 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004248
Arun Menon906de572013-06-18 17:01:40 -07004249 if (!m_use_android_native_buffers) {
4250 if (!secure_mode) {
4251 buff = (OMX_U8*)mmap(0, handle->size,
4252 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4253 if (buff == MAP_FAILED) {
4254 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4255 return OMX_ErrorInsufficientResources;
4256 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004257 }
4258 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004259#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004260 native_buffer[i].nativehandle = handle;
4261 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004262#endif
Arun Menon906de572013-06-18 17:01:40 -07004263 if (!handle) {
4264 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4265 return OMX_ErrorBadParameter;
4266 }
4267 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4268 drv_ctx.ptr_outputbuffer[i].offset = 0;
4269 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4270 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4271 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4272 } else
4273#endif
4274
4275 if (!ouput_egl_buffers && !m_use_output_pmem) {
4276#ifdef USE_ION
4277 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4278 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4279 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4280 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4281 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004282 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 -07004283 return OMX_ErrorInsufficientResources;
4284 }
4285 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4286 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4287#else
4288 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4289 open (MEM_DEVICE,O_RDWR);
4290
4291 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004292 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004293 return OMX_ErrorInsufficientResources;
4294 }
4295
4296 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4297 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4298 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4299 open (MEM_DEVICE,O_RDWR);
4300 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004301 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004302 return OMX_ErrorInsufficientResources;
4303 }
4304 }
4305
4306 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4307 drv_ctx.op_buf.buffer_size,
4308 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004309 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004310 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4311 return OMX_ErrorInsufficientResources;
4312 }
4313#endif
4314 if (!secure_mode) {
4315 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4316 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4317 PROT_READ|PROT_WRITE, MAP_SHARED,
4318 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4319 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4320 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4321#ifdef USE_ION
4322 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4323#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004324 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004325 return OMX_ErrorInsufficientResources;
4326 }
4327 }
4328 drv_ctx.ptr_outputbuffer[i].offset = 0;
4329 privateAppData = appData;
4330 } else {
4331
4332 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4333 if (!appData || !bytes ) {
4334 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004335 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004336 return OMX_ErrorBadParameter;
4337 }
4338 }
4339
4340 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4341 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4342 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4343 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4344 !pmem_list->nEntries ||
4345 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004346 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004347 return OMX_ErrorBadParameter;
4348 }
4349 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4350 pmem_list->entryList->entry;
4351 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4352 pmem_info->pmem_fd);
4353 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4354 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4355 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4356 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4357 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4358 privateAppData = appData;
4359 }
4360 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4361 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304362 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4363 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4364 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004365
4366 *bufferHdr = (m_out_mem_ptr + i );
4367 if (secure_mode)
4368 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4369 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4370 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4371 sizeof (vdec_bufferpayload));
4372
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004373 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004374 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4375 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4376
4377 buf.index = i;
4378 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4379 buf.memory = V4L2_MEMORY_USERPTR;
4380 plane[0].length = drv_ctx.op_buf.buffer_size;
4381 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4382 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4383 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4384 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4385 plane[0].data_offset = 0;
4386 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4387 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4388 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4389 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4390#ifdef USE_ION
4391 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4392#endif
4393 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4394 plane[extra_idx].data_offset = 0;
4395 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004396 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004397 return OMX_ErrorBadParameter;
4398 }
Arun Menon906de572013-06-18 17:01:40 -07004399 buf.m.planes = plane;
4400 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004401
Arun Menon906de572013-06-18 17:01:40 -07004402 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004403 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004404 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004405 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004406 }
4407
Arun Menon906de572013-06-18 17:01:40 -07004408 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4409 enum v4l2_buf_type buf_type;
4410 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4411 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4412 return OMX_ErrorInsufficientResources;
4413 } else {
4414 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004415 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004416 }
4417 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004418
Arun Menon906de572013-06-18 17:01:40 -07004419 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4420 if (m_enable_android_native_buffers) {
4421 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4422 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4423 } else {
4424 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004425 }
Arun Menon906de572013-06-18 17:01:40 -07004426 (*bufferHdr)->pAppPrivate = privateAppData;
4427 BITMASK_SET(&m_out_bm_count,i);
4428 }
4429 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004430}
4431
4432/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004433 FUNCTION
4434 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435
Arun Menon906de572013-06-18 17:01:40 -07004436 DESCRIPTION
4437 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438
Arun Menon906de572013-06-18 17:01:40 -07004439 PARAMETERS
4440 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004441
Arun Menon906de572013-06-18 17:01:40 -07004442 RETURN VALUE
4443 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004444
Arun Menon906de572013-06-18 17:01:40 -07004445 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004446OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004447 OMX_IN OMX_HANDLETYPE hComp,
4448 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4449 OMX_IN OMX_U32 port,
4450 OMX_IN OMX_PTR appData,
4451 OMX_IN OMX_U32 bytes,
4452 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004453{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004454 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004455 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4456 if (!m_inp_heap_ptr)
4457 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4458 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4459 drv_ctx.ip_buf.actualcount);
4460 if (!m_phdr_pmem_ptr)
4461 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4462 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4463 drv_ctx.ip_buf.actualcount);
4464 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4465 DEBUG_PRINT_ERROR("Insufficent memory");
4466 eRet = OMX_ErrorInsufficientResources;
4467 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4468 input_use_buffer = true;
4469 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4470 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4471 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4472 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4473 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4474 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4475 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4476 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004477 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 -07004478 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4479 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004480 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004481 return OMX_ErrorInsufficientResources;
4482 }
4483 m_in_alloc_cnt++;
4484 } else {
4485 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4486 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004487 }
Arun Menon906de572013-06-18 17:01:40 -07004488 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004489}
4490
4491/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004492 FUNCTION
4493 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004494
Arun Menon906de572013-06-18 17:01:40 -07004495 DESCRIPTION
4496 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004497
Arun Menon906de572013-06-18 17:01:40 -07004498 PARAMETERS
4499 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004500
Arun Menon906de572013-06-18 17:01:40 -07004501 RETURN VALUE
4502 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004503
Arun Menon906de572013-06-18 17:01:40 -07004504 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004505OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004506 OMX_IN OMX_HANDLETYPE hComp,
4507 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4508 OMX_IN OMX_U32 port,
4509 OMX_IN OMX_PTR appData,
4510 OMX_IN OMX_U32 bytes,
4511 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004512{
Arun Menon906de572013-06-18 17:01:40 -07004513 OMX_ERRORTYPE error = OMX_ErrorNone;
4514 struct vdec_setbuffer_cmd setbuffers;
4515
4516 if (bufferHdr == NULL || bytes == 0) {
4517 if (!secure_mode && buffer == NULL) {
4518 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4519 return OMX_ErrorBadParameter;
4520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521 }
Arun Menon906de572013-06-18 17:01:40 -07004522 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004523 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004524 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004525 }
Arun Menon906de572013-06-18 17:01:40 -07004526 if (port == OMX_CORE_INPUT_PORT_INDEX)
4527 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4528 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4529 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4530 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004531 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004532 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004533 }
Arun Menon906de572013-06-18 17:01:40 -07004534 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4535 if (error == OMX_ErrorNone) {
4536 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4537 // Send the callback now
4538 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4539 post_event(OMX_CommandStateSet,OMX_StateIdle,
4540 OMX_COMPONENT_GENERATE_EVENT);
4541 }
4542 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4543 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4544 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4545 post_event(OMX_CommandPortEnable,
4546 OMX_CORE_INPUT_PORT_INDEX,
4547 OMX_COMPONENT_GENERATE_EVENT);
4548 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4549 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4550 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4551 post_event(OMX_CommandPortEnable,
4552 OMX_CORE_OUTPUT_PORT_INDEX,
4553 OMX_COMPONENT_GENERATE_EVENT);
4554 }
4555 }
4556 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557}
4558
4559OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004560 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004561{
Arun Menon906de572013-06-18 17:01:40 -07004562 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4563 if (m_inp_heap_ptr[bufferindex].pBuffer)
4564 free(m_inp_heap_ptr[bufferindex].pBuffer);
4565 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4566 }
4567 if (pmem_bufferHdr)
4568 free_input_buffer(pmem_bufferHdr);
4569 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570}
4571
4572OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4573{
Arun Menon906de572013-06-18 17:01:40 -07004574 unsigned int index = 0;
4575 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4576 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004578
Arun Menon906de572013-06-18 17:01:40 -07004579 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004580 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004581
4582 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004583 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004584 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4585 struct vdec_setbuffer_cmd setbuffers;
4586 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4587 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4588 sizeof (vdec_bufferpayload));
4589 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004590 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004591 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004592 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004593 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4594 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4595 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4596 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4597 }
4598 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4599 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4600 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4601 free(m_desc_buffer_ptr[index].buf_addr);
4602 m_desc_buffer_ptr[index].buf_addr = NULL;
4603 m_desc_buffer_ptr[index].desc_data_size = 0;
4604 }
4605#ifdef USE_ION
4606 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4607#endif
4608 }
4609 }
4610
4611 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612}
4613
4614OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4615{
Arun Menon906de572013-06-18 17:01:40 -07004616 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004617
Arun Menon906de572013-06-18 17:01:40 -07004618 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4619 return OMX_ErrorBadParameter;
4620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004621
Arun Menon906de572013-06-18 17:01:40 -07004622 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004623 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624
Arun Menon906de572013-06-18 17:01:40 -07004625 if (index < drv_ctx.op_buf.actualcount
4626 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004627 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004628 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004629
Arun Menon906de572013-06-18 17:01:40 -07004630 struct vdec_setbuffer_cmd setbuffers;
4631 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4632 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4633 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004634
4635 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004636#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004637 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004638 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004639 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4640 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4641 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4642 }
Arun Menon906de572013-06-18 17:01:40 -07004643 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004644 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4645 } else {
4646#endif
4647 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4648 if (!secure_mode) {
4649 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4650 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4651 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4652 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4653 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4654 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4655 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4656 }
4657 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4658 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004659#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004660 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004661#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004664 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004665#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004666 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004667 if (release_output_done()) {
4668 free_extradata();
4669 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671
Arun Menon906de572013-06-18 17:01:40 -07004672 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004673
4674}
4675
4676OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004677 OMX_BUFFERHEADERTYPE **bufferHdr,
4678 OMX_U32 port,
4679 OMX_PTR appData,
4680 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004681{
Arun Menon906de572013-06-18 17:01:40 -07004682 OMX_BUFFERHEADERTYPE *input = NULL;
4683 unsigned char *buf_addr = NULL;
4684 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4685 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004686
Arun Menon906de572013-06-18 17:01:40 -07004687 /* Sanity Check*/
4688 if (bufferHdr == NULL) {
4689 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004690 }
4691
Arun Menon906de572013-06-18 17:01:40 -07004692 if (m_inp_heap_ptr == NULL) {
4693 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4694 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4695 drv_ctx.ip_buf.actualcount);
4696 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4697 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4698 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699
Arun Menon906de572013-06-18 17:01:40 -07004700 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004701 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004702 return OMX_ErrorInsufficientResources;
4703 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004704 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705
Arun Menon906de572013-06-18 17:01:40 -07004706 /*Find a Free index*/
4707 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4708 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004709 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004710 break;
4711 }
4712 }
4713
4714 if (i < drv_ctx.ip_buf.actualcount) {
4715 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4716
4717 if (buf_addr == NULL) {
4718 return OMX_ErrorInsufficientResources;
4719 }
4720
4721 *bufferHdr = (m_inp_heap_ptr + i);
4722 input = *bufferHdr;
4723 BITMASK_SET(&m_heap_inp_bm_count,i);
4724
4725 input->pBuffer = (OMX_U8 *)buf_addr;
4726 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4727 input->nVersion.nVersion = OMX_SPEC_VERSION;
4728 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4729 input->pAppPrivate = appData;
4730 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004731 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004732 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004733 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004734 /*Add the Buffers to freeq*/
4735 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4736 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004737 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004738 return OMX_ErrorInsufficientResources;
4739 }
4740 } else {
4741 return OMX_ErrorBadParameter;
4742 }
4743
4744 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004745
4746}
4747
4748
4749/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004750 FUNCTION
4751 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004752
Arun Menon906de572013-06-18 17:01:40 -07004753 DESCRIPTION
4754 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004755
Arun Menon906de572013-06-18 17:01:40 -07004756 PARAMETERS
4757 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004758
Arun Menon906de572013-06-18 17:01:40 -07004759 RETURN VALUE
4760 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004761
Arun Menon906de572013-06-18 17:01:40 -07004762 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004763OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004764 OMX_IN OMX_HANDLETYPE hComp,
4765 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4766 OMX_IN OMX_U32 port,
4767 OMX_IN OMX_PTR appData,
4768 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769{
4770
Arun Menon906de572013-06-18 17:01:40 -07004771 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4772 struct vdec_setbuffer_cmd setbuffers;
4773 OMX_BUFFERHEADERTYPE *input = NULL;
4774 unsigned i = 0;
4775 unsigned char *buf_addr = NULL;
4776 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004777
Arun Menon906de572013-06-18 17:01:40 -07004778 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004779 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004780 bytes, drv_ctx.ip_buf.buffer_size);
4781 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782 }
4783
Arun Menon906de572013-06-18 17:01:40 -07004784 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004785 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004786 drv_ctx.ip_buf.actualcount,
4787 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004788
Arun Menon906de572013-06-18 17:01:40 -07004789 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4790 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4791
4792 if (m_inp_mem_ptr == NULL) {
4793 return OMX_ErrorInsufficientResources;
4794 }
4795
4796 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4797 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4798
4799 if (drv_ctx.ptr_inputbuffer == NULL) {
4800 return OMX_ErrorInsufficientResources;
4801 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004802#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004803 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4804 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004805
Arun Menon906de572013-06-18 17:01:40 -07004806 if (drv_ctx.ip_buf_ion_info == NULL) {
4807 return OMX_ErrorInsufficientResources;
4808 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004809#endif
4810
Arun Menon906de572013-06-18 17:01:40 -07004811 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4812 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004813#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004814 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004815#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004816 }
4817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004818
Arun Menon906de572013-06-18 17:01:40 -07004819 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4820 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004821 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004822 break;
4823 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824 }
Arun Menon906de572013-06-18 17:01:40 -07004825
4826 if (i < drv_ctx.ip_buf.actualcount) {
4827 struct v4l2_buffer buf;
4828 struct v4l2_plane plane;
4829 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004830 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004831#ifdef USE_ION
4832 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4833 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4834 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4835 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4836 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4837 return OMX_ErrorInsufficientResources;
4838 }
4839 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4840#else
4841 pmem_fd = open (MEM_DEVICE,O_RDWR);
4842
4843 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004844 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004845 return OMX_ErrorInsufficientResources;
4846 }
4847
4848 if (pmem_fd == 0) {
4849 pmem_fd = open (MEM_DEVICE,O_RDWR);
4850
4851 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004852 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004853 return OMX_ErrorInsufficientResources;
4854 }
4855 }
4856
4857 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4858 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004859 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004860 close(pmem_fd);
4861 return OMX_ErrorInsufficientResources;
4862 }
4863#endif
4864 if (!secure_mode) {
4865 buf_addr = (unsigned char *)mmap(NULL,
4866 drv_ctx.ip_buf.buffer_size,
4867 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4868
4869 if (buf_addr == MAP_FAILED) {
4870 close(pmem_fd);
4871#ifdef USE_ION
4872 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4873#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004874 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004875 return OMX_ErrorInsufficientResources;
4876 }
4877 }
4878 *bufferHdr = (m_inp_mem_ptr + i);
4879 if (secure_mode)
4880 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4881 else
4882 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4883 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4884 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4885 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4886 drv_ctx.ptr_inputbuffer [i].offset = 0;
4887
4888
4889 buf.index = i;
4890 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4891 buf.memory = V4L2_MEMORY_USERPTR;
4892 plane.bytesused = 0;
4893 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4894 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4895 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4896 plane.reserved[1] = 0;
4897 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4898 buf.m.planes = &plane;
4899 buf.length = 1;
4900
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004901 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004902 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4903
4904 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4905
4906 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004907 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004908 /*TODO: How to handle this case */
4909 return OMX_ErrorInsufficientResources;
4910 }
4911
4912 input = *bufferHdr;
4913 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004914 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004915 if (secure_mode)
4916 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4917 else
4918 input->pBuffer = (OMX_U8 *)buf_addr;
4919 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4920 input->nVersion.nVersion = OMX_SPEC_VERSION;
4921 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4922 input->pAppPrivate = appData;
4923 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4924 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4925
4926 if (drv_ctx.disable_dmx) {
4927 eRet = allocate_desc_buffer(i);
4928 }
4929 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004930 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004931 eRet = OMX_ErrorInsufficientResources;
4932 }
4933 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004934}
4935
4936
4937/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004938 FUNCTION
4939 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004940
Arun Menon906de572013-06-18 17:01:40 -07004941 DESCRIPTION
4942 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004943
Arun Menon906de572013-06-18 17:01:40 -07004944 PARAMETERS
4945 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004946
Arun Menon906de572013-06-18 17:01:40 -07004947 RETURN VALUE
4948 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004949
Arun Menon906de572013-06-18 17:01:40 -07004950 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004951OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004952 OMX_IN OMX_HANDLETYPE hComp,
4953 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4954 OMX_IN OMX_U32 port,
4955 OMX_IN OMX_PTR appData,
4956 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004957{
Arun Menon906de572013-06-18 17:01:40 -07004958 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4959 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4960 unsigned i= 0; // Temporary counter
4961 struct vdec_setbuffer_cmd setbuffers;
4962 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004964 int ion_device_fd =-1;
4965 struct ion_allocation_data ion_alloc_data;
4966 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004967#endif
Arun Menon906de572013-06-18 17:01:40 -07004968 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004969 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004970 drv_ctx.op_buf.actualcount,
4971 drv_ctx.op_buf.buffer_size);
4972 int nBufHdrSize = 0;
4973 int nPlatformEntrySize = 0;
4974 int nPlatformListSize = 0;
4975 int nPMEMInfoSize = 0;
4976 int pmem_fd = -1;
4977 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004978
Arun Menon906de572013-06-18 17:01:40 -07004979 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4980 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4981 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004983 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004984 drv_ctx.op_buf.actualcount);
4985 nBufHdrSize = drv_ctx.op_buf.actualcount *
4986 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987
Arun Menon906de572013-06-18 17:01:40 -07004988 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4989 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4990 nPlatformListSize = drv_ctx.op_buf.actualcount *
4991 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4992 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4993 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004994
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004995 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004996 sizeof(OMX_BUFFERHEADERTYPE),
4997 nPMEMInfoSize,
4998 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004999 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005000 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005001#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005002 ion_device_fd = alloc_map_ion_memory(
5003 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5004 drv_ctx.op_buf.alignment,
5005 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5006 if (ion_device_fd < 0) {
5007 return OMX_ErrorInsufficientResources;
5008 }
5009 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005010#else
Arun Menon906de572013-06-18 17:01:40 -07005011 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005012
Arun Menon906de572013-06-18 17:01:40 -07005013 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005014 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005015 drv_ctx.op_buf.buffer_size);
5016 return OMX_ErrorInsufficientResources;
5017 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005018
Arun Menon906de572013-06-18 17:01:40 -07005019 if (pmem_fd == 0) {
5020 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005021
Arun Menon906de572013-06-18 17:01:40 -07005022 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005023 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005024 drv_ctx.op_buf.buffer_size);
5025 return OMX_ErrorInsufficientResources;
5026 }
5027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005028
Arun Menon906de572013-06-18 17:01:40 -07005029 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5030 drv_ctx.op_buf.actualcount,
5031 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005032 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005033 close(pmem_fd);
5034 return OMX_ErrorInsufficientResources;
5035 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005036#endif
Arun Menon906de572013-06-18 17:01:40 -07005037 if (!secure_mode) {
5038 pmem_baseaddress = (unsigned char *)mmap(NULL,
5039 (drv_ctx.op_buf.buffer_size *
5040 drv_ctx.op_buf.actualcount),
5041 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5042 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005043 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005044 drv_ctx.op_buf.buffer_size);
5045 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005047 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005048#endif
Arun Menon906de572013-06-18 17:01:40 -07005049 return OMX_ErrorInsufficientResources;
5050 }
5051 }
5052 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5053 // Alloc mem for platform specific info
5054 char *pPtr=NULL;
5055 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5056 nPMEMInfoSize,1);
5057 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5058 calloc (sizeof(struct vdec_bufferpayload),
5059 drv_ctx.op_buf.actualcount);
5060 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5061 calloc (sizeof (struct vdec_output_frameinfo),
5062 drv_ctx.op_buf.actualcount);
5063#ifdef USE_ION
5064 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5065 calloc (sizeof(struct vdec_ion),
5066 drv_ctx.op_buf.actualcount);
5067#endif
5068
5069 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5070 && drv_ctx.ptr_respbuffer) {
5071 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5072 (drv_ctx.op_buf.buffer_size *
5073 drv_ctx.op_buf.actualcount);
5074 bufHdr = m_out_mem_ptr;
5075 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5076 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5077 (((char *) m_platform_list) + nPlatformListSize);
5078 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5079 (((char *) m_platform_entry) + nPlatformEntrySize);
5080 pPlatformList = m_platform_list;
5081 pPlatformEntry = m_platform_entry;
5082 pPMEMInfo = m_pmem_info;
5083
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005084 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005085
5086 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005087 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5088 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005089 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5090 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5091 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5092 // Set the values when we determine the right HxW param
5093 bufHdr->nAllocLen = bytes;
5094 bufHdr->nFilledLen = 0;
5095 bufHdr->pAppPrivate = appData;
5096 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5097 // Platform specific PMEM Information
5098 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005099 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005100 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5101 pPlatformEntry->entry = pPMEMInfo;
5102 // Initialize the Platform List
5103 pPlatformList->nEntries = 1;
5104 pPlatformList->entryList = pPlatformEntry;
5105 // Keep pBuffer NULL till vdec is opened
5106 bufHdr->pBuffer = NULL;
5107 bufHdr->nOffset = 0;
5108
5109 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5110 pPMEMInfo->pmem_fd = 0;
5111 bufHdr->pPlatformPrivate = pPlatformList;
5112
5113 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5114 m_pmem_info[i].pmem_fd = pmem_fd;
5115#ifdef USE_ION
5116 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5117 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5118 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5119#endif
5120
5121 /*Create a mapping between buffers*/
5122 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5123 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5124 &drv_ctx.ptr_outputbuffer[i];
5125 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5126 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5127 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305128 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5129 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5130 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005131
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005132 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005133 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5134 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5135 // Move the buffer and buffer header pointers
5136 bufHdr++;
5137 pPMEMInfo++;
5138 pPlatformEntry++;
5139 pPlatformList++;
5140 }
5141 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005142 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005143 m_out_mem_ptr, pPtr);
5144 if (m_out_mem_ptr) {
5145 free(m_out_mem_ptr);
5146 m_out_mem_ptr = NULL;
5147 }
5148 if (pPtr) {
5149 free(pPtr);
5150 pPtr = NULL;
5151 }
5152 if (drv_ctx.ptr_outputbuffer) {
5153 free(drv_ctx.ptr_outputbuffer);
5154 drv_ctx.ptr_outputbuffer = NULL;
5155 }
5156 if (drv_ctx.ptr_respbuffer) {
5157 free(drv_ctx.ptr_respbuffer);
5158 drv_ctx.ptr_respbuffer = NULL;
5159 }
5160#ifdef USE_ION
5161 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005162 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005163 free(drv_ctx.op_buf_ion_info);
5164 drv_ctx.op_buf_ion_info = NULL;
5165 }
5166#endif
5167 eRet = OMX_ErrorInsufficientResources;
5168 }
5169 if (eRet == OMX_ErrorNone)
5170 eRet = allocate_extradata();
5171 }
5172
5173 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5174 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005175 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005176 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005177 }
5178 }
Arun Menon906de572013-06-18 17:01:40 -07005179
5180 if (eRet == OMX_ErrorNone) {
5181 if (i < drv_ctx.op_buf.actualcount) {
5182 struct v4l2_buffer buf;
5183 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5184 int rc;
5185 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5186
5187 drv_ctx.ptr_outputbuffer[i].buffer_len =
5188 drv_ctx.op_buf.buffer_size;
5189
5190 *bufferHdr = (m_out_mem_ptr + i );
5191 if (secure_mode) {
5192 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5193 }
5194 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5195
5196 buf.index = i;
5197 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5198 buf.memory = V4L2_MEMORY_USERPTR;
5199 plane[0].length = drv_ctx.op_buf.buffer_size;
5200 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5201 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005202#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005203 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204#endif
Arun Menon906de572013-06-18 17:01:40 -07005205 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5206 plane[0].data_offset = 0;
5207 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5208 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5209 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5210 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 -07005211#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005212 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005213#endif
Arun Menon906de572013-06-18 17:01:40 -07005214 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5215 plane[extra_idx].data_offset = 0;
5216 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005217 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005218 return OMX_ErrorBadParameter;
5219 }
5220 buf.m.planes = plane;
5221 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005222 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 -07005223 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5224 if (rc) {
5225 /*TODO: How to handle this case */
5226 return OMX_ErrorInsufficientResources;
5227 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5230 enum v4l2_buf_type buf_type;
5231 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5232 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5233 if (rc) {
5234 return OMX_ErrorInsufficientResources;
5235 } else {
5236 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005237 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005238 }
5239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005240
Arun Menon906de572013-06-18 17:01:40 -07005241 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5242 (*bufferHdr)->pAppPrivate = appData;
5243 BITMASK_SET(&m_out_bm_count,i);
5244 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005245 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005246 eRet = OMX_ErrorInsufficientResources;
5247 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005248 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249
Arun Menon906de572013-06-18 17:01:40 -07005250 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005251}
5252
5253
5254// AllocateBuffer -- API Call
5255/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005256 FUNCTION
5257 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005258
Arun Menon906de572013-06-18 17:01:40 -07005259 DESCRIPTION
5260 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005261
Arun Menon906de572013-06-18 17:01:40 -07005262 PARAMETERS
5263 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264
Arun Menon906de572013-06-18 17:01:40 -07005265 RETURN VALUE
5266 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267
Arun Menon906de572013-06-18 17:01:40 -07005268 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005269OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005270 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5271 OMX_IN OMX_U32 port,
5272 OMX_IN OMX_PTR appData,
5273 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005274{
5275 unsigned i = 0;
5276 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5277
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005278 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005279 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005280 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005281 return OMX_ErrorInvalidState;
5282 }
5283
Arun Menon906de572013-06-18 17:01:40 -07005284 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5285 if (arbitrary_bytes) {
5286 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5287 } else {
5288 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5289 }
5290 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005291 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5292 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005293 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005294 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005295 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005296 }
5297 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005298 if (eRet == OMX_ErrorNone) {
5299 if (allocate_done()) {
5300 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005301 // Send the callback now
5302 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5303 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005304 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005305 }
5306 }
Arun Menon906de572013-06-18 17:01:40 -07005307 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5308 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5309 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5310 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005311 OMX_CORE_INPUT_PORT_INDEX,
5312 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005313 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005314 }
Arun Menon906de572013-06-18 17:01:40 -07005315 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5316 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5317 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005318 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005319 OMX_CORE_OUTPUT_PORT_INDEX,
5320 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005321 }
5322 }
5323 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005324 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005325 return eRet;
5326}
5327
5328// Free Buffer - API call
5329/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005330 FUNCTION
5331 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005332
Arun Menon906de572013-06-18 17:01:40 -07005333 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005334
Arun Menon906de572013-06-18 17:01:40 -07005335 PARAMETERS
5336 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005337
Arun Menon906de572013-06-18 17:01:40 -07005338 RETURN VALUE
5339 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005340
Arun Menon906de572013-06-18 17:01:40 -07005341 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005342OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005343 OMX_IN OMX_U32 port,
5344 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345{
5346 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5347 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005348 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005349
Arun Menon906de572013-06-18 17:01:40 -07005350 if (m_state == OMX_StateIdle &&
5351 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005352 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005353 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5354 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005355 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005356 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5357 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5358 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5359 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005360 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005361 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005362 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005363 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005364 OMX_ErrorPortUnpopulated,
5365 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005366
5367 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005368 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005369 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005370 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005371 OMX_ErrorPortUnpopulated,
5372 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005373 }
5374
Arun Menon906de572013-06-18 17:01:40 -07005375 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5376 /*Check if arbitrary bytes*/
5377 if (!arbitrary_bytes && !input_use_buffer)
5378 nPortIndex = buffer - m_inp_mem_ptr;
5379 else
5380 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005381
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005382 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005383 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5384 // Clear the bit associated with it.
5385 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5386 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5387 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005388
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005389 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005390 if (m_phdr_pmem_ptr)
5391 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5392 } else {
5393 if (arbitrary_bytes) {
5394 if (m_phdr_pmem_ptr)
5395 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5396 else
5397 free_input_buffer(nPortIndex,NULL);
5398 } else
5399 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005400 }
Arun Menon906de572013-06-18 17:01:40 -07005401 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305402 if(release_input_done())
5403 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005404 /*Free the Buffer Header*/
5405 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005406 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005407 free_input_buffer_header();
5408 }
5409 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005410 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411 eRet = OMX_ErrorBadPortIndex;
5412 }
5413
Arun Menon906de572013-06-18 17:01:40 -07005414 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5415 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005416 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005417 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5418 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005419 OMX_CORE_INPUT_PORT_INDEX,
5420 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005421 }
Arun Menon906de572013-06-18 17:01:40 -07005422 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005423 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005424 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005425 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005426 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427 // Clear the bit associated with it.
5428 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5429 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005430 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Surajit Podder12aefac2013-08-06 18:43:32 +05305432 if(release_output_done()) {
5433 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5434 }
Arun Menon906de572013-06-18 17:01:40 -07005435 if (release_output_done()) {
5436 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005437 }
Arun Menon906de572013-06-18 17:01:40 -07005438 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005439 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005440 eRet = OMX_ErrorBadPortIndex;
5441 }
Arun Menon906de572013-06-18 17:01:40 -07005442 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5443 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005444 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005445
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005446 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005447 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005448#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005449 if (m_enable_android_native_buffers) {
5450 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5451 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453#endif
5454
Arun Menon906de572013-06-18 17:01:40 -07005455 post_event(OMX_CommandPortDisable,
5456 OMX_CORE_OUTPUT_PORT_INDEX,
5457 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458 }
Arun Menon906de572013-06-18 17:01:40 -07005459 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460 eRet = OMX_ErrorBadPortIndex;
5461 }
Arun Menon906de572013-06-18 17:01:40 -07005462 if ((eRet == OMX_ErrorNone) &&
5463 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5464 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465 // Send the callback now
5466 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5467 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005468 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005469 }
5470 }
5471 return eRet;
5472}
5473
5474
5475/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005476 FUNCTION
5477 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005478
Arun Menon906de572013-06-18 17:01:40 -07005479 DESCRIPTION
5480 This routine is used to push the encoded video frames to
5481 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005482
Arun Menon906de572013-06-18 17:01:40 -07005483 PARAMETERS
5484 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 RETURN VALUE
5487 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488
Arun Menon906de572013-06-18 17:01:40 -07005489 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005490OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005491 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492{
Arun Menon906de572013-06-18 17:01:40 -07005493 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5494 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495
Arun Menon906de572013-06-18 17:01:40 -07005496 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005497 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005498 return OMX_ErrorInvalidState;
5499 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005500
Arun Menon906de572013-06-18 17:01:40 -07005501 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005502 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005503 return OMX_ErrorBadParameter;
5504 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005505
Arun Menon906de572013-06-18 17:01:40 -07005506 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005507 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005508 return OMX_ErrorIncorrectStateOperation;
5509 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510
Arun Menon906de572013-06-18 17:01:40 -07005511 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005512 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005513 return OMX_ErrorBadPortIndex;
5514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005515
5516#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005517 if (iDivXDrmDecrypt) {
5518 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5519 if (drmErr != OMX_ErrorNone) {
5520 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005521 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005524#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005525 if (perf_flag) {
5526 if (!latency) {
5527 dec_time.stop();
5528 latency = dec_time.processing_time_us();
5529 dec_time.start();
5530 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005531 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005532
Arun Menon906de572013-06-18 17:01:40 -07005533 if (arbitrary_bytes) {
5534 nBufferIndex = buffer - m_inp_heap_ptr;
5535 } else {
5536 if (input_use_buffer == true) {
5537 nBufferIndex = buffer - m_inp_heap_ptr;
5538 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5539 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5540 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5541 buffer = &m_inp_mem_ptr[nBufferIndex];
5542 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5543 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5544 } else {
5545 nBufferIndex = buffer - m_inp_mem_ptr;
5546 }
5547 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005548
Arun Menon906de572013-06-18 17:01:40 -07005549 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005550 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005551 return OMX_ErrorBadParameter;
5552 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005553
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005554 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5555 codec_config_flag = true;
5556 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5557 }
5558
Arun Menon906de572013-06-18 17:01:40 -07005559 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5560 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5561 if (arbitrary_bytes) {
5562 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005563 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005564 } else {
Arun Menon906de572013-06-18 17:01:40 -07005565 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5566 }
5567 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005568}
5569
5570/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005571 FUNCTION
5572 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005573
Arun Menon906de572013-06-18 17:01:40 -07005574 DESCRIPTION
5575 This routine is used to push the encoded video frames to
5576 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577
Arun Menon906de572013-06-18 17:01:40 -07005578 PARAMETERS
5579 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005580
Arun Menon906de572013-06-18 17:01:40 -07005581 RETURN VALUE
5582 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005583
Arun Menon906de572013-06-18 17:01:40 -07005584 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005586 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005587{
Arun Menon906de572013-06-18 17:01:40 -07005588 int push_cnt = 0,i=0;
5589 unsigned nPortIndex = 0;
5590 OMX_ERRORTYPE ret = OMX_ErrorNone;
5591 struct vdec_input_frameinfo frameinfo;
5592 struct vdec_bufferpayload *temp_buffer;
5593 struct vdec_seqheader seq_header;
5594 bool port_setting_changed = true;
5595 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005596
Arun Menon906de572013-06-18 17:01:40 -07005597 /*Should we generate a Aync error event*/
5598 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005599 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005600 return OMX_ErrorBadParameter;
5601 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602
Arun Menon906de572013-06-18 17:01:40 -07005603 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604
Arun Menon906de572013-06-18 17:01:40 -07005605 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005606 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005607 nPortIndex);
5608 return OMX_ErrorBadParameter;
5609 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005610
Arun Menon906de572013-06-18 17:01:40 -07005611 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Arun Menon906de572013-06-18 17:01:40 -07005613 /* return zero length and not an EOS buffer */
5614 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5615 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005616 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005617 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5618 OMX_COMPONENT_GENERATE_EBD);
5619 return OMX_ErrorNone;
5620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005621
5622
Arun Menon906de572013-06-18 17:01:40 -07005623 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5624 mp4StreamType psBits;
5625 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5626 psBits.numBytes = buffer->nFilledLen;
5627 mp4_headerparser.parseHeader(&psBits);
5628 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5629 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5630 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005631 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005632 buffer->nFilledLen,frame_count);
5633 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005634 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005635 not_coded_vop = false;
5636 buffer->nFilledLen = 0;
5637 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005638 }
5639 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640
Arun Menon906de572013-06-18 17:01:40 -07005641 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005642
Arun Menon906de572013-06-18 17:01:40 -07005643 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005644
Arun Menon906de572013-06-18 17:01:40 -07005645 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005646 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005647 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5648 OMX_COMPONENT_GENERATE_EBD);
5649 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005650 }
5651
Arun Menon906de572013-06-18 17:01:40 -07005652 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005653
Surajit Podderd2644d52013-08-28 17:59:06 +05305654 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005655 return OMX_ErrorBadParameter;
5656 }
5657 /* If its first frame, H264 codec and reject is true, then parse the nal
5658 and get the profile. Based on this, reject the clip playback */
5659 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5660 m_reject_avc_1080p_mp) {
5661 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005662 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005663 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5664 NALU_TYPE_SPS);
5665 m_profile = h264_parser->get_profile();
5666 ret = is_video_session_supported();
5667 if (ret) {
5668 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5669 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5670 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5671 m_state = OMX_StateInvalid;
5672 return OMX_ErrorNone;
5673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005674 }
5675
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005676 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005677 /*for use buffer we need to memcpy the data*/
5678 temp_buffer->buffer_len = buffer->nFilledLen;
5679
5680 if (input_use_buffer) {
5681 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5682 if (arbitrary_bytes) {
5683 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5684 } else {
5685 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5686 buffer->nFilledLen);
5687 }
5688 } else {
5689 return OMX_ErrorBadParameter;
5690 }
5691
5692 }
5693
5694 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5695 frameinfo.client_data = (void *) buffer;
5696 frameinfo.datalen = temp_buffer->buffer_len;
5697 frameinfo.flags = 0;
5698 frameinfo.offset = buffer->nOffset;
5699 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5700 frameinfo.pmem_offset = temp_buffer->offset;
5701 frameinfo.timestamp = buffer->nTimeStamp;
5702 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5703 DEBUG_PRINT_LOW("ETB: dmx enabled");
5704 if (m_demux_entries == 0) {
5705 extract_demux_addr_offsets(buffer);
5706 }
5707
5708 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5709 handle_demux_data(buffer);
5710 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5711 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5712 } else {
5713 frameinfo.desc_addr = NULL;
5714 frameinfo.desc_size = 0;
5715 }
5716 if (!arbitrary_bytes) {
5717 frameinfo.flags |= buffer->nFlags;
5718 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005719
5720#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005721 if (m_debug_timestamp) {
5722 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005723 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005724 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5725 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005726 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005727 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5728 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730#endif
5731
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005732log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005733
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005734if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005735 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5736 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005740 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005741 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5742 h264_scratch.nFilledLen = 0;
5743 nal_count = 0;
5744 look_ahead_nal = false;
5745 frame_count = 0;
5746 if (m_frame_parser.mutils)
5747 m_frame_parser.mutils->initialize_frame_checking_environment();
5748 m_frame_parser.flush();
5749 h264_last_au_ts = LLONG_MAX;
5750 h264_last_au_flags = 0;
5751 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5752 m_demux_entries = 0;
5753 }
5754 struct v4l2_buffer buf;
5755 struct v4l2_plane plane;
5756 memset( (void *)&buf, 0, sizeof(buf));
5757 memset( (void *)&plane, 0, sizeof(plane));
5758 int rc;
5759 unsigned long print_count;
5760 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005761 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005762 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005763 }
5764 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5765 buf.index = nPortIndex;
5766 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5767 buf.memory = V4L2_MEMORY_USERPTR;
5768 plane.bytesused = temp_buffer->buffer_len;
5769 plane.length = drv_ctx.ip_buf.buffer_size;
5770 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5771 (unsigned long)temp_buffer->offset;
5772 plane.reserved[0] = temp_buffer->pmem_fd;
5773 plane.reserved[1] = temp_buffer->offset;
5774 plane.data_offset = 0;
5775 buf.m.planes = &plane;
5776 buf.length = 1;
5777 if (frameinfo.timestamp >= LLONG_MAX) {
5778 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5779 }
5780 //assumption is that timestamp is in milliseconds
5781 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5782 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5783 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5784 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005785
Arun Menon906de572013-06-18 17:01:40 -07005786 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5787 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005788 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005789 return OMX_ErrorHardware;
5790 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005791 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5792 codec_config_flag = false;
5793 }
Arun Menon906de572013-06-18 17:01:40 -07005794 if (!streaming[OUTPUT_PORT]) {
5795 enum v4l2_buf_type buf_type;
5796 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005797
Arun Menon906de572013-06-18 17:01:40 -07005798 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005799 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005800 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5801 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005802 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005803 streaming[OUTPUT_PORT] = true;
5804 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005805 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005806 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5807 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5808 OMX_COMPONENT_GENERATE_EBD);
5809 return OMX_ErrorBadParameter;
5810 }
5811 }
5812 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5813 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5814 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005815
Arun Menon906de572013-06-18 17:01:40 -07005816 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005817}
5818
5819/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005820 FUNCTION
5821 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822
Arun Menon906de572013-06-18 17:01:40 -07005823 DESCRIPTION
5824 IL client uses this method to release the frame buffer
5825 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005826
Arun Menon906de572013-06-18 17:01:40 -07005827 PARAMETERS
5828 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005829
Arun Menon906de572013-06-18 17:01:40 -07005830 RETURN VALUE
5831 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005832
Arun Menon906de572013-06-18 17:01:40 -07005833 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005835 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005836{
Arun Menonbdb80b02013-08-12 17:45:54 -07005837 if (dynamic_buf_mode) {
5838 private_handle_t *handle = NULL;
5839 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005840 unsigned int nPortIndex = 0;
5841
5842 if (!buffer || !buffer->pBuffer) {
5843 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5844 return OMX_ErrorBadParameter;
5845 }
5846
5847 //get the buffer type and fd info
5848 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5849 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005850 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5851
5852 if (!handle) {
5853 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5854 return OMX_ErrorBadParameter;
5855 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005856 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5857 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5858 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005859 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005860
5861 //Store private handle from GraphicBuffer
5862 native_buffer[nPortIndex].privatehandle = handle;
5863 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005865
Arun Menon906de572013-06-18 17:01:40 -07005866 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005867 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005868 return OMX_ErrorInvalidState;
5869 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005870
Arun Menon906de572013-06-18 17:01:40 -07005871 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005872 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005873 return OMX_ErrorIncorrectStateOperation;
5874 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005875
Arun Menon906de572013-06-18 17:01:40 -07005876 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305877 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005878 return OMX_ErrorBadParameter;
5879 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005880
Arun Menon906de572013-06-18 17:01:40 -07005881 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005882 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005883 return OMX_ErrorBadPortIndex;
5884 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005885
Arun Menon906de572013-06-18 17:01:40 -07005886 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5887 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5888 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005889}
5890/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005891 FUNCTION
5892 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005893
Arun Menon906de572013-06-18 17:01:40 -07005894 DESCRIPTION
5895 IL client uses this method to release the frame buffer
5896 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005897
Arun Menon906de572013-06-18 17:01:40 -07005898 PARAMETERS
5899 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005900
Arun Menon906de572013-06-18 17:01:40 -07005901 RETURN VALUE
5902 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005903
Arun Menon906de572013-06-18 17:01:40 -07005904 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005906 OMX_IN OMX_HANDLETYPE hComp,
5907 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005908{
Arun Menon906de572013-06-18 17:01:40 -07005909 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5910 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5911 unsigned nPortIndex = 0;
5912 struct vdec_fillbuffer_cmd fillbuffer;
5913 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5914 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005915
Arun Menon906de572013-06-18 17:01:40 -07005916 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005917
Arun Menon906de572013-06-18 17:01:40 -07005918 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5919 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005920
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005921 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005922 bufferAdd, bufferAdd->pBuffer);
5923 /*Return back the output buffer to client*/
5924 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005925 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005926 buffer->nFilledLen = 0;
5927 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5928 return OMX_ErrorNone;
5929 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005930
5931 if (dynamic_buf_mode) {
5932 //map the buffer handle based on the size set on output port definition.
5933 if (!secure_mode) {
5934 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5935 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5936 PROT_READ|PROT_WRITE, MAP_SHARED,
5937 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5938 }
5939 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5940 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5941 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5942 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5943 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5944 }
5945
Arun Menon906de572013-06-18 17:01:40 -07005946 pending_output_buffers++;
5947 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5948 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5949 if (ptr_respbuffer) {
5950 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5951 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952
Arun Menon906de572013-06-18 17:01:40 -07005953 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5954 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5955 buffer->nFilledLen = 0;
5956 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5957 pending_output_buffers--;
5958 return OMX_ErrorBadParameter;
5959 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005960
Arun Menon906de572013-06-18 17:01:40 -07005961 int rc = 0;
5962 struct v4l2_buffer buf;
5963 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5964 memset( (void *)&buf, 0, sizeof(buf));
5965 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5966 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005967
Arun Menon906de572013-06-18 17:01:40 -07005968 buf.index = nPortIndex;
5969 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5970 buf.memory = V4L2_MEMORY_USERPTR;
5971 plane[0].bytesused = buffer->nFilledLen;
5972 plane[0].length = drv_ctx.op_buf.buffer_size;
5973 plane[0].m.userptr =
5974 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5975 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5976 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5977 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5978 plane[0].data_offset = 0;
5979 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5980 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5981 plane[extra_idx].bytesused = 0;
5982 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5983 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 -07005984#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005985 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005986#endif
Arun Menon906de572013-06-18 17:01:40 -07005987 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5988 plane[extra_idx].data_offset = 0;
5989 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005990 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005991 return OMX_ErrorBadParameter;
5992 }
5993 buf.m.planes = plane;
5994 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005995 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005996 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5997
Arun Menon906de572013-06-18 17:01:40 -07005998 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5999 if (rc) {
6000 /*TODO: How to handle this case */
6001 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6002 }
Arun Menon906de572013-06-18 17:01:40 -07006003return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006004}
6005
6006/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006007 FUNCTION
6008 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006009
Arun Menon906de572013-06-18 17:01:40 -07006010 DESCRIPTION
6011 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006012
Arun Menon906de572013-06-18 17:01:40 -07006013 PARAMETERS
6014 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006015
Arun Menon906de572013-06-18 17:01:40 -07006016 RETURN VALUE
6017 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006018
Arun Menon906de572013-06-18 17:01:40 -07006019 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006020OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006021 OMX_IN OMX_CALLBACKTYPE* callbacks,
6022 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006023{
6024
Arun Menon906de572013-06-18 17:01:40 -07006025 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006026 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006027 m_cb.EventHandler,m_cb.FillBufferDone);
6028 m_app_data = appData;
6029 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030}
6031
6032/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006033 FUNCTION
6034 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006035
Arun Menon906de572013-06-18 17:01:40 -07006036 DESCRIPTION
6037 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006038
Arun Menon906de572013-06-18 17:01:40 -07006039 PARAMETERS
6040 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006041
Arun Menon906de572013-06-18 17:01:40 -07006042 RETURN VALUE
6043 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006046OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6047{
6048#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006049 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006050 delete iDivXDrmDecrypt;
6051 iDivXDrmDecrypt=NULL;
6052 }
6053#endif //_ANDROID_
6054
Shalaj Jain286b0062013-02-21 20:35:48 -08006055 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006056 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006057 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006058 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006059 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006060 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006061 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006062 }
6063
6064 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006065 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006066 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006067 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6068 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069 }
6070#ifdef _ANDROID_ICS_
6071 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6072#endif
6073 }
6074
6075 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006076 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006077 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006078 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6079 if (m_inp_mem_ptr)
6080 free_input_buffer (i,&m_inp_mem_ptr[i]);
6081 else
6082 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083 }
6084 }
6085 free_input_buffer_header();
6086 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006087 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088 free(h264_scratch.pBuffer);
6089 h264_scratch.pBuffer = NULL;
6090 }
6091
Arun Menon906de572013-06-18 17:01:40 -07006092 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006093 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006094 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006095 }
6096
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006097 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006098 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006099 delete (m_frame_parser.mutils);
6100 m_frame_parser.mutils = NULL;
6101 }
6102
Arun Menon906de572013-06-18 17:01:40 -07006103 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006104 free(m_platform_list);
6105 m_platform_list = NULL;
6106 }
Arun Menon906de572013-06-18 17:01:40 -07006107 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108 free(m_vendor_config.pData);
6109 m_vendor_config.pData = NULL;
6110 }
6111
6112 // Reset counters in mesg queues
6113 m_ftb_q.m_size=0;
6114 m_cmd_q.m_size=0;
6115 m_etb_q.m_size=0;
6116 m_ftb_q.m_read = m_ftb_q.m_write =0;
6117 m_cmd_q.m_read = m_cmd_q.m_write =0;
6118 m_etb_q.m_read = m_etb_q.m_write =0;
6119#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006120 if (m_debug_timestamp) {
6121 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006122 }
6123#endif
6124
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006125 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006126 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006127 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006128 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006129
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006130 if (m_debug.infile) {
6131 fclose(m_debug.infile);
6132 m_debug.infile = NULL;
6133 }
6134 if (m_debug.outfile) {
6135 fclose(m_debug.outfile);
6136 m_debug.outfile = NULL;
6137 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006138#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006139 if (outputExtradataFile)
6140 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006141#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006142 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006143 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144}
6145
6146/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006147 FUNCTION
6148 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006149
Arun Menon906de572013-06-18 17:01:40 -07006150 DESCRIPTION
6151 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006152
Arun Menon906de572013-06-18 17:01:40 -07006153 PARAMETERS
6154 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006155
Arun Menon906de572013-06-18 17:01:40 -07006156 RETURN VALUE
6157 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006158
Arun Menon906de572013-06-18 17:01:40 -07006159 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006160OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006161 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6162 OMX_IN OMX_U32 port,
6163 OMX_IN OMX_PTR appData,
6164 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165{
Arun Menon906de572013-06-18 17:01:40 -07006166 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6167 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6168 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006169
6170#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006171 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6172 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006173#else
Arun Menon906de572013-06-18 17:01:40 -07006174 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006175#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006176 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006177 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006178 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006179 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006180#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006181 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006182 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006184 }
6185 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6186 eglGetProcAddress("eglQueryImageKHR");
6187 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6188 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6189 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006190#else //with OMX test app
6191 struct temp_egl {
6192 int pmem_fd;
6193 int offset;
6194 };
6195 struct temp_egl *temp_egl_id = NULL;
6196 void * pmemPtr = (void *) eglImage;
6197 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006198 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006199 fd = temp_egl_id->pmem_fd;
6200 offset = temp_egl_id->offset;
6201 }
6202#endif
6203 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006204 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006205 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006206 }
6207 pmem_info.pmem_fd = (OMX_U32) fd;
6208 pmem_info.offset = (OMX_U32) offset;
6209 pmem_entry.entry = (void *) &pmem_info;
6210 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6211 pmem_list.entryList = &pmem_entry;
6212 pmem_list.nEntries = 1;
6213 ouput_egl_buffers = true;
6214 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6215 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6216 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006217 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006218 return OMX_ErrorInsufficientResources;
6219 }
6220 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006221}
6222
6223/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006224 FUNCTION
6225 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006226
Arun Menon906de572013-06-18 17:01:40 -07006227 DESCRIPTION
6228 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229
Arun Menon906de572013-06-18 17:01:40 -07006230 PARAMETERS
6231 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006232
Arun Menon906de572013-06-18 17:01:40 -07006233 RETURN VALUE
6234 OMX Error None if everything is successful.
6235 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006236OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006237 OMX_OUT OMX_U8* role,
6238 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006239{
Arun Menon906de572013-06-18 17:01:40 -07006240 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241
Arun Menon906de572013-06-18 17:01:40 -07006242 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6243 if ((0 == index) && role) {
6244 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006245 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006246 } else {
6247 eRet = OMX_ErrorNoMore;
6248 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006249 }
Arun Menon906de572013-06-18 17:01:40 -07006250 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6251 if ((0 == index) && role) {
6252 strlcpy((char *)role, "video_decoder.mpeg2",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 {
6255 eRet = OMX_ErrorNoMore;
6256 }
6257 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6258 if ((0 == index) && role) {
6259 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006260 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006261 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006262 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006263 eRet = OMX_ErrorNoMore;
6264 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006265 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006266
Arun Menon906de572013-06-18 17:01:40 -07006267 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6268 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6269 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006270
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271 {
Arun Menon906de572013-06-18 17:01:40 -07006272 if ((0 == index) && role) {
6273 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006274 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006275 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006276 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006277 eRet = OMX_ErrorNoMore;
6278 }
6279 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6280 if ((0 == index) && role) {
6281 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006282 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006283 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006284 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006285 eRet = OMX_ErrorNoMore;
6286 }
6287 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6288 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6289 ) {
6290 if ((0 == index) && role) {
6291 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006292 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006293 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006294 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006295 eRet = OMX_ErrorNoMore;
6296 }
6297 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6298 if ((0 == index) && role) {
6299 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006300 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006301 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006302 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006303 eRet = OMX_ErrorNoMore;
6304 }
6305 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006306 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006307 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006308 }
Arun Menon906de572013-06-18 17:01:40 -07006309 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310}
6311
6312
6313
6314
6315/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006316 FUNCTION
6317 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006318
Arun Menon906de572013-06-18 17:01:40 -07006319 DESCRIPTION
6320 Checks if entire buffer pool is allocated by IL Client or not.
6321 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006322
Arun Menon906de572013-06-18 17:01:40 -07006323 PARAMETERS
6324 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006325
Arun Menon906de572013-06-18 17:01:40 -07006326 RETURN VALUE
6327 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006328
Arun Menon906de572013-06-18 17:01:40 -07006329 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006330bool omx_vdec::allocate_done(void)
6331{
Arun Menon906de572013-06-18 17:01:40 -07006332 bool bRet = false;
6333 bool bRet_In = false;
6334 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006335
Arun Menon906de572013-06-18 17:01:40 -07006336 bRet_In = allocate_input_done();
6337 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006338
Arun Menon906de572013-06-18 17:01:40 -07006339 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006340 bRet = true;
6341 }
Arun Menon906de572013-06-18 17:01:40 -07006342
6343 return bRet;
6344}
6345/* ======================================================================
6346 FUNCTION
6347 omx_vdec::AllocateInputDone
6348
6349 DESCRIPTION
6350 Checks if I/P buffer pool is allocated by IL Client or not.
6351
6352 PARAMETERS
6353 None.
6354
6355 RETURN VALUE
6356 true/false.
6357
6358 ========================================================================== */
6359bool omx_vdec::allocate_input_done(void)
6360{
6361 bool bRet = false;
6362 unsigned i=0;
6363
6364 if (m_inp_mem_ptr == NULL) {
6365 return bRet;
6366 }
6367 if (m_inp_mem_ptr ) {
6368 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6369 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6370 break;
6371 }
6372 }
6373 }
6374 if (i == drv_ctx.ip_buf.actualcount) {
6375 bRet = true;
6376 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6377 }
6378 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6379 m_inp_bPopulated = OMX_TRUE;
6380 }
6381 return bRet;
6382}
6383/* ======================================================================
6384 FUNCTION
6385 omx_vdec::AllocateOutputDone
6386
6387 DESCRIPTION
6388 Checks if entire O/P buffer pool is allocated by IL Client or not.
6389
6390 PARAMETERS
6391 None.
6392
6393 RETURN VALUE
6394 true/false.
6395
6396 ========================================================================== */
6397bool omx_vdec::allocate_output_done(void)
6398{
6399 bool bRet = false;
6400 unsigned j=0;
6401
6402 if (m_out_mem_ptr == NULL) {
6403 return bRet;
6404 }
6405
6406 if (m_out_mem_ptr) {
6407 for (; j < drv_ctx.op_buf.actualcount; j++) {
6408 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6409 break;
6410 }
6411 }
6412 }
6413
6414 if (j == drv_ctx.op_buf.actualcount) {
6415 bRet = true;
6416 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6417 if (m_out_bEnabled)
6418 m_out_bPopulated = OMX_TRUE;
6419 }
6420
6421 return bRet;
6422}
6423
6424/* ======================================================================
6425 FUNCTION
6426 omx_vdec::ReleaseDone
6427
6428 DESCRIPTION
6429 Checks if IL client has released all the buffers.
6430
6431 PARAMETERS
6432 None.
6433
6434 RETURN VALUE
6435 true/false
6436
6437 ========================================================================== */
6438bool omx_vdec::release_done(void)
6439{
6440 bool bRet = false;
6441
6442 if (release_input_done()) {
6443 if (release_output_done()) {
6444 bRet = true;
6445 }
6446 }
6447 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006448}
6449
6450
6451/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006452 FUNCTION
6453 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006454
Arun Menon906de572013-06-18 17:01:40 -07006455 DESCRIPTION
6456 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457
Arun Menon906de572013-06-18 17:01:40 -07006458 PARAMETERS
6459 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006460
Arun Menon906de572013-06-18 17:01:40 -07006461 RETURN VALUE
6462 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006463
Arun Menon906de572013-06-18 17:01:40 -07006464 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006465bool omx_vdec::release_output_done(void)
6466{
Arun Menon906de572013-06-18 17:01:40 -07006467 bool bRet = false;
6468 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006469
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006470 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006471 if (m_out_mem_ptr) {
6472 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6473 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6474 break;
6475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006476 }
Arun Menon906de572013-06-18 17:01:40 -07006477 if (j == drv_ctx.op_buf.actualcount) {
6478 m_out_bm_count = 0;
6479 bRet = true;
6480 }
6481 } else {
6482 m_out_bm_count = 0;
6483 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006484 }
Arun Menon906de572013-06-18 17:01:40 -07006485 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006486}
6487/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006488 FUNCTION
6489 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006490
Arun Menon906de572013-06-18 17:01:40 -07006491 DESCRIPTION
6492 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006493
Arun Menon906de572013-06-18 17:01:40 -07006494 PARAMETERS
6495 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006496
Arun Menon906de572013-06-18 17:01:40 -07006497 RETURN VALUE
6498 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006499
Arun Menon906de572013-06-18 17:01:40 -07006500 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006501bool omx_vdec::release_input_done(void)
6502{
Arun Menon906de572013-06-18 17:01:40 -07006503 bool bRet = false;
6504 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006505
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006506 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006507 if (m_inp_mem_ptr) {
6508 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6509 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6510 break;
6511 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006512 }
Arun Menon906de572013-06-18 17:01:40 -07006513 if (j==drv_ctx.ip_buf.actualcount) {
6514 bRet = true;
6515 }
6516 } else {
6517 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006518 }
Arun Menon906de572013-06-18 17:01:40 -07006519 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006520}
6521
6522OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006523 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006524{
Arun Menon906de572013-06-18 17:01:40 -07006525 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306526 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006527 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006528 return OMX_ErrorBadParameter;
6529 } else if (output_flush_progress) {
6530 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6531 buffer->nFilledLen = 0;
6532 buffer->nTimeStamp = 0;
6533 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6534 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6535 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006536 }
6537
Arun Menon906de572013-06-18 17:01:40 -07006538 if (m_debug_extradata) {
6539 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006540 DEBUG_PRINT_HIGH("");
6541 DEBUG_PRINT_HIGH("***************************************************");
6542 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6543 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006544 }
6545
6546 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006547 DEBUG_PRINT_HIGH("");
6548 DEBUG_PRINT_HIGH("***************************************************");
6549 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6550 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006551 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006552 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006553
6554
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006555 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006556 buffer, buffer->pBuffer);
6557 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006558
Arun Menon906de572013-06-18 17:01:40 -07006559 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006560 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006561 if (!output_flush_progress)
6562 post_event((unsigned)NULL, (unsigned)NULL,
6563 OMX_COMPONENT_GENERATE_EOS_DONE);
6564
6565 if (psource_frame) {
6566 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6567 psource_frame = NULL;
6568 }
6569 if (pdest_frame) {
6570 pdest_frame->nFilledLen = 0;
6571 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6572 (unsigned)NULL);
6573 pdest_frame = NULL;
6574 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006575 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006576
Shalaj Jain273b3e02012-06-22 19:08:03 -07006577
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006578 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6579 DEBUG_PRINT_LOW("Processing extradata");
6580 handle_extradata(buffer);
6581 }
6582
Arun Menon906de572013-06-18 17:01:40 -07006583 /* For use buffer we need to copy the data */
6584 if (!output_flush_progress) {
6585 /* This is the error check for non-recoverable errros */
6586 bool is_duplicate_ts_valid = true;
6587 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006588
Arun Menon906de572013-06-18 17:01:40 -07006589 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6590 output_capability == V4L2_PIX_FMT_MPEG2 ||
6591 output_capability == V4L2_PIX_FMT_DIVX ||
6592 output_capability == V4L2_PIX_FMT_DIVX_311)
6593 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006594
Arun Menon906de572013-06-18 17:01:40 -07006595 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6596 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6597 if (mbaff) {
6598 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306599 }
Arun Menon906de572013-06-18 17:01:40 -07006600 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306601
Arun Menon906de572013-06-18 17:01:40 -07006602 if (buffer->nFilledLen > 0) {
6603 time_stamp_dts.get_next_timestamp(buffer,
6604 is_interlaced && is_duplicate_ts_valid);
6605 if (m_debug_timestamp) {
6606 {
6607 OMX_TICKS expected_ts = 0;
6608 m_timestamp_list.pop_min_ts(expected_ts);
6609 if (is_interlaced && is_duplicate_ts_valid) {
6610 m_timestamp_list.pop_min_ts(expected_ts);
6611 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006612 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006613 buffer->nTimeStamp, expected_ts);
6614
6615 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006616 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006617 }
6618 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306619 }
Arun Menon906de572013-06-18 17:01:40 -07006620 } else {
Arun Menon906de572013-06-18 17:01:40 -07006621 time_stamp_dts.remove_time_stamp(
6622 buffer->nTimeStamp,
6623 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306624 }
Arun Menon906de572013-06-18 17:01:40 -07006625
6626
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006627 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006628
Arun Menon906de572013-06-18 17:01:40 -07006629 if (m_cb.FillBufferDone) {
6630 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006631 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006632 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006633 else
6634 set_frame_rate(buffer->nTimeStamp);
6635
Arun Menon906de572013-06-18 17:01:40 -07006636 if (perf_flag) {
6637 if (!proc_frms) {
6638 dec_time.stop();
6639 latency = dec_time.processing_time_us() - latency;
6640 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6641 dec_time.start();
6642 fps_metrics.start();
6643 }
6644 proc_frms++;
6645 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6646 OMX_U64 proc_time = 0;
6647 fps_metrics.stop();
6648 proc_time = fps_metrics.processing_time_us();
6649 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006650 proc_frms, (float)proc_time / 1e6,
6651 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006652 proc_frms = 0;
6653 }
6654 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006655
6656#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006657 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006658
Arun Menon906de572013-06-18 17:01:40 -07006659 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6660 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6661 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6662 buffer->nFilledLen + 3)&(~3));
6663 while (p_extra &&
6664 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006665 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006666 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6667 if (p_extra->eType == OMX_ExtraDataNone) {
6668 break;
6669 }
6670 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6671 }
6672 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006673#endif
Arun Menon906de572013-06-18 17:01:40 -07006674 }
6675 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6676 prev_ts = LLONG_MAX;
6677 rst_prev_ts = true;
6678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006679
Arun Menon906de572013-06-18 17:01:40 -07006680 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6681 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6682 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006683 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006684 OMX_BUFFERHEADERTYPE *il_buffer;
6685 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006686
vivek mehta79cff222014-01-22 12:17:07 -08006687 if (il_buffer && m_last_rendered_TS >= 0) {
6688 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306689 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006690
6691 // Current frame can be send for rendering if
6692 // (a) current FPS is <= 60
6693 // (b) is the next frame after the frame with TS 0
6694 // (c) is the first frame after seek
6695 // (d) the delta TS b\w two consecutive frames is > 16 ms
6696 // (e) its TS is equal to previous frame TS
6697 // (f) if marked EOS
6698
6699 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6700 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6701 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006702 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006703 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006704 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006705 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006706 }
6707
6708 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6709 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6710 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006711 }
6712
vivek mehta79cff222014-01-22 12:17:07 -08006713 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006714 log_output_buffers(il_buffer);
6715 if (dynamic_buf_mode) {
6716 unsigned int nPortIndex = 0;
6717 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6718
6719 if (!secure_mode) {
6720 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6721 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6722 }
6723
6724 //Clear graphic buffer handles in dynamic mode
6725 native_buffer[nPortIndex].privatehandle = NULL;
6726 native_buffer[nPortIndex].nativehandle = NULL;
6727 }
Arun Menon906de572013-06-18 17:01:40 -07006728 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006729 } else {
Arun Menon906de572013-06-18 17:01:40 -07006730 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6731 return OMX_ErrorBadParameter;
6732 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006733 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006734 } else {
6735 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006736 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006737
Praveen Chavancf924182013-12-06 23:16:23 -08006738#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6739 if (m_smoothstreaming_mode) {
6740 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6741 BufferDim_t dim;
6742 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6743 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6744 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6745 if (private_handle) {
6746 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6747 dim.sliceWidth, dim.sliceHeight);
6748 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6749 }
6750 }
6751#endif
6752
Arun Menon906de572013-06-18 17:01:40 -07006753 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006754}
6755
6756OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006757 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006758{
6759
Surajit Podderd2644d52013-08-28 17:59:06 +05306760 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006761 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006762 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006763 }
6764
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006765 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006766 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006767 pending_input_buffers--;
6768
Arun Menon906de572013-06-18 17:01:40 -07006769 if (arbitrary_bytes) {
6770 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006771 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006772 pdest_frame = buffer;
6773 buffer->nFilledLen = 0;
6774 buffer->nTimeStamp = LLONG_MAX;
6775 push_input_buffer (hComp);
6776 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006777 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006778 buffer->nFilledLen = 0;
6779 if (!m_input_free_q.insert_entry((unsigned)buffer,
6780 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006781 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006782 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006783 }
Arun Menon906de572013-06-18 17:01:40 -07006784 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006785 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006786 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006787 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6788 }
6789 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6790 }
6791 return OMX_ErrorNone;
6792}
6793
Shalaj Jain273b3e02012-06-22 19:08:03 -07006794int omx_vdec::async_message_process (void *context, void* message)
6795{
Arun Menon906de572013-06-18 17:01:40 -07006796 omx_vdec* omx = NULL;
6797 struct vdec_msginfo *vdec_msg = NULL;
6798 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6799 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6800 struct vdec_output_frameinfo *output_respbuf = NULL;
6801 int rc=1;
6802 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006803 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006804 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006805 }
Arun Menon906de572013-06-18 17:01:40 -07006806 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006807
Arun Menon906de572013-06-18 17:01:40 -07006808 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006809
Arun Menon906de572013-06-18 17:01:40 -07006810 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006811
Arun Menon906de572013-06-18 17:01:40 -07006812 case VDEC_MSG_EVT_HW_ERROR:
6813 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6814 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6815 break;
6816
Deepak Verma24720fb2014-01-29 16:57:40 +05306817 case VDEC_MSG_EVT_HW_OVERLOAD:
6818 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6819 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
6820 break;
6821
6822 case VDEC_MSG_EVT_MAX_CLIENTS:
6823 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6824 OMX_COMPONENT_GENERATE_MAX_CLIENTS_ERROR);
6825 break;
6826
Arun Menon906de572013-06-18 17:01:40 -07006827 case VDEC_MSG_RESP_START_DONE:
6828 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6829 OMX_COMPONENT_GENERATE_START_DONE);
6830 break;
6831
6832 case VDEC_MSG_RESP_STOP_DONE:
6833 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6834 OMX_COMPONENT_GENERATE_STOP_DONE);
6835 break;
6836
6837 case VDEC_MSG_RESP_RESUME_DONE:
6838 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6839 OMX_COMPONENT_GENERATE_RESUME_DONE);
6840 break;
6841
6842 case VDEC_MSG_RESP_PAUSE_DONE:
6843 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6844 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6845 break;
6846
6847 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6848 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6849 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6850 break;
6851 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6852 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6853 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6854 break;
6855 case VDEC_MSG_RESP_INPUT_FLUSHED:
6856 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6857
6858 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6859 vdec_msg->msgdata.input_frame_clientdata; */
6860
6861 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6862 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6863 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306864 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006865 omxhdr = NULL;
6866 vdec_msg->status_code = VDEC_S_EFATAL;
6867 }
6868 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6869 DEBUG_PRINT_HIGH("Unsupported input");
6870 omx->omx_report_error ();
6871 }
6872 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6873 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6874 }
6875 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6876 OMX_COMPONENT_GENERATE_EBD);
6877 break;
6878 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6879 int64_t *timestamp;
6880 timestamp = (int64_t *) malloc(sizeof(int64_t));
6881 if (timestamp) {
6882 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6883 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6884 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006885 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006886 vdec_msg->msgdata.output_frame.time_stamp);
6887 }
6888 break;
6889 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6890 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6891
6892 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6893 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6894 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6895 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6896 vdec_msg->msgdata.output_frame.pic_type);
6897
6898 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306899 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006900 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306901 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006902 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6903 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6904 }
Arun Menon906de572013-06-18 17:01:40 -07006905 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6906 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6907 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6908 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6909 omxhdr->nFlags = 0;
6910
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006911 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006912 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6913 //rc = -1;
6914 }
6915 if (omxhdr->nFilledLen) {
6916 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6917 }
6918 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6919 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6920 } else {
6921 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6922 }
6923 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6924 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6925 }
6926 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6927 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6928 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006929 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006930 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006931 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6932 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6933 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006934 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6935 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6936 omxhdr->nOffset);
6937 }
Arun Menon906de572013-06-18 17:01:40 -07006938 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6939 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006940 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006941 omx->time_stamp_dts.remove_time_stamp(
6942 omxhdr->nTimeStamp,
6943 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6944 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006945 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6946 OMX_COMPONENT_GENERATE_FTB);
6947 break;
6948 }
6949 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6950 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6951 }
6952 vdec_msg->msgdata.output_frame.bufferaddr =
6953 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6954 int format_notably_changed = 0;
6955 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306956 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006957 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6958 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006959 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006960 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6961 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6962 format_notably_changed = 1;
6963 }
6964 }
6965 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6966 vdec_msg->msgdata.output_frame.framesize.left)
6967 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6968 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6969 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6970 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6971 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6972 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6973 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006974 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006975 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6976 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6977 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006978 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006979 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6980 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006981 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6982 omx->drv_ctx.video_resolution.frame_width) {
6983 vdec_msg->msgdata.output_frame.framesize.left = 0;
6984 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6985 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6986 }
6987 }
6988 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6989 omx->drv_ctx.video_resolution.frame_height) {
6990 vdec_msg->msgdata.output_frame.framesize.top = 0;
6991 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6992 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6993 }
6994 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006995 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 -07006996 vdec_msg->msgdata.output_frame.framesize.left,
6997 vdec_msg->msgdata.output_frame.framesize.top,
6998 vdec_msg->msgdata.output_frame.framesize.right,
6999 vdec_msg->msgdata.output_frame.framesize.bottom,
7000 omx->drv_ctx.video_resolution.frame_width,
7001 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07007002 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
7003 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
7004 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
7005 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
7006 format_notably_changed = 1;
7007 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007008 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07007009 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
7010 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007011 if (format_notably_changed) {
7012 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05307013 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07007014 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7015 } else {
7016 if (!omx->client_buffers.update_buffer_req()) {
7017 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7018 }
7019 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
7020 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7021 }
7022 }
7023 if (omxhdr->nFilledLen)
7024 omx->prev_n_filled_len = omxhdr->nFilledLen;
7025
7026 output_respbuf = (struct vdec_output_frameinfo *)\
7027 omxhdr->pOutputPortPrivate;
7028 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7029 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
7030 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7031 output_respbuf->pic_type = PICTURE_TYPE_I;
7032 }
7033 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7034 output_respbuf->pic_type = PICTURE_TYPE_P;
7035 }
7036 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7037 output_respbuf->pic_type = PICTURE_TYPE_B;
7038 }
7039
7040 if (omx->output_use_buffer)
7041 memcpy ( omxhdr->pBuffer, (void *)
7042 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7043 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7044 vdec_msg->msgdata.output_frame.len);
7045 } else
7046 omxhdr->nFilledLen = 0;
7047 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7048 OMX_COMPONENT_GENERATE_FBD);
7049 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
7050 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7051 OMX_COMPONENT_GENERATE_EOS_DONE);
7052 else
7053 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7054 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7055 break;
7056 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007057 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007058 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7059 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7060 break;
7061 default:
7062 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063 }
Arun Menon906de572013-06-18 17:01:40 -07007064 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007065}
7066
7067OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007068 OMX_HANDLETYPE hComp,
7069 OMX_BUFFERHEADERTYPE *buffer
7070 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007071{
Arun Menon906de572013-06-18 17:01:40 -07007072 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007073 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007074
Arun Menon906de572013-06-18 17:01:40 -07007075 if (buffer == NULL) {
7076 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007077 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007078 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7079 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007080 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7081
7082 /* return zero length and not an EOS buffer */
7083 /* return buffer if input flush in progress */
7084 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7085 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007086 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007087 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7088 return OMX_ErrorNone;
7089 }
7090
7091 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007092 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007093 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007094 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007095 push_input_buffer (hComp);
7096 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007097 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007098 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7099 (unsigned)NULL)) {
7100 return OMX_ErrorBadParameter;
7101 }
7102 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007103
7104
Arun Menon906de572013-06-18 17:01:40 -07007105 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007106}
7107
7108OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7109{
Arun Menon906de572013-06-18 17:01:40 -07007110 unsigned address,p2,id;
7111 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007112
Arun Menon906de572013-06-18 17:01:40 -07007113 if (pdest_frame == NULL || psource_frame == NULL) {
7114 /*Check if we have a destination buffer*/
7115 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007116 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007117 if (m_input_free_q.m_size) {
7118 m_input_free_q.pop_entry(&address,&p2,&id);
7119 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7120 pdest_frame->nFilledLen = 0;
7121 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007122 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007123 }
7124 }
7125
7126 /*Check if we have a destination buffer*/
7127 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007128 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007129 if (m_input_pending_q.m_size) {
7130 m_input_pending_q.pop_entry(&address,&p2,&id);
7131 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007132 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007133 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007134 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007135 psource_frame->nFlags,psource_frame->nFilledLen);
7136
7137 }
7138 }
7139
Shalaj Jain273b3e02012-06-22 19:08:03 -07007140 }
7141
Arun Menon906de572013-06-18 17:01:40 -07007142 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7143 switch (codec_type_parse) {
7144 case CODEC_TYPE_MPEG4:
7145 case CODEC_TYPE_H263:
7146 case CODEC_TYPE_MPEG2:
7147 ret = push_input_sc_codec(hComp);
7148 break;
7149 case CODEC_TYPE_H264:
7150 ret = push_input_h264(hComp);
7151 break;
7152 case CODEC_TYPE_VC1:
7153 ret = push_input_vc1(hComp);
7154 break;
7155 default:
7156 break;
7157 }
7158 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007159 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007160 omx_report_error ();
7161 break;
7162 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007163 }
7164
Arun Menon906de572013-06-18 17:01:40 -07007165 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007166}
7167
7168OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7169{
Arun Menon906de572013-06-18 17:01:40 -07007170 OMX_U32 partial_frame = 1;
7171 OMX_BOOL generate_ebd = OMX_TRUE;
7172 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007173
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007174 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007175 psource_frame,psource_frame->nTimeStamp);
7176 if (m_frame_parser.parse_sc_frame(psource_frame,
7177 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007178 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007179 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007180 }
Arun Menon906de572013-06-18 17:01:40 -07007181
7182 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007183 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007184 pdest_frame->nFilledLen,psource_frame,frame_count);
7185
7186
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007187 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007188 /*First Parsed buffer will have only header Hence skip*/
7189 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007190 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007191
7192 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7193 codec_type_parse == CODEC_TYPE_DIVX) {
7194 mp4StreamType psBits;
7195 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7196 psBits.numBytes = pdest_frame->nFilledLen;
7197 mp4_headerparser.parseHeader(&psBits);
7198 }
7199
7200 frame_count++;
7201 } else {
7202 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7203 if (pdest_frame->nFilledLen) {
7204 /*Push the frame to the Decoder*/
7205 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7206 return OMX_ErrorBadParameter;
7207 }
7208 frame_count++;
7209 pdest_frame = NULL;
7210
7211 if (m_input_free_q.m_size) {
7212 m_input_free_q.pop_entry(&address,&p2,&id);
7213 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7214 pdest_frame->nFilledLen = 0;
7215 }
7216 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007217 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007218 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7219 (unsigned)NULL);
7220 pdest_frame = NULL;
7221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007222 }
Arun Menon906de572013-06-18 17:01:40 -07007223 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007224 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007225 /*Check if Destination Buffer is full*/
7226 if (pdest_frame->nAllocLen ==
7227 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007228 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007229 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007230 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007231 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007232
Arun Menon906de572013-06-18 17:01:40 -07007233 if (psource_frame->nFilledLen == 0) {
7234 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7235 if (pdest_frame) {
7236 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007237 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007238 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007240 pdest_frame->nFilledLen,frame_count++);
7241 /*Push the frame to the Decoder*/
7242 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7243 return OMX_ErrorBadParameter;
7244 }
7245 frame_count++;
7246 pdest_frame = NULL;
7247 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007248 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007249 generate_ebd = OMX_FALSE;
7250 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007251 }
Arun Menon906de572013-06-18 17:01:40 -07007252 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007253 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007254 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7255 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007256
Arun Menon906de572013-06-18 17:01:40 -07007257 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007258 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007259 m_input_pending_q.pop_entry(&address,&p2,&id);
7260 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007261 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007262 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007263 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007264 psource_frame->nFlags,psource_frame->nFilledLen);
7265 }
7266 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007267 }
Arun Menon906de572013-06-18 17:01:40 -07007268 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007269}
7270
7271OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7272{
Arun Menon906de572013-06-18 17:01:40 -07007273 OMX_U32 partial_frame = 1;
7274 unsigned address = 0, p2 = 0, id = 0;
7275 OMX_BOOL isNewFrame = OMX_FALSE;
7276 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007277
Arun Menon906de572013-06-18 17:01:40 -07007278 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007279 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007280 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007281 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007282 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007283 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007284 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007285 if (h264_scratch.nFilledLen && look_ahead_nal) {
7286 look_ahead_nal = false;
7287 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7288 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007289 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7290 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7291 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007292 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007293 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007294 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007295 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007296 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007297 }
Arun Menon906de572013-06-18 17:01:40 -07007298 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007299
7300 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7301 in EOS flag getting associated with the destination
7302 */
7303 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7304 pdest_frame->nFilledLen) {
7305 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7306 generate_ebd = OMX_FALSE;
7307 }
7308
Arun Menon906de572013-06-18 17:01:40 -07007309 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007310 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007311 if (m_frame_parser.parse_sc_frame(psource_frame,
7312 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007313 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007314 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007315 }
Arun Menon906de572013-06-18 17:01:40 -07007316 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007317 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007318 if (m_frame_parser.parse_h264_nallength(psource_frame,
7319 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007320 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007321 return OMX_ErrorBadParameter;
7322 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007323 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007324
Arun Menon906de572013-06-18 17:01:40 -07007325 if (partial_frame == 0) {
7326 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007327 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007328 nal_count++;
7329 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7330 h264_scratch.nFlags = psource_frame->nFlags;
7331 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007332 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007333 if (h264_scratch.nFilledLen) {
7334 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7335 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007336#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007337 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7338 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7339 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7340 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7341 // If timeinfo is present frame info from SEI is already processed
7342 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7343 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007344#endif
Arun Menon906de572013-06-18 17:01:40 -07007345 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7346 nal_count++;
7347 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7348 pdest_frame->nTimeStamp = h264_last_au_ts;
7349 pdest_frame->nFlags = h264_last_au_flags;
7350#ifdef PANSCAN_HDLR
7351 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7352 h264_parser->update_panscan_data(h264_last_au_ts);
7353#endif
7354 }
7355 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7356 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7357 h264_last_au_ts = h264_scratch.nTimeStamp;
7358 h264_last_au_flags = h264_scratch.nFlags;
7359#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7360 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7361 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7362 if (!VALID_TS(h264_last_au_ts))
7363 h264_last_au_ts = ts_in_sei;
7364 }
7365#endif
7366 } else
7367 h264_last_au_ts = LLONG_MAX;
7368 }
7369
7370 if (!isNewFrame) {
7371 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7372 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007373 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007374 h264_scratch.nFilledLen);
7375 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7376 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7377 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7378 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7379 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7380 h264_scratch.nFilledLen = 0;
7381 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007382 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007383 return OMX_ErrorBadParameter;
7384 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007385 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007386 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007387 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007388 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007389 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007390 pdest_frame->nFilledLen,frame_count++);
7391
7392 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007393 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007394 look_ahead_nal = false;
7395 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7396 h264_scratch.nFilledLen) {
7397 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7398 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7399 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7400 h264_scratch.nFilledLen = 0;
7401 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007402 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007403 return OMX_ErrorBadParameter;
7404 }
7405 } else {
7406 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007407 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007408 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7409 }
7410 /*Push the frame to the Decoder*/
7411 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7412 return OMX_ErrorBadParameter;
7413 }
7414 //frame_count++;
7415 pdest_frame = NULL;
7416 if (m_input_free_q.m_size) {
7417 m_input_free_q.pop_entry(&address,&p2,&id);
7418 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007419 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007420 pdest_frame->nFilledLen = 0;
7421 pdest_frame->nFlags = 0;
7422 pdest_frame->nTimeStamp = LLONG_MAX;
7423 }
7424 }
7425 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007426 }
Arun Menon906de572013-06-18 17:01:40 -07007427 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007428 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007429 /*Check if Destination Buffer is full*/
7430 if (h264_scratch.nAllocLen ==
7431 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007432 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007433 return OMX_ErrorStreamCorrupt;
7434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007435 }
Arun Menon906de572013-06-18 17:01:40 -07007436
7437 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007438 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007439
7440 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7441 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007442 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007443 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7444 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007445 if(pdest_frame->nFilledLen == 0) {
7446 /* No residual frame from before, send whatever
7447 * we have left */
7448 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7449 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7450 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7451 h264_scratch.nFilledLen = 0;
7452 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7453 } else {
7454 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7455 if(!isNewFrame) {
7456 /* Have a residual frame, but we know that the
7457 * AU in this frame is belonging to whatever
7458 * frame we had left over. So append it */
7459 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7460 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7461 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7462 h264_scratch.nFilledLen = 0;
7463 pdest_frame->nTimeStamp = h264_last_au_ts;
7464 } else {
7465 /* Completely new frame, let's just push what
7466 * we have now. The resulting EBD would trigger
7467 * another push */
7468 generate_ebd = OMX_FALSE;
7469 pdest_frame->nTimeStamp = h264_last_au_ts;
7470 h264_last_au_ts = h264_scratch.nTimeStamp;
7471 }
7472 }
Arun Menon906de572013-06-18 17:01:40 -07007473 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007474 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007475 return OMX_ErrorBadParameter;
7476 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007477
7478 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7479 if(generate_ebd == OMX_TRUE) {
7480 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7481 }
Arun Menon906de572013-06-18 17:01:40 -07007482
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007483 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007484 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007485 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007486#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7487 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7488 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7489 if (!VALID_TS(pdest_frame->nTimeStamp))
7490 pdest_frame->nTimeStamp = ts_in_sei;
7491 }
7492#endif
7493 /*Push the frame to the Decoder*/
7494 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7495 return OMX_ErrorBadParameter;
7496 }
7497 frame_count++;
7498 pdest_frame = NULL;
7499 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007500 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007501 pdest_frame,h264_scratch.nFilledLen);
7502 generate_ebd = OMX_FALSE;
7503 }
7504 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007505 }
Arun Menon906de572013-06-18 17:01:40 -07007506 if (generate_ebd && !psource_frame->nFilledLen) {
7507 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7508 psource_frame = NULL;
7509 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007510 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007511 m_input_pending_q.pop_entry(&address,&p2,&id);
7512 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007513 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007514 psource_frame->nFlags,psource_frame->nFilledLen);
7515 }
7516 }
7517 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518}
7519
7520OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7521{
7522 OMX_U8 *buf, *pdest;
7523 OMX_U32 partial_frame = 1;
7524 OMX_U32 buf_len, dest_len;
7525
Arun Menon906de572013-06-18 17:01:40 -07007526 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007527 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007528 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007529 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007530 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007531 buf = psource_frame->pBuffer;
7532 buf_len = psource_frame->nFilledLen;
7533
7534 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007535 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007536 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007537 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007538 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007539 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007540 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007541 return OMX_ErrorStreamCorrupt;
7542 }
Arun Menon906de572013-06-18 17:01:40 -07007543 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7545 pdest_frame->nOffset;
7546 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007547 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007548
Arun Menon906de572013-06-18 17:01:40 -07007549 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007550 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007551 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007552 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007553 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7554 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7555 }
7556 }
7557 }
7558
Arun Menon906de572013-06-18 17:01:40 -07007559 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007560 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007561 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007562 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007563 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007564 return OMX_ErrorBadParameter;
7565 }
Arun Menon906de572013-06-18 17:01:40 -07007566 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007567
7568 case VC1_SP_MP_RCV:
7569 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007570 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007571 return OMX_ErrorBadParameter;
7572 }
7573 return OMX_ErrorNone;
7574}
7575
David Ng38e2d232013-03-15 20:05:58 -07007576#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007577bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007578 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007579{
Arun Menon906de572013-06-18 17:01:40 -07007580 struct pmem_allocation allocation;
7581 allocation.size = buffer_size;
7582 allocation.align = clip2(alignment);
7583 if (allocation.align < 4096) {
7584 allocation.align = 4096;
7585 }
7586 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007587 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007588 allocation.align, allocation.size);
7589 return false;
7590 }
7591 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007592}
David Ng38e2d232013-03-15 20:05:58 -07007593#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007594#ifdef USE_ION
7595int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007596 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7597 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007598{
Arun Menon906de572013-06-18 17:01:40 -07007599 int fd = -EINVAL;
7600 int rc = -EINVAL;
7601 int ion_dev_flag;
7602 struct vdec_ion ion_buf_info;
7603 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007604 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007605 return -EINVAL;
7606 }
7607 ion_dev_flag = O_RDONLY;
7608 fd = open (MEM_DEVICE, ion_dev_flag);
7609 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007610 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007611 return fd;
7612 }
7613 alloc_data->flags = 0;
7614 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7615 alloc_data->flags |= ION_FLAG_CACHED;
7616 }
7617 alloc_data->len = buffer_size;
7618 alloc_data->align = clip2(alignment);
7619 if (alloc_data->align < 4096) {
7620 alloc_data->align = 4096;
7621 }
7622 if ((secure_mode) && (flag & ION_SECURE))
7623 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007624
Arun Menon906de572013-06-18 17:01:40 -07007625 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307626 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007627 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7628 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7629 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007630 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007631 alloc_data->handle = NULL;
7632 close(fd);
7633 fd = -ENOMEM;
7634 return fd;
7635 }
7636 fd_data->handle = alloc_data->handle;
7637 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7638 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007639 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007640 ion_buf_info.ion_alloc_data = *alloc_data;
7641 ion_buf_info.ion_device_fd = fd;
7642 ion_buf_info.fd_ion_data = *fd_data;
7643 free_ion_memory(&ion_buf_info);
7644 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007645 fd = -ENOMEM;
7646 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007647
Arun Menon906de572013-06-18 17:01:40 -07007648 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649}
7650
Arun Menon906de572013-06-18 17:01:40 -07007651void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7652{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007653
Arun Menon906de572013-06-18 17:01:40 -07007654 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007655 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007656 return;
7657 }
7658 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7659 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007660 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007661 }
7662 close(buf_ion_info->ion_device_fd);
7663 buf_ion_info->ion_device_fd = -1;
7664 buf_ion_info->ion_alloc_data.handle = NULL;
7665 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007666}
7667#endif
7668void omx_vdec::free_output_buffer_header()
7669{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007670 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007671 output_use_buffer = false;
7672 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007673
Arun Menon906de572013-06-18 17:01:40 -07007674 if (m_out_mem_ptr) {
7675 free (m_out_mem_ptr);
7676 m_out_mem_ptr = NULL;
7677 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007678
Arun Menon906de572013-06-18 17:01:40 -07007679 if (m_platform_list) {
7680 free(m_platform_list);
7681 m_platform_list = NULL;
7682 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007683
Arun Menon906de572013-06-18 17:01:40 -07007684 if (drv_ctx.ptr_respbuffer) {
7685 free (drv_ctx.ptr_respbuffer);
7686 drv_ctx.ptr_respbuffer = NULL;
7687 }
7688 if (drv_ctx.ptr_outputbuffer) {
7689 free (drv_ctx.ptr_outputbuffer);
7690 drv_ctx.ptr_outputbuffer = NULL;
7691 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007692#ifdef USE_ION
7693 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007694 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007695 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007696 drv_ctx.op_buf_ion_info = NULL;
7697 }
7698#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007699 if (out_dynamic_list) {
7700 free(out_dynamic_list);
7701 out_dynamic_list = NULL;
7702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007703}
7704
7705void omx_vdec::free_input_buffer_header()
7706{
7707 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007708 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007709 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007710 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007711 free (m_inp_heap_ptr);
7712 m_inp_heap_ptr = NULL;
7713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007714
Arun Menon906de572013-06-18 17:01:40 -07007715 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007716 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007717 free (m_phdr_pmem_ptr);
7718 m_phdr_pmem_ptr = NULL;
7719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007720 }
Arun Menon906de572013-06-18 17:01:40 -07007721 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007722 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007723 free (m_inp_mem_ptr);
7724 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007725 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007726 /* We just freed all the buffer headers, every thing in m_input_free_q,
7727 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007728 while (m_input_free_q.m_size) {
7729 unsigned address, p2, id;
7730 m_input_free_q.pop_entry(&address, &p2, &id);
7731 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007732 while (m_input_pending_q.m_size) {
7733 unsigned address, p2, id;
7734 m_input_pending_q.pop_entry(&address, &p2, &id);
7735 }
7736 pdest_frame = NULL;
7737 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007738 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007739 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007740 free (drv_ctx.ptr_inputbuffer);
7741 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007742 }
7743#ifdef USE_ION
7744 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007745 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007746 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007747 drv_ctx.ip_buf_ion_info = NULL;
7748 }
7749#endif
7750}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007751
7752int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007753{
Arun Menon906de572013-06-18 17:01:40 -07007754 enum v4l2_buf_type btype;
7755 int rc = 0;
7756 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007757
Arun Menon906de572013-06-18 17:01:40 -07007758 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7759 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7760 v4l2_port = OUTPUT_PORT;
7761 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7762 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7763 v4l2_port = CAPTURE_PORT;
7764 } else if (port == OMX_ALL) {
7765 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7766 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007767
Arun Menon906de572013-06-18 17:01:40 -07007768 if (!rc_input)
7769 return rc_input;
7770 else
7771 return rc_output;
7772 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007773
Arun Menon906de572013-06-18 17:01:40 -07007774 if (!streaming[v4l2_port]) {
7775 // already streamed off, warn and move on
7776 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7777 " which is already streamed off", v4l2_port);
7778 return 0;
7779 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007780
Arun Menon906de572013-06-18 17:01:40 -07007781 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007782
Arun Menon906de572013-06-18 17:01:40 -07007783 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7784 if (rc) {
7785 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007786 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007787 } else {
7788 streaming[v4l2_port] = false;
7789 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007790
Arun Menon906de572013-06-18 17:01:40 -07007791 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007792}
7793
7794OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7795{
Arun Menon906de572013-06-18 17:01:40 -07007796 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7797 struct v4l2_requestbuffers bufreq;
7798 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307799 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007800 struct v4l2_format fmt;
7801 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007802 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007803 buffer_prop->actualcount, buffer_prop->buffer_size);
7804 bufreq.memory = V4L2_MEMORY_USERPTR;
7805 bufreq.count = 1;
7806 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7807 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7808 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7809 fmt.fmt.pix_mp.pixelformat = output_capability;
7810 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7811 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7812 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7813 fmt.fmt.pix_mp.pixelformat = capture_capability;
7814 } else {
7815 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007816 }
Arun Menon906de572013-06-18 17:01:40 -07007817 if (eRet==OMX_ErrorNone) {
7818 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007819 }
Arun Menon906de572013-06-18 17:01:40 -07007820 if (ret) {
7821 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7822 /*TODO: How to handle this case */
7823 eRet = OMX_ErrorInsufficientResources;
7824 return eRet;
7825 } else {
7826 buffer_prop->actualcount = bufreq.count;
7827 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007828 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007829 }
Arun Menon906de572013-06-18 17:01:40 -07007830 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7831 buffer_prop->actualcount, buffer_prop->buffer_size);
7832
7833 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7834 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7835
7836 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7837
7838 update_resolution(fmt.fmt.pix_mp.width,
7839 fmt.fmt.pix_mp.height,
7840 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7841 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7842 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7843 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007844 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007845
7846 if (ret) {
7847 /*TODO: How to handle this case */
7848 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7849 eRet = OMX_ErrorInsufficientResources;
7850 } else {
7851 int extra_idx = 0;
7852
7853 eRet = is_video_session_supported();
7854 if (eRet)
7855 return eRet;
7856
7857 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7858 buf_size = buffer_prop->buffer_size;
7859 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7860 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7861 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7862 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007863 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007864 return OMX_ErrorBadParameter;
7865 }
7866 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7867 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7868 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7869 }
7870 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7871 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7872 }
7873 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7874 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007875 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007876 client_extra_data_size);
7877 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307878 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7879 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7880 DEBUG_PRINT_HIGH("framepack extradata enabled");
7881 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007882 if (client_extradata & OMX_QP_EXTRADATA) {
7883 client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
7884 DEBUG_PRINT_HIGH("QP extradata enabled");
7885 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08007886 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
7887 client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
7888 DEBUG_PRINT_HIGH("Input bits info extradata enabled");
7889 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08007890
Arun Menon906de572013-06-18 17:01:40 -07007891 if (client_extra_data_size) {
7892 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7893 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7894 }
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307895 final_extra_data_size = (extra_data_size > client_extra_data_size ?
7896 extra_data_size : client_extra_data_size);
7897 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007898 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307899 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07007900 buf_size += client_extra_data_size;
7901 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7902 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7903 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7904 if (in_reconfig) // BufReq will be set to driver when port is disabled
7905 buffer_prop->buffer_size = buf_size;
7906 else if (buf_size != buffer_prop->buffer_size) {
7907 buffer_prop->buffer_size = buf_size;
7908 eRet = set_buffer_req(buffer_prop);
7909 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007910 }
Arun Menon906de572013-06-18 17:01:40 -07007911 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7912 buffer_prop->actualcount, buffer_prop->buffer_size);
7913 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007914}
7915
7916OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7917{
Arun Menon906de572013-06-18 17:01:40 -07007918 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7919 unsigned buf_size = 0;
7920 struct v4l2_format fmt;
7921 struct v4l2_requestbuffers bufreq;
7922 int ret;
7923 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7924 buffer_prop->actualcount, buffer_prop->buffer_size);
7925 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7926 if (buf_size != buffer_prop->buffer_size) {
7927 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7928 buffer_prop->buffer_size, buf_size);
7929 eRet = OMX_ErrorBadParameter;
7930 } else {
7931 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7932 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007933
Arun Menon906de572013-06-18 17:01:40 -07007934 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7935 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7936 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007937 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007938 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7939 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7940 fmt.fmt.pix_mp.pixelformat = capture_capability;
7941 } else {
7942 eRet = OMX_ErrorBadParameter;
7943 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007944
Arun Menon906de572013-06-18 17:01:40 -07007945 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7946 if (ret) {
7947 /*TODO: How to handle this case */
7948 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7949 eRet = OMX_ErrorInsufficientResources;
7950 }
7951
7952 bufreq.memory = V4L2_MEMORY_USERPTR;
7953 bufreq.count = buffer_prop->actualcount;
7954 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7955 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7956 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7957 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7958 } else {
7959 eRet = OMX_ErrorBadParameter;
7960 }
7961
7962 if (eRet==OMX_ErrorNone) {
7963 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7964 }
7965
7966 if (ret) {
7967 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7968 /*TODO: How to handle this case */
7969 eRet = OMX_ErrorInsufficientResources;
7970 } else if (bufreq.count < buffer_prop->actualcount) {
7971 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7972 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7973 buffer_prop->actualcount, bufreq.count);
7974 eRet = OMX_ErrorInsufficientResources;
7975 } else {
7976 if (!client_buffers.update_buffer_req()) {
7977 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7978 eRet = OMX_ErrorInsufficientResources;
7979 }
7980 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007981 }
Arun Menon906de572013-06-18 17:01:40 -07007982 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007983}
7984
Shalaj Jain273b3e02012-06-22 19:08:03 -07007985OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7986{
Arun Menon906de572013-06-18 17:01:40 -07007987 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7988 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007989}
7990
7991OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7992{
Arun Menon906de572013-06-18 17:01:40 -07007993 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7994 if (!portDefn) {
7995 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007996 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007997 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007998 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7999 portDefn->nSize = sizeof(portDefn);
8000 portDefn->eDomain = OMX_PortDomainVideo;
8001 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008002 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8003 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008004 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008005 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008006 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008007 }
Arun Menon906de572013-06-18 17:01:40 -07008008 if (0 == portDefn->nPortIndex) {
8009 portDefn->eDir = OMX_DirInput;
8010 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8011 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8012 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8013 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8014 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8015 portDefn->bEnabled = m_inp_bEnabled;
8016 portDefn->bPopulated = m_inp_bPopulated;
8017 } else if (1 == portDefn->nPortIndex) {
8018 unsigned int buf_size = 0;
8019 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008020 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008021 return OMX_ErrorHardware;
8022 }
8023 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008024 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008025 return OMX_ErrorHardware;
8026 }
8027 portDefn->nBufferSize = buf_size;
8028 portDefn->eDir = OMX_DirOutput;
8029 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8030 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8031 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8032 portDefn->bEnabled = m_out_bEnabled;
8033 portDefn->bPopulated = m_out_bPopulated;
8034 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008035 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008036 return OMX_ErrorHardware;
8037 }
8038 } else {
8039 portDefn->eDir = OMX_DirMax;
8040 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8041 (int)portDefn->nPortIndex);
8042 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008043 }
Arun Menon906de572013-06-18 17:01:40 -07008044 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8045 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8046 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8047 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praveen Chavandb7776f2014-02-06 18:17:25 -08008048 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8049 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308050 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8051 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8052 }
8053 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8054 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8055 portDefn->nPortIndex,
8056 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008057 portDefn->format.video.nFrameHeight,
8058 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308059 portDefn->format.video.nSliceHeight,
8060 portDefn->format.video.eColorFormat,
8061 portDefn->nBufferSize,
8062 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008063
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308064 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008065}
8066
8067OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8068{
Arun Menon906de572013-06-18 17:01:40 -07008069 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8070 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8071 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008072
Arun Menon906de572013-06-18 17:01:40 -07008073 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008074 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008075 int nBufHdrSize = 0;
8076 int nPlatformEntrySize = 0;
8077 int nPlatformListSize = 0;
8078 int nPMEMInfoSize = 0;
8079 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8080 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8081 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008082
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008083 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008084 drv_ctx.op_buf.actualcount);
8085 nBufHdrSize = drv_ctx.op_buf.actualcount *
8086 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008087
Arun Menon906de572013-06-18 17:01:40 -07008088 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8089 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8090 nPlatformListSize = drv_ctx.op_buf.actualcount *
8091 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8092 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8093 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008094
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008095 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008096 sizeof(OMX_BUFFERHEADERTYPE),
8097 nPMEMInfoSize,
8098 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008099 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008100 m_out_bm_count);
8101 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8102 // Alloc mem for platform specific info
8103 char *pPtr=NULL;
8104 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8105 nPMEMInfoSize,1);
8106 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8107 calloc (sizeof(struct vdec_bufferpayload),
8108 drv_ctx.op_buf.actualcount);
8109 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8110 calloc (sizeof (struct vdec_output_frameinfo),
8111 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008112#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008113 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8114 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008115#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008116 if (dynamic_buf_mode) {
8117 out_dynamic_list = (struct dynamic_buf_list *) \
8118 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8119 }
Arun Menon906de572013-06-18 17:01:40 -07008120 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8121 && drv_ctx.ptr_respbuffer) {
8122 bufHdr = m_out_mem_ptr;
8123 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8124 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8125 (((char *) m_platform_list) + nPlatformListSize);
8126 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8127 (((char *) m_platform_entry) + nPlatformEntrySize);
8128 pPlatformList = m_platform_list;
8129 pPlatformEntry = m_platform_entry;
8130 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008131
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008132 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008133
Arun Menon906de572013-06-18 17:01:40 -07008134 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008135 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008136 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008137 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008138 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8139 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8140 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8141 // Set the values when we determine the right HxW param
8142 bufHdr->nAllocLen = 0;
8143 bufHdr->nFilledLen = 0;
8144 bufHdr->pAppPrivate = NULL;
8145 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8146 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8147 pPlatformEntry->entry = pPMEMInfo;
8148 // Initialize the Platform List
8149 pPlatformList->nEntries = 1;
8150 pPlatformList->entryList = pPlatformEntry;
8151 // Keep pBuffer NULL till vdec is opened
8152 bufHdr->pBuffer = NULL;
8153 pPMEMInfo->offset = 0;
8154 pPMEMInfo->pmem_fd = 0;
8155 bufHdr->pPlatformPrivate = pPlatformList;
8156 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008157#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008158 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008159#endif
Arun Menon906de572013-06-18 17:01:40 -07008160 /*Create a mapping between buffers*/
8161 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8162 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8163 &drv_ctx.ptr_outputbuffer[i];
8164 // Move the buffer and buffer header pointers
8165 bufHdr++;
8166 pPMEMInfo++;
8167 pPlatformEntry++;
8168 pPlatformList++;
8169 }
8170 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008171 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008172 m_out_mem_ptr, pPtr);
8173 if (m_out_mem_ptr) {
8174 free(m_out_mem_ptr);
8175 m_out_mem_ptr = NULL;
8176 }
8177 if (pPtr) {
8178 free(pPtr);
8179 pPtr = NULL;
8180 }
8181 if (drv_ctx.ptr_outputbuffer) {
8182 free(drv_ctx.ptr_outputbuffer);
8183 drv_ctx.ptr_outputbuffer = NULL;
8184 }
8185 if (drv_ctx.ptr_respbuffer) {
8186 free(drv_ctx.ptr_respbuffer);
8187 drv_ctx.ptr_respbuffer = NULL;
8188 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008189#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008190 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008191 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008192 free(drv_ctx.op_buf_ion_info);
8193 drv_ctx.op_buf_ion_info = NULL;
8194 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008195#endif
Arun Menon906de572013-06-18 17:01:40 -07008196 eRet = OMX_ErrorInsufficientResources;
8197 }
8198 } else {
8199 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008200 }
Arun Menon906de572013-06-18 17:01:40 -07008201 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008202}
8203
8204void omx_vdec::complete_pending_buffer_done_cbs()
8205{
Arun Menon906de572013-06-18 17:01:40 -07008206 unsigned p1;
8207 unsigned p2;
8208 unsigned ident;
8209 omx_cmd_queue tmp_q, pending_bd_q;
8210 pthread_mutex_lock(&m_lock);
8211 // pop all pending GENERATE FDB from ftb queue
8212 while (m_ftb_q.m_size) {
8213 m_ftb_q.pop_entry(&p1,&p2,&ident);
8214 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8215 pending_bd_q.insert_entry(p1,p2,ident);
8216 } else {
8217 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008218 }
Arun Menon906de572013-06-18 17:01:40 -07008219 }
8220 //return all non GENERATE FDB to ftb queue
8221 while (tmp_q.m_size) {
8222 tmp_q.pop_entry(&p1,&p2,&ident);
8223 m_ftb_q.insert_entry(p1,p2,ident);
8224 }
8225 // pop all pending GENERATE EDB from etb queue
8226 while (m_etb_q.m_size) {
8227 m_etb_q.pop_entry(&p1,&p2,&ident);
8228 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8229 pending_bd_q.insert_entry(p1,p2,ident);
8230 } else {
8231 tmp_q.insert_entry(p1,p2,ident);
8232 }
8233 }
8234 //return all non GENERATE FDB to etb queue
8235 while (tmp_q.m_size) {
8236 tmp_q.pop_entry(&p1,&p2,&ident);
8237 m_etb_q.insert_entry(p1,p2,ident);
8238 }
8239 pthread_mutex_unlock(&m_lock);
8240 // process all pending buffer dones
8241 while (pending_bd_q.m_size) {
8242 pending_bd_q.pop_entry(&p1,&p2,&ident);
8243 switch (ident) {
8244 case OMX_COMPONENT_GENERATE_EBD:
8245 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008246 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008247 omx_report_error ();
8248 }
8249 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008250
Arun Menon906de572013-06-18 17:01:40 -07008251 case OMX_COMPONENT_GENERATE_FBD:
8252 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008253 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008254 omx_report_error ();
8255 }
8256 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008257 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008258 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008259}
8260
8261void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8262{
Arun Menon906de572013-06-18 17:01:40 -07008263 OMX_U32 new_frame_interval = 0;
8264 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8265 && llabs(act_timestamp - prev_ts) > 2000) {
8266 new_frame_interval = client_set_fps ? frm_int :
8267 llabs(act_timestamp - prev_ts);
8268 if (new_frame_interval < frm_int || frm_int == 0) {
8269 frm_int = new_frame_interval;
8270 if (frm_int) {
8271 drv_ctx.frame_rate.fps_numerator = 1e6;
8272 drv_ctx.frame_rate.fps_denominator = frm_int;
8273 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8274 frm_int, drv_ctx.frame_rate.fps_numerator /
8275 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008276
Arun Menon906de572013-06-18 17:01:40 -07008277 /* We need to report the difference between this FBD and the previous FBD
8278 * back to the driver for clock scaling purposes. */
8279 struct v4l2_outputparm oparm;
8280 /*XXX: we're providing timing info as seconds per frame rather than frames
8281 * per second.*/
8282 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8283 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008284
Arun Menon906de572013-06-18 17:01:40 -07008285 struct v4l2_streamparm sparm;
8286 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8287 sparm.parm.output = oparm;
8288 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8289 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8290 performance might be affected");
8291 }
8292
8293 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008294 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008295 }
Arun Menon906de572013-06-18 17:01:40 -07008296 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008297}
8298
8299void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8300{
Arun Menon906de572013-06-18 17:01:40 -07008301 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8302 prev_ts = act_timestamp;
8303 rst_prev_ts = false;
8304 } else if (VALID_TS(prev_ts)) {
8305 bool codec_cond = (drv_ctx.timestamp_adjust)?
8306 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8307 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8308 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8309 if (frm_int > 0 && codec_cond) {
8310 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8311 act_timestamp = prev_ts + frm_int;
8312 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8313 prev_ts = act_timestamp;
8314 } else
8315 set_frame_rate(act_timestamp);
8316 } else if (frm_int > 0) // In this case the frame rate was set along
8317 { // with the port definition, start ts with 0
8318 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8319 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008320 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008321}
8322
8323void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8324{
Arun Menon906de572013-06-18 17:01:40 -07008325 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8326 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308327 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008328 OMX_U32 frame_rate = 0;
8329 int consumed_len = 0;
8330 OMX_U32 num_MB_in_frame;
8331 OMX_U32 recovery_sei_flags = 1;
8332 int enable = 0;
8333 OMX_U32 mbaff = 0;
8334 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008335 if (buf_index >= drv_ctx.extradata_info.count) {
8336 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8337 buf_index, drv_ctx.extradata_info.count);
8338 return;
8339 }
Arun Menon906de572013-06-18 17:01:40 -07008340 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8341 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8342 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308343
Arun Menon906de572013-06-18 17:01:40 -07008344 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308345 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008346 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008347 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308348 if (!secure_mode)
8349 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008350 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308351 else
8352 p_extra = m_other_extradata;
8353
Arun Menon906de572013-06-18 17:01:40 -07008354 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308355
8356 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008357 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308358 return;
8359 }
Arun Menon906de572013-06-18 17:01:40 -07008360 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8361 if (data) {
8362 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8363 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308364 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008365 DEBUG_PRINT_LOW("Invalid extra data size");
8366 break;
8367 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308368 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008369 switch ((unsigned long)data->eType) {
8370 case EXTRADATA_INTERLACE_VIDEO:
8371 struct msm_vidc_interlace_payload *payload;
8372 payload = (struct msm_vidc_interlace_payload *)data->data;
8373 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8374 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8375 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008376 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8377 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8378 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8379 enable = 1;
8380 } else {
Arun Menon906de572013-06-18 17:01:40 -07008381 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8382 enable = 1;
8383 }
8384 if (m_enable_android_native_buffers)
8385 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8386 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308387 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008388 append_interlace_extradata(p_extra, payload->format);
8389 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8390 }
8391 break;
8392 case EXTRADATA_FRAME_RATE:
8393 struct msm_vidc_framerate_payload *frame_rate_payload;
8394 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8395 frame_rate = frame_rate_payload->frame_rate;
8396 break;
8397 case EXTRADATA_TIMESTAMP:
8398 struct msm_vidc_ts_payload *time_stamp_payload;
8399 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308400 time_stamp = time_stamp_payload->timestamp_lo;
8401 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8402 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008403 break;
8404 case EXTRADATA_NUM_CONCEALED_MB:
8405 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8406 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8407 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8408 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8409 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8410 break;
8411 case EXTRADATA_INDEX:
8412 int *etype;
8413 etype = (int *)(data->data);
8414 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8415 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8416 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8417 if (aspect_ratio_payload) {
8418 ((struct vdec_output_frameinfo *)
8419 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8420 ((struct vdec_output_frameinfo *)
8421 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8422 }
8423 }
8424 break;
8425 case EXTRADATA_RECOVERY_POINT_SEI:
8426 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8427 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8428 recovery_sei_flags = recovery_sei_payload->flags;
8429 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8430 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008431 DEBUG_PRINT_HIGH("");
8432 DEBUG_PRINT_HIGH("***************************************************");
8433 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8434 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008435 }
8436 break;
8437 case EXTRADATA_PANSCAN_WINDOW:
8438 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8439 break;
8440 case EXTRADATA_MPEG2_SEQDISP:
8441 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8442 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8443 if (seqdisp_payload) {
8444 m_disp_hor_size = seqdisp_payload->disp_width;
8445 m_disp_vert_size = seqdisp_payload->disp_height;
8446 }
8447 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308448 case EXTRADATA_S3D_FRAME_PACKING:
8449 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8450 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308451 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308452 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8453 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8454 }
8455 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008456 case EXTRADATA_FRAME_QP:
8457 struct msm_vidc_frame_qp_payload *qp_payload;
8458 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308459 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008460 append_qp_extradata(p_extra, qp_payload);
8461 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8462 }
8463 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008464 case EXTRADATA_FRAME_BITS_INFO:
8465 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8466 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308467 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008468 append_bitsinfo_extradata(p_extra, bits_info_payload);
8469 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8470 }
8471 break;
Arun Menon906de572013-06-18 17:01:40 -07008472 default:
8473 goto unrecognized_extradata;
8474 }
8475 consumed_len += data->nSize;
8476 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8477 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308478 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008479 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8480 append_frame_info_extradata(p_extra,
8481 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308482 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008483 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008484 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008485 }
8486 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008487unrecognized_extradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308488 if (client_extradata)
Arun Menon906de572013-06-18 17:01:40 -07008489 append_terminator_extradata(p_extra);
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308490 if (secure_mode) {
8491 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8492 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8493 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8494 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8495 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8496 }
Arun Menon906de572013-06-18 17:01:40 -07008497 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008498}
8499
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008500OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008501 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008502{
Arun Menon906de572013-06-18 17:01:40 -07008503 OMX_ERRORTYPE ret = OMX_ErrorNone;
8504 struct v4l2_control control;
8505 if (m_state != OMX_StateLoaded) {
8506 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8507 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008508 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008509 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008510 client_extradata, requested_extradata, enable, is_internal);
8511
8512 if (!is_internal) {
8513 if (enable)
8514 client_extradata |= requested_extradata;
8515 else
8516 client_extradata = client_extradata & ~requested_extradata;
8517 }
8518
8519 if (enable) {
8520 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8521 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8522 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8523 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8524 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008525 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008526 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308527 }
8528 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008529 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8530 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8531 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008532 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008533 }
8534 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8535 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8536 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008537 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008538 }
8539 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8540 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8541 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008542 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008543 }
8544 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8545 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8546 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008547 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008548 }
8549 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8550 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8551 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008552 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008553 }
8554 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8555 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8556 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8557 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008558 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008559 }
8560 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308561 }
8562 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008563 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8564 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8565 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008566 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008567 }
8568 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308569 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8570 if (output_capability == V4L2_PIX_FMT_H264) {
8571 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8572 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8573 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8574 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8575 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8576 }
8577 } else {
8578 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8579 }
8580 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008581 if (requested_extradata & OMX_QP_EXTRADATA) {
8582 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8583 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8584 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8585 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8586 }
8587 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008588 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8589 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8590 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8591 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8592 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8593 }
8594 }
Arun Menon906de572013-06-18 17:01:40 -07008595 }
8596 ret = get_buffer_req(&drv_ctx.op_buf);
8597 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008598}
8599
8600OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8601{
Arun Menon906de572013-06-18 17:01:40 -07008602 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8603 OMX_U8 *data_ptr = extra->data, data = 0;
8604 while (byte_count < extra->nDataSize) {
8605 data = *data_ptr;
8606 while (data) {
8607 num_MB += (data&0x01);
8608 data >>= 1;
8609 }
8610 data_ptr++;
8611 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008612 }
Arun Menon906de572013-06-18 17:01:40 -07008613 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8614 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8615 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008616}
8617
8618void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8619{
Arun Menon906de572013-06-18 17:01:40 -07008620 if (!m_debug_extradata)
8621 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008622
8623 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308624 "============== Extra Data ==============\n"
8625 " Size: %lu\n"
8626 " Version: %lu\n"
8627 " PortIndex: %lu\n"
8628 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008629 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008630 extra->nSize, extra->nVersion.nVersion,
8631 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008632
Arun Menon906de572013-06-18 17:01:40 -07008633 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8634 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8635 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308636 "------ Interlace Format ------\n"
8637 " Size: %lu\n"
8638 " Version: %lu\n"
8639 " PortIndex: %lu\n"
8640 " Is Interlace Format: %d\n"
8641 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008642 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008643 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8644 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8645 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8646 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8647
8648 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308649 "-------- Frame Format --------\n"
8650 " Picture Type: %d\n"
8651 " Interlace Type: %d\n"
8652 " Pan Scan Total Frame Num: %lu\n"
8653 " Concealed Macro Blocks: %lu\n"
8654 " frame rate: %lu\n"
8655 " Time Stamp: %llu\n"
8656 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008657 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008658 fminfo->ePicType,
8659 fminfo->interlaceType,
8660 fminfo->panScan.numWindows,
8661 fminfo->nConcealedMacroblocks,
8662 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308663 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008664 fminfo->aspectRatio.aspectRatioX,
8665 fminfo->aspectRatio.aspectRatioY);
8666
8667 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8668 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008669 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308670 " Pan Scan Frame Num: %lu\n"
8671 " Rectangle x: %ld\n"
8672 " Rectangle y: %ld\n"
8673 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008674 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008675 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8676 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8677 }
8678
8679 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308680 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8681 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8682 DEBUG_PRINT_HIGH(
8683 "------------------ Framepack Format ----------\n"
8684 " id: %lu \n"
8685 " cancel_flag: %lu \n"
8686 " type: %lu \n"
8687 " quincunx_sampling_flagFormat: %lu \n"
8688 " content_interpretation_type: %lu \n"
8689 " content_interpretation_type: %lu \n"
8690 " spatial_flipping_flag: %lu \n"
8691 " frame0_flipped_flag: %lu \n"
8692 " field_views_flag: %lu \n"
8693 " current_frame_is_frame0_flag: %lu \n"
8694 " frame0_self_contained_flag: %lu \n"
8695 " frame1_self_contained_flag: %lu \n"
8696 " frame0_grid_position_x: %lu \n"
8697 " frame0_grid_position_y: %lu \n"
8698 " frame1_grid_position_x: %lu \n"
8699 " frame1_grid_position_y: %lu \n"
8700 " reserved_byte: %lu \n"
8701 " repetition_period: %lu \n"
8702 " extension_flag: %lu \n"
8703 "================== End of Framepack ===========",
8704 framepack->id,
8705 framepack->cancel_flag,
8706 framepack->type,
8707 framepack->quincunx_sampling_flag,
8708 framepack->content_interpretation_type,
8709 framepack->spatial_flipping_flag,
8710 framepack->frame0_flipped_flag,
8711 framepack->field_views_flag,
8712 framepack->current_frame_is_frame0_flag,
8713 framepack->frame0_self_contained_flag,
8714 framepack->frame1_self_contained_flag,
8715 framepack->frame0_grid_position_x,
8716 framepack->frame0_grid_position_y,
8717 framepack->frame1_grid_position_x,
8718 framepack->frame1_grid_position_y,
8719 framepack->reserved_byte,
8720 framepack->repetition_period,
8721 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008722 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8723 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8724 DEBUG_PRINT_HIGH(
8725 "---- QP (Frame quantization parameter) ----\n"
8726 " Frame QP: %lu \n"
8727 "================ End of QP ================\n",
8728 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008729 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8730 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8731 DEBUG_PRINT_HIGH(
8732 "--------- Input bits information --------\n"
8733 " Header bits: %lu \n"
8734 " Frame bits: %lu \n"
8735 "===== End of Input bits information =====\n",
8736 bits->header_bits, bits->frame_bits);
Arun Menon906de572013-06-18 17:01:40 -07008737 } else if (extra->eType == OMX_ExtraDataNone) {
8738 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8739 } else {
8740 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008741 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008742}
8743
8744void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008745 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008746{
Arun Menon906de572013-06-18 17:01:40 -07008747 OMX_STREAMINTERLACEFORMAT *interlace_format;
8748 OMX_U32 mbaff = 0;
8749 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8750 return;
8751 }
8752 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8753 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8754 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8755 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8756 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8757 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8758 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8759 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8760 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8761 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8762 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8763 interlace_format->bInterlaceFormat = OMX_FALSE;
8764 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8765 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008766 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8767 interlace_format->bInterlaceFormat = OMX_TRUE;
8768 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8769 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8770 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8771 interlace_format->bInterlaceFormat = OMX_TRUE;
8772 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8773 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008774 } else {
8775 interlace_format->bInterlaceFormat = OMX_TRUE;
8776 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8777 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8778 }
8779 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008780}
8781
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008782void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008783 struct vdec_aspectratioinfo *aspect_ratio_info,
8784 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008785{
Arun Menon906de572013-06-18 17:01:40 -07008786 m_extradata = frame_info;
8787 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8788 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308789 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008790 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008791}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008792
8793void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008794 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308795 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008796 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008797{
Arun Menon906de572013-06-18 17:01:40 -07008798 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8799 struct msm_vidc_panscan_window *panscan_window;
8800 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008801 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008802 }
Arun Menon906de572013-06-18 17:01:40 -07008803 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8804 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8805 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8806 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8807 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8808 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8809 switch (picture_type) {
8810 case PICTURE_TYPE_I:
8811 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8812 break;
8813 case PICTURE_TYPE_P:
8814 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8815 break;
8816 case PICTURE_TYPE_B:
8817 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8818 break;
8819 default:
8820 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8821 }
8822 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8823 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8824 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8825 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8826 else
8827 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8828 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8829 frame_info->nConcealedMacroblocks = num_conceal_mb;
8830 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308831 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008832 frame_info->panScan.numWindows = 0;
8833 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8834 if (m_disp_hor_size && m_disp_vert_size) {
8835 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8836 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8837 }
8838 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008839
Arun Menon906de572013-06-18 17:01:40 -07008840 if (panscan_payload) {
8841 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8842 panscan_window = &panscan_payload->wnd[0];
8843 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8844 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8845 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8846 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8847 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8848 panscan_window++;
8849 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008850 }
Arun Menon906de572013-06-18 17:01:40 -07008851 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8852 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008853}
8854
8855void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8856{
Arun Menon906de572013-06-18 17:01:40 -07008857 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8858 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8859 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8860 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8861 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8862 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8863 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8864 *portDefn = m_port_def;
8865 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008866 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008867 portDefn->format.video.nFrameWidth,
8868 portDefn->format.video.nStride,
8869 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008870}
8871
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308872void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8873 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8874{
8875 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8876 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8877 DEBUG_PRINT_ERROR("frame packing size mismatch");
8878 return;
8879 }
8880 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8881 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8882 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8883 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8884 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8885 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8886 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8887 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8888 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8889 memcpy(&framepack->id, s3d_frame_packing_payload,
8890 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8891 memcpy(&m_frame_pack_arrangement, framepack,
8892 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8893 print_debug_extradata(extra);
8894}
8895
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008896void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8897 struct msm_vidc_frame_qp_payload *qp_payload)
8898{
8899 OMX_QCOM_EXTRADATA_QP * qp = NULL;
8900 if (!qp_payload) {
8901 DEBUG_PRINT_ERROR("QP payload is NULL");
8902 return;
8903 }
8904 extra->nSize = OMX_QP_EXTRADATA_SIZE;
8905 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8906 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8907 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
8908 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
8909 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8910 qp->nQP = qp_payload->frame_qp;
8911 print_debug_extradata(extra);
8912}
8913
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008914void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8915 struct msm_vidc_frame_bits_info_payload *bits_payload)
8916{
8917 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
8918 if (!bits_payload) {
8919 DEBUG_PRINT_ERROR("bits info payload is NULL");
8920 return;
8921 }
8922 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
8923 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8924 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8925 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
8926 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
8927 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
8928 bits->frame_bits = bits_payload->frame_bits;
8929 bits->header_bits = bits_payload->header_bits;
8930 print_debug_extradata(extra);
8931}
8932
Shalaj Jain273b3e02012-06-22 19:08:03 -07008933void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8934{
Arun Menon906de572013-06-18 17:01:40 -07008935 if (!client_extradata) {
8936 return;
8937 }
8938 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8939 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8940 extra->eType = OMX_ExtraDataNone;
8941 extra->nDataSize = 0;
8942 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008943
Arun Menon906de572013-06-18 17:01:40 -07008944 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008945}
8946
8947OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8948{
Arun Menon906de572013-06-18 17:01:40 -07008949 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8950 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008951 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008952 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008953 }
Arun Menon906de572013-06-18 17:01:40 -07008954 if (m_desc_buffer_ptr == NULL) {
8955 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8956 calloc( (sizeof(desc_buffer_hdr)),
8957 drv_ctx.ip_buf.actualcount);
8958 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008959 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008960 return OMX_ErrorInsufficientResources;
8961 }
8962 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008963
Arun Menon906de572013-06-18 17:01:40 -07008964 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8965 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008966 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008967 return OMX_ErrorInsufficientResources;
8968 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008969
Arun Menon906de572013-06-18 17:01:40 -07008970 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008971}
8972
8973void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8974{
Arun Menon906de572013-06-18 17:01:40 -07008975 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8976 if (m_demux_entries < 8192) {
8977 m_demux_offsets[m_demux_entries++] = address_offset;
8978 }
8979 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008980}
8981
8982void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8983{
Arun Menon906de572013-06-18 17:01:40 -07008984 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8985 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8986 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008987
Arun Menon906de572013-06-18 17:01:40 -07008988 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008989
Arun Menon906de572013-06-18 17:01:40 -07008990 while (index < bytes_to_parse) {
8991 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8992 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8993 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8994 (buf[index+2] == 0x01)) ) {
8995 //Found start code, insert address offset
8996 insert_demux_addr_offset(index);
8997 if (buf[index+2] == 0x01) // 3 byte start code
8998 index += 3;
8999 else //4 byte start code
9000 index += 4;
9001 } else
9002 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009003 }
Arun Menon906de572013-06-18 17:01:40 -07009004 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9005 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009006}
9007
9008OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9009{
Arun Menon906de572013-06-18 17:01:40 -07009010 //fix this, handle 3 byte start code, vc1 terminator entry
9011 OMX_U8 *p_demux_data = NULL;
9012 OMX_U32 desc_data = 0;
9013 OMX_U32 start_addr = 0;
9014 OMX_U32 nal_size = 0;
9015 OMX_U32 suffix_byte = 0;
9016 OMX_U32 demux_index = 0;
9017 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009018
Arun Menon906de572013-06-18 17:01:40 -07009019 if (m_desc_buffer_ptr == NULL) {
9020 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9021 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009022 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009023
Arun Menon906de572013-06-18 17:01:40 -07009024 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9025 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9026 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9027 return OMX_ErrorBadParameter;
9028 }
9029
9030 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9031
9032 if ( ((OMX_U8*)p_demux_data == NULL) ||
9033 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9034 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9035 return OMX_ErrorBadParameter;
9036 } else {
9037 for (; demux_index < m_demux_entries; demux_index++) {
9038 desc_data = 0;
9039 start_addr = m_demux_offsets[demux_index];
9040 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9041 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9042 } else {
9043 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9044 }
9045 if (demux_index < (m_demux_entries - 1)) {
9046 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9047 } else {
9048 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9049 }
9050 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9051 (void *)start_addr,
9052 suffix_byte,
9053 nal_size,
9054 demux_index);
9055 desc_data = (start_addr >> 3) << 1;
9056 desc_data |= (start_addr & 7) << 21;
9057 desc_data |= suffix_byte << 24;
9058
9059 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9060 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9061 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9062 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9063
9064 p_demux_data += 16;
9065 }
9066 if (codec_type_parse == CODEC_TYPE_VC1) {
9067 DEBUG_PRINT_LOW("VC1 terminator entry");
9068 desc_data = 0;
9069 desc_data = 0x82 << 24;
9070 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9071 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9072 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9073 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9074 p_demux_data += 16;
9075 m_demux_entries++;
9076 }
9077 //Add zero word to indicate end of descriptors
9078 memset(p_demux_data, 0, sizeof(OMX_U32));
9079
9080 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9081 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9082 }
9083 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9084 m_demux_entries = 0;
9085 DEBUG_PRINT_LOW("Demux table complete!");
9086 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009087}
9088
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009089OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009090{
Arun Menon906de572013-06-18 17:01:40 -07009091 OMX_ERRORTYPE err = OMX_ErrorNone;
9092 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9093 if (iDivXDrmDecrypt) {
9094 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9095 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009096 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009097 delete iDivXDrmDecrypt;
9098 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009099 }
9100 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009101 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009102 err = OMX_ErrorUndefined;
9103 }
9104 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009105}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009106
Vinay Kaliada4f4422013-01-09 10:45:03 -08009107omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9108{
Arun Menon906de572013-06-18 17:01:40 -07009109 enabled = false;
9110 omx = NULL;
9111 init_members();
9112 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009113 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009114}
9115
9116void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9117{
Arun Menon906de572013-06-18 17:01:40 -07009118 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009119}
9120
Arun Menon906de572013-06-18 17:01:40 -07009121void omx_vdec::allocate_color_convert_buf::init_members()
9122{
9123 allocated_count = 0;
9124 buffer_size_req = 0;
9125 buffer_alignment_req = 0;
9126 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9127 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9128 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9129 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009130#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009131 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009132#endif
Arun Menon906de572013-06-18 17:01:40 -07009133 for (int i = 0; i < MAX_COUNT; i++)
9134 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009135}
9136
Arun Menon906de572013-06-18 17:01:40 -07009137omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9138{
9139 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009140}
9141
9142bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9143{
Arun Menon906de572013-06-18 17:01:40 -07009144 bool status = true;
9145 unsigned int src_size = 0, destination_size = 0;
9146 OMX_COLOR_FORMATTYPE drv_color_format;
9147 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009148 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009149 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009150 }
Arun Menon906de572013-06-18 17:01:40 -07009151 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009152 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009153 return status;
9154 }
9155 pthread_mutex_lock(&omx->c_lock);
9156 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9157 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009158 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009159 status = false;
9160 goto fail_update_buf_req;
9161 }
9162 c2d.close();
9163 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9164 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009165 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009166 if (status) {
9167 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9168 if (status)
9169 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9170 }
9171 if (status) {
9172 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9173 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009174 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009175 "driver size %d destination size %d",
9176 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9177 status = false;
9178 c2d.close();
9179 buffer_size_req = 0;
9180 } else {
9181 buffer_size_req = destination_size;
9182 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9183 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9184 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9185 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9186 }
9187 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009188fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009189 pthread_mutex_unlock(&omx->c_lock);
9190 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009191}
9192
9193bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009194 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009195{
Arun Menon906de572013-06-18 17:01:40 -07009196 bool status = true;
9197 OMX_COLOR_FORMATTYPE drv_color_format;
9198 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009199 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009200 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009201 }
Arun Menon906de572013-06-18 17:01:40 -07009202 pthread_mutex_lock(&omx->c_lock);
9203 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9204 drv_color_format = (OMX_COLOR_FORMATTYPE)
9205 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9206 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009207 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009208 status = false;
9209 }
9210 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009211 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009212 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9213 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009214 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009215 status = false;
9216 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009217 ColorFormat = dest_color_format;
9218 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9219 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009220 if (enabled)
9221 c2d.destroy();
9222 enabled = false;
9223 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009224 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009225 status = false;
9226 } else
9227 enabled = true;
9228 }
9229 } else {
9230 if (enabled)
9231 c2d.destroy();
9232 enabled = false;
9233 }
9234 pthread_mutex_unlock(&omx->c_lock);
9235 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009236}
9237
9238OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9239{
Arun Menon906de572013-06-18 17:01:40 -07009240 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009241 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009242 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009243 }
Arun Menon906de572013-06-18 17:01:40 -07009244 if (!enabled)
9245 return omx->m_out_mem_ptr;
9246 return m_out_mem_ptr_client;
9247}
9248
9249 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9250(OMX_BUFFERHEADERTYPE *bufadd)
9251{
9252 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009253 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009254 return NULL;
9255 }
9256 if (!enabled)
9257 return bufadd;
9258
9259 unsigned index = 0;
9260 index = bufadd - omx->m_out_mem_ptr;
9261 if (index < omx->drv_ctx.op_buf.actualcount) {
9262 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9263 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9264 bool status;
9265 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9266 pthread_mutex_lock(&omx->c_lock);
9267 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9268 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9269 pmem_baseaddress[index], pmem_baseaddress[index]);
9270 pthread_mutex_unlock(&omx->c_lock);
9271 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9272 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009273 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009274 m_out_mem_ptr_client[index].nFilledLen = 0;
9275 return &m_out_mem_ptr_client[index];
9276 }
9277 } else
9278 m_out_mem_ptr_client[index].nFilledLen = 0;
9279 return &m_out_mem_ptr_client[index];
9280 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009281 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009282 return NULL;
9283}
9284
9285 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9286(OMX_BUFFERHEADERTYPE *bufadd)
9287{
9288 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009289 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009290 return NULL;
9291 }
9292 if (!enabled)
9293 return bufadd;
9294 unsigned index = 0;
9295 index = bufadd - m_out_mem_ptr_client;
9296 if (index < omx->drv_ctx.op_buf.actualcount) {
9297 return &omx->m_out_mem_ptr[index];
9298 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009299 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009300 return NULL;
9301}
9302 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9303(unsigned int &buffer_size)
9304{
9305 bool status = true;
9306 pthread_mutex_lock(&omx->c_lock);
9307 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009308 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009309 else {
9310 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009311 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009312 status = false;
9313 goto fail_get_buffer_size;
9314 }
9315 }
9316 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9317 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9318 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9319 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009320fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009321 pthread_mutex_unlock(&omx->c_lock);
9322 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009323}
9324OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009325 OMX_BUFFERHEADERTYPE *bufhdr)
9326{
9327 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009328
Arun Menon906de572013-06-18 17:01:40 -07009329 if (!enabled)
9330 return omx->free_output_buffer(bufhdr);
9331 if (enabled && omx->is_component_secure())
9332 return OMX_ErrorNone;
9333 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009334 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009335 return OMX_ErrorBadParameter;
9336 }
9337 index = bufhdr - m_out_mem_ptr_client;
9338 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009339 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009340 return OMX_ErrorBadParameter;
9341 }
9342 if (pmem_fd[index] > 0) {
9343 munmap(pmem_baseaddress[index], buffer_size_req);
9344 close(pmem_fd[index]);
9345 }
9346 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009347#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009348 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009349#endif
Arun Menon906de572013-06-18 17:01:40 -07009350 m_heap_ptr[index].video_heap_ptr = NULL;
9351 if (allocated_count > 0)
9352 allocated_count--;
9353 else
9354 allocated_count = 0;
9355 if (!allocated_count) {
9356 pthread_mutex_lock(&omx->c_lock);
9357 c2d.close();
9358 init_members();
9359 pthread_mutex_unlock(&omx->c_lock);
9360 }
9361 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009362}
9363
9364OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009365 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009366{
Arun Menon906de572013-06-18 17:01:40 -07009367 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9368 if (!enabled) {
9369 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9370 return eRet;
9371 }
9372 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009373 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009374 omx->is_component_secure());
9375 return OMX_ErrorUnsupportedSetting;
9376 }
9377 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009378 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9379 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009380 buffer_size_req,bytes);
9381 return OMX_ErrorBadParameter;
9382 }
9383 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009384 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009385 return OMX_ErrorInsufficientResources;
9386 }
9387 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9388 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9389 port,appData,omx->drv_ctx.op_buf.buffer_size);
9390 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009391 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009392 return eRet;
9393 }
9394 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309395 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009396 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009397 (temp_bufferHdr - omx->m_out_mem_ptr));
9398 return OMX_ErrorUndefined;
9399 }
9400 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009401#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009402 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9403 buffer_size_req,buffer_alignment_req,
9404 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9405 0);
9406 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9407 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009408 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009409 return OMX_ErrorInsufficientResources;
9410 }
9411 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9412 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009413
Arun Menon906de572013-06-18 17:01:40 -07009414 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009415 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009416 close(pmem_fd[i]);
9417 omx->free_ion_memory(&op_buf_ion_info[i]);
9418 return OMX_ErrorInsufficientResources;
9419 }
9420 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9421 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9422 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009423#endif
Arun Menon906de572013-06-18 17:01:40 -07009424 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9425 m_pmem_info_client[i].offset = 0;
9426 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9427 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9428 m_platform_list_client[i].nEntries = 1;
9429 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9430 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9431 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9432 m_out_mem_ptr_client[i].nFilledLen = 0;
9433 m_out_mem_ptr_client[i].nFlags = 0;
9434 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9435 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9436 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9437 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9438 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9439 m_out_mem_ptr_client[i].pAppPrivate = appData;
9440 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009441 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009442 allocated_count++;
9443 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009444}
9445
9446bool omx_vdec::is_component_secure()
9447{
Arun Menon906de572013-06-18 17:01:40 -07009448 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009449}
9450
9451bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9452{
Arun Menon906de572013-06-18 17:01:40 -07009453 bool status = true;
9454 if (!enabled) {
9455 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9456 dest_color_format = (OMX_COLOR_FORMATTYPE)
9457 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9458 else
9459 status = false;
9460 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009461 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9462 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9463 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009464 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009465 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009466 }
9467 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009468}
Arun Menonbdb80b02013-08-12 17:45:54 -07009469
Arun Menonbdb80b02013-08-12 17:45:54 -07009470void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9471{
9472 int i = 0;
9473 bool buf_present = false;
9474 pthread_mutex_lock(&m_lock);
9475 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9476 //check the buffer fd, offset, uv addr with list contents
9477 //If present increment reference.
9478 if ((out_dynamic_list[i].fd == fd) &&
9479 (out_dynamic_list[i].offset == offset)) {
9480 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009481 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009482 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9483 buf_present = true;
9484 break;
9485 }
9486 }
9487 if (!buf_present) {
9488 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9489 //search for a entry to insert details of the new buffer
9490 if (out_dynamic_list[i].dup_fd == 0) {
9491 out_dynamic_list[i].fd = fd;
9492 out_dynamic_list[i].offset = offset;
9493 out_dynamic_list[i].dup_fd = dup(fd);
9494 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009495 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009496 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9497 break;
9498 }
9499 }
9500 }
9501 pthread_mutex_unlock(&m_lock);
9502}
9503
9504void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9505{
9506 int i = 0;
9507 pthread_mutex_lock(&m_lock);
9508 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9509 //check the buffer fd, offset, uv addr with list contents
9510 //If present decrement reference.
9511 if ((out_dynamic_list[i].fd == fd) &&
9512 (out_dynamic_list[i].offset == offset)) {
9513 out_dynamic_list[i].ref_count--;
9514 if (out_dynamic_list[i].ref_count == 0) {
9515 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009516 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009517 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9518 out_dynamic_list[i].dup_fd = 0;
9519 out_dynamic_list[i].fd = 0;
9520 out_dynamic_list[i].offset = 0;
9521 }
9522 break;
9523 }
9524 }
9525 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009526 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009527 }
9528 pthread_mutex_unlock(&m_lock);
9529}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009530
9531#ifdef _MSM8974_
9532void omx_vdec::send_codec_config() {
9533 if (codec_config_flag) {
9534 unsigned p1 = 0; // Parameter - 1
9535 unsigned p2 = 0; // Parameter - 2
9536 unsigned ident = 0;
9537 pthread_mutex_lock(&m_lock);
9538 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9539 while (m_etb_q.m_size) {
9540 m_etb_q.pop_entry(&p1,&p2,&ident);
9541 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9542 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9543 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9544 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9545 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9546 omx_report_error();
9547 }
9548 } else {
9549 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9550 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9551 }
9552 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9553 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9554 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9555 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9556 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9557 omx_report_error ();
9558 }
9559 } else {
9560 pending_input_buffers++;
9561 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9562 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9563 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9564 }
9565 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9566 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9567 (OMX_BUFFERHEADERTYPE *)p1);
9568 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9569 }
9570 }
9571 pthread_mutex_unlock(&m_lock);
9572 }
9573}
9574#endif